Log4Net Protokollierung von zwei verschiedenen Ebenen in zwei verschiedenen Appendern für denselben Logger

76

Wir haben zwei verschiedene asp.net-Anwendungen mit aktivierter Log4net-Protokollierung. Beide haben dieselbe Version von Log4Net, 1.2.10.0.

Wir haben den log4net.Appender.AdoNetAppenderLogger zu beiden hinzugefügt und möchten die Info-Ebene für den Root-Logger protokollieren, möchten aber auch die Fehler-Ebene für einen Root-Logger in einem Datei-Appender protokollieren. Unsere Konfiguration ist wie folgt;

<?xml version="1.0" encoding="utf-8"?>

<log4net>
    <appender name="filelogAppender" type="log4net.Appender.RollingFileAppender" >
        <file value="..\logs\app.debug.log" />
        <encoding value="utf-8" />
        <staticLogFileName value="true" />
        <datePattern value=".yyyyMMdd.'log'" />
        <rollingStyle value="Composite" />
        <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
        <appendToFile value="true" />
        <maximumFileSize value="1MB" />
        <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%date [%3thread] %-5level %property{log4net:HostName} [%property{Revision}] %logger %message%n" />
        </layout>
    </appender>
    <!--    
        use [DB]
        GO
        CREATE TABLE [dbo].[Log] (
            [Id] [int] IDENTITY (1, 1) NOT NULL,
            [Date] [datetime] NOT NULL,
            [Application][varchar] (255) NOT NULL,
            [Thread] [varchar] (255) NOT NULL,
            [Level] [varchar] (50) NOT NULL,
            [Logger] [varchar] (255) NOT NULL,
            [Server][varchar](255) NOT NULL,
            [Revision][varchar](50) NOT NULL,
            [Message] [varchar] (4000) NOT NULL,
            [Exception] [varchar] (2000) NULL
        )
    -->
    <appender name="dbLogAppender" type="log4net.Appender.AdoNetAppender" xdt:Transform="InsertBefore(/log4net/root)">
        <bufferSize value="100" />
        <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
        <connectionString value="data source=sqlserver;initial catalog=DB;integrated security=false;persist security info=True;User ID=USER;Password=PASSWORD" />
        <commandText value="INSERT INTO Log ([Date],[Application],[Thread],[Level],[Logger],[Server],[Revision],[Message],[Exception]) VALUES (@log_date,'WebApp1', @thread, @log_level, @logger, @server, @revision, @message, @exception)" />
        <parameter>
            <parameterName value="@log_date" />
            <dbType value="DateTime" />
            <layout type="log4net.Layout.RawTimeStampLayout" />
        </parameter>
        <parameter>
            <parameterName value="@thread" />
            <dbType value="String" />
            <size value="255" />
            <layout type="log4net.Layout.PatternLayout">
                <conversionPattern value="%thread" />
            </layout>
        </parameter>
        <parameter>
            <parameterName value="@log_level" />
            <dbType value="String" />
            <size value="50" />
            <layout type="log4net.Layout.PatternLayout">
                <conversionPattern value="%level" />
            </layout>
        </parameter>
        <parameter>
            <parameterName value="@logger" />
            <dbType value="String" />
            <size value="255" />
            <layout type="log4net.Layout.PatternLayout">
                <conversionPattern value="%logger" />
            </layout>
        </parameter>
        <parameter>
            <parameterName value="@server" />
            <dbType value="String" />
            <size value="255" />
            <layout type="log4net.Layout.PatternLayout">
                <conversionPattern value="%property{log4net:HostName}"/>
            </layout>
        </parameter>
        <parameter>
            <parameterName value="@revision" />
            <dbType value="String" />
            <size value="50" />
            <layout type="log4net.Layout.PatternLayout">
                <conversionPattern value="%property{Revision}"/>
            </layout>
        </parameter>
        <parameter>
            <parameterName value="@message" />
            <dbType value="String" />
            <size value="4000" />
            <layout type="log4net.Layout.PatternLayout">
                <conversionPattern value="%message" />
            </layout>
        </parameter>
        <parameter>
            <parameterName value="@exception" />
            <dbType value="String" />
            <size value="2000" />
            <layout type="log4net.Layout.ExceptionLayout" />
        </parameter>
    </appender>
    <root>
        <level value="Error"/>
        <appender-ref ref="filelogAppender"/>
    </root>
    <root>
        <level value="Info"/>
        <appender-ref ref="dbLogAppender"/>
    </root>
</log4net>  

Das Problem, das wir sehen, ist, dass wir für eine Anwendung Einträge in der Datenbank sehen, für die andere jedoch nicht.

Revisionist eine GlobalContextEigenschaft, die wir Application_Start()in beiden Anwendungen festgelegt haben. Und der einzige Unterschied zwischen den beiden Konfigurationen besteht darin, dass wir einen unterschiedlichen fest codierten Wert für haben Application.

Können wir zwei solche Root-Logger haben? Könnte dies die Quelle unseres Problems sein, das wir in einer Anwendung sehen?

Graney
quelle

Antworten:

123

Sie sollten in der Lage sein, die thresholdEigenschaft jedes Appenders separat festzulegen und sie im selben Stammverzeichnis einzuschließen.

<appender name="filelogAppender" type="log4net.Appender.RollingFileAppender">
  <threshold value="Error" />
</appender>
<appender name="dblogAppender" type="log4net.Appender.AdoNetAppender">
  <threshold value="Info" />
</appender>
<root>
  <appender-ref ref="filelogAppender" />
  <appender-ref ref="dblogAppender" />
</root>

Referenz

Barry Colebank Jr.
quelle
38

Sie können LevelRangeFilterfür jeden der Appender eine angeben und jeden Appender im Stammverzeichnis definieren, um auf verschiedenen Ebenen zu protokollieren.

<appender name="filelogAppender" type="log4net.Appender.RollingFileAppender" >
    <!--File Details/Layout Options-->
    <filter type="log4net.Filter.LevelRangeFilter">
        <levelMin value="INFO"/>
    </filter>
</appender>
<appender name="dbLogAppender" type="log4net.Appender.AdoNetAppender">
    <!--SQL Options-->      
    <filter type="log4net.Filter.LevelRangeFilter">
        <levelMin value="ERROR"/>
    </filter>
</appender>
<root>
    <level value="INFO"/>
    <appender-ref ref="filelogAppender" /> <!--Prints info, warn, error, or fatal logs. -->
    <appender-ref ref="dbLogAppender" />   <!--Prints only error or fatal logs. -->
</root>
matth
quelle
1
Eine gute Antwort! Und bietet Flexibilität, die mir überhaupt nicht bewusst war. Ich denke, ich werde die @ barry-Antwort verwenden, da ich keinen Bereich definieren muss, sondern nur einen Schwellenwert.
Graney
Aus irgendeinem Grund funktionierten die Knoten "Schwelle" und "Bewerter" für mich nicht, aber dies funktionierte (ich habe levelMin und levelMax als denselben Wert angegeben).
Anssssss
Ich hatte nur ein Problem damit, dass levelMin, sobald es im Appender verwendet wird, in allen Appendern angegeben werden muss, da sonst die Filterung in meinem Fall nicht richtig funktioniert hat und nur das Root-Level berücksichtigt wurde.
Honza P.
1

Zwei <root>Elemente sind nicht zulässig.

Aus der Dokumentation :

root     Optional element, maximum of one allowed. Defines the configuration of the root logger.

Sie können jedoch einen Root-Logger wie Sie haben und dann einen separaten Logger haben, der durch einen Namespace angegeben wird.

<root>
    <level value="Error"/>
    <appender-ref ref="filelogAppender"/>
</root>
<logger name="MyCompany.MyApp.Namespace">
    <level value="Info"/>
    <appender-ref ref="dbLogAppender"/>
</logger>
scheien
quelle
1
Wir möchten jedoch root an zwei Speicherorten protokollieren. Wir möchten die Protokollierung eines bestimmten Namespace nicht einschränken. Daher unser Versuch, zwei Root-Logger zu verwenden. [Was seltsamerweise bei einer der Apps funktioniert] Andernfalls müssen wir eine additivityMenge Logger für jeden möglichen Root-Namespace erstellen , wobei false festgelegt ist.
Graney
0

Verwenden Sie einfach den Evaluator. Sie müssen nicht in allen Appendern einen Schwellenwert angeben.

<appender name="filelogAppender" type="log4net.Appender.RollingFileAppender">
        <evaluator type="log4net.Core.LevelEvaluator">
          <threshold value="ERROR" />
  </evaluator>
</appender>
mvk
quelle