Log4net

1. Prolog

Der nachfolgende Text umfaßt einen Schnelleinstieg in die Konfiguration von Log4net. Das Beispiel-Projekt steht auf Github zur Verfügung.

1.1 Log4net bereitstellen

Per NuGet steht unter „Add library package reference“ das Paket log4net bereit. Alternativ kann man unter http://logging.apache.org/log4net/download.html ein entsprechendes Paket herunterladen.

1.2 Programm vorbereiten

Es gibt zwei Möglichkeiten, ein Programm zur Zusammenarbeit mit Log4net zu bewegen: entweder per Eintrag in der AssemblyInfo.cs oder programmatisch.

1.2.1 Per AssemblyInfo

In der Datei AssemblyInfo.cs ist die Zeile einzufügen:

[assembly: log4net.Config.XmlConfigurator()]

Falls es sich um ein Web-Projekt handelt, oder man aus einem anderen Grund die Konfigurationsdatei ändern möchte, kann man per optionalem Parameter eine andere
Konfigurationsdatei angeben:

[assembly: log4net.Config.XmlConfigurator(ConfigFile = "App.config")]

Ein weiterer Parameter namens Watch gibt an, ob die Konfigurationsdatei auf Änderungen hin überwacht werden soll:

[assembly: log4net.Config.XmlConfigurator(Watch=true)]
1.2.2 Programmatisch

Für das einfache Konfigurieren von Log4net genügt die Zeile

log4net.Config.XmlConfigurator.Configure();

Das Ändern der Konfigurationsdatei kann zB erfolgen durch

log4net.Config.XmlConfigurator.Configure(new FileInfo("log4net.config"));

Das Überwachen der Konfigurationsdatei wird erreicht mittels

log4net.Config.XmlConfigurator.ConfigureAndWatch(new FileInfo("log4net.config"));

in diesem Fall muss allerdings zwingend eine Konfigurationsdatei angegeben werden.

2. Logs ausgeben

Zur Ausgabe von Logs genügt es, vom LogManager von Log4net ein Handle für die aktuelle Klasse anzufordern und die Nachricht abzusetzen:

class Foo
{
  static readonly ILog Log = LogManager.GetLogger(typeof(Foo));
  public Foo()
  {
    Log.Info("c'tor of Foo");
  }
}

Je nach globalen Konfiguration der Logausgabe von Log4net und eventuell  vorgenommenen gesonderten Einstellungen der Klasse, in diesem Falle Foo, wird die Nachricht ausgegeben oder unterdrückt.
Zu den einfachen Textausgabe-Funktionen – Debug, Info, Warn, Error – gibt es eine korrespondierende Funktion zur formatierten Ausgabe von Text – DebugFormat, InfoFormat, WarnFormat, ErrorFormat:

Log.InfoFormat("Foo called at {0}", DateTime.Now);

3. Logs konfigurieren

Nachdem wir das Programm auf das Loggen vorbereitet und sogar schon erste Log-Ausgaben in die Klassen eingefügt haben, erhalten wir vorerst keine Ausgaben – es ist kein Log-Mechanismus konfiguriert, der die Ausgabe vornimmt.
Um wenigstens zu sehen, was eventuell schief läuft bei der Konfiguration von Log4net, können wir innerhalb der App.config (oder der jeweils angegebenen Konfigurationsdatei für Log4net) das interne Debugging anschalten:

<configuration>
  <appSettings>
    <add key="log4net.Internal.Debug" value="true" />
  </appSettings>
</configuration>

3.1 Globale Einstellungen

Die Konfiguration der Log-Mechanismen erfolgt mittels eines SectionHandlers von Log4net. Wir legen eine neue Sektion an und setzen den Default-Level erst einmal auf  Warn:

<configuration>
  <configSections>
    <section name="log4net"
      type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
  </configSections>
  <log4net>
    <root>
      <level value="WARN"/>
    </root>
  </log4net>
</configuration>

Damit ist erst einmal sichergestellt, daß Log4net konfiguriert wird und alle Nachrichten mit den Stufen Warn oder Error ausgegeben werden. Aber wohin?

3.1.1 Konsolenausgabe

Die erste Möglichkeit wäre die Ausgabe auf die Konsole. Hierfür müssen wir einen Appender einrichten und Log4net anweisen ihn zu benutzen:

...
<log4net>
 <root>
   <level value="WARN"/>
   <appender-ref ref="Console"/>
  </root>
 <appender name="Console" type="log4net.Appender.ConsoleAppender">
   <layout type="log4net.Layout.PatternLayout">
     <conversionPattern value="%date [%thread] %-5level %logger [%ndc] &lt;%property{auth}&gt; - %message%newline" />
   </layout>
 </appender>
/log4net>
...

Wichtig hierbei ist die Definition eines Ausgabe-Layouts, sonst beschwert sich Log4net. Alternativ kann auch das Layout auch mittels

<layout type="log4net.Layout.SimpleLayout" />

erfolgen. Ab jetzt sollte eine Ausgabe der Log-Nachrichten in der Konsole erscheinen! Wohlgemerkt auf der Konsole, nicht im Debug-Fenster von Visual Studio.

3.1.2 Farbige Konsolenausgabe

Wer es lieber bunt mag, kann auch die kolorierte Ausgabe des Konsolenappenders benutzen. Allerdings muß hierfür auch das Farbmapping angegeben werden:

...
<log4net>
  <root>
    <level value="WARN"/>
    <appender-ref ref="Colored"/>
  </root>
  <appender name="Colored" type="log4net.Appender.ColoredConsoleAppender">
    <mapping>
      <level value="FATAL" />
      <foreColor value="Red" />
      <backColor value="White" />
    </mapping>
    <mapping>
      <level value="ERROR" />
      <foreColor value="Red, HighIntensity" />
    </mapping>
    <mapping>
      <level value="WARN" />
      <foreColor value="Yellow" />
    </mapping>
    <mapping>
      <level value="INFO" />
      <foreColor value="Cyan" />
    </mapping>
    <mapping>
      <level value="DEBUG" />
      <foreColor value="Green" />
    </mapping>
    <layout type="log4net.Layout.SimpleLayout" />
    </appender>
</log4net>
...
3.1.3 Ausgabe im Debug-Fenster

Wie erwähnt, erscheint die Konsolenausgabe nicht im Debug-Fenster von Visual Studio. Hierfür existiert ein eigener Appender:

...
<log4net>
  <root>
    <level value="WARN"/>
    <appender-ref ref="Debug"/>
  </root>
  <appender name="Debug" type="log4net.Appender.DebugAppender">
    <immediateFlush value="true" />
    <layout type="log4net.Layout.SimpleLayout" />
  </appender>
</log4net>
...
3.1.4 Ausgabe in Datei

Die Ausgabe in eine Datei kann ganz einfach erfolgen über:

...
<log4net>
  <root>
    <level value="WARN"/>
    <appender-ref ref="File"/>
  </root>
  <appender name="File" type="log4net.Appender.FileAppender">
    <file value="log/myfile.txt" />
    <appendToFile value="true" />
    <encoding value="utf-8" />
    <layout type="log4net.Layout.SimpleLayout" />
  </appender>
</log4net>
...

Das Unterverzeichnis ‘log’ wird hierbei angelegt falls es nicht existiert.
Soll die Log-Datei hierbei eine gewisse Größe nicht überschreiten, oder soll der Dateiname in Abhängigkeit des Datums gebildet werden, empfiehlt sich der Einsatz des RollingFileAppenders:

...
<log4net>
  <root>
    <level value="WARN"/>
    <appender-ref ref="RollSize"/>
    <appender-ref ref="RollDate"/>
  </root>
  <appender name="RollSize" type="log4net.Appender.RollingFileAppender">
    <file value="log/SizeLog.txt" />
    <appendToFile value="true" />
    <rollingStyle value="size" />
    <maxSizeRollBackups value="10" />
    <maximumFileSize value="1MB" />
    <layout type="log4net.Layout.SimpleLayout" />
  </appender>
  <appender name="RollDate" type="log4net.Appender.RollingFileAppender">
    <file value="log/DateLog.txt" />
    <appendToFile value="true" />
    <rollingStyle value="date" />
    <layout type="log4net.Layout.SimpleLayout" />
  </appender>
</log4net>
...

4. Ausgabe anpassen

Wie in einem Beispiel bereits gesehen, kann die Log-Ausgabe auch an persönliche Bedürfnisse angepasst werden. Hierfür wird das Layout nicht auf SimpleLayout gesetzt, sondern explizit per Patternlayout angegeben:

...
<appender name="Console" type="log4net.Appender.ConsoleAppender">
  <layout type="log4net.Layout.PatternLayout">
  <conversionPattern value="%date [%thread] %-5level %logger [%ndc] &lt;%property{auth}&gt; - %message%newline" />
  </layout>
</appender>
...

Um die Ausgabe anzupassen, stehen folgende Kürzel bereit:

Pattern Kürzel Bedeutung
appdomain a
class c Äquivalent zu type
date d Datum
exception Gespeicherte Exception, leer wenn keine verfügbar
file f Dateiname des Log-Aufrufs (*)
identity Benutzername (*)
location l FQN des Log-Aufrufs (*)
level p Level des Log-Events
line L Zeilennummer des Log-Aufrufs (*)
logger Klassenname des Log-Aufrufers
message m Die Log-Nachricht
method M Der Methodenname des Log-Aufrufs (*)
newline n Beginnt eine neue Zeile
ndc Ausgabe des Nested Diagnostic Context
property P Ausgabe einer Log-Event-Property, zB
%property{User}
timestamp r Millisekunden seit Applikationsstart
thread t Thread-ID sofern verfügbar
type C FQN des Typs des Log-Aufrufers (*)
username w Name des aktuellen Windows-Benutzers (*)
utcdate Ausgabe des Datums im UTC-Format

Quelle: http://logging.apache.org/log4net/release/sdk/log4net.Layout.PatternLayout.html

Warnung: Die mit (*) gekennzeichneten Pattern verlangsamen den Log-Mechanismus extrem und sollten vermieden werden.

Datums-/Uhrzeitangaben können in gewohnter Weise mit den üblichen Kürzeln genauer spezifiziert werden, zB mit %utcdate{dd MMM yyyy HH:mm:ss,fff}

Weiterhin können die Einträge auch auf bestimmte Längen formatiert werden mit der Anweisung %[-][min].[max][eintrag]
Hier bedeutet – rechtsbündiges Auffüllen, auf die min-Werte wird aufgefüllt, ab den max-Werten wird abgeschnitten, zB %-20.30logger oder %.10logger.

5. Log pro Klasse

Das global eingestellte Log-Verhalten kann pro Klasse überschrieben werden. Damit ist es möglich, nur bestimmte Klassen bzw deren Methoden zu protokollieren, oder auch nur diese Log-Nachrichten auf anderen Appendern auszugeben.
Hierzu wird für diese Klasse eine eigene Einstellungsebene hinzugefügt:

...
<root>
  <level value="WARN"/>
  <appender-ref ref="Console"/>
</root>
<logger name="HelloLog.Foo">
  <level value="ALL" />
  <appender-ref ref="Colored"/>
</logger>
...

In diesem Beispiel werden alle Log-Nachrichten der Stufe Warn auf der Konsole ausgegeben, für die Klasse HelloLog.Foo allerdings werden alle Nachrichten ausgegeben, zusätzlich werden diese Nachrichten noch farbig auf der Konsole ausgegeben.

Dieses Überschreiben kann auch per Namensraum geschehen. Mit:

...
<logger name="HelloLog">
  <level value="ALL" />
  <appender-ref ref="Colored"/>
</logger>
...

gilt oben beschriebenes Verhalten für alle Klassen im Namensraum HelloLog.

 

6. Epilog

Es existieren noch weit mehr Appender als hier angegeben, zB Ausgabe auf Twitter, MongoDB, etc…
Hier noch eine kleine Übersicht der mitgelieferten Appender:

log4net.Appender. Beschreibung
AdoNetAppender Ausgabe in Datenbank
AnsiColorTerminalAppender Ausgabe auf Terminal mittels ANSI-Farbsequenzen
AspNetTraceAppender Ausgabe in ASP.NET Trace-Kontext
BufferingForwardingAppender Puffert Einträge und leitet sie weiter
ColoredConsoleAppender Farbige Ausgabe in Konsole
ConsoleAppender Ausgabe in Konsole
DebugAppender Ausgabe in das Debug-Fenster
EventLogAppender Ausgabe in das Event-Log
ForwardingAppender Weiterleitung der Einträge
FileAppender Ausgabe in Datei
LocalSyslogAppender Ausgabe in das Syslog-System
MemoryAppender
NetSendAppender
OutputDebugStringAppender
RemoteSyslogAppender
RemotingAppender
RollingFileAppender Ausgabe in Datei mit rotierendem Dateinamen
SmtpAppender Versenden der Einträge per Mail
SmtpPickupDirAppender Versenden der Einträge per Mail-Programm
TelnetAppender Ausgabe auf Telnet-Host, mit dem man sich verbinden kann
TraceAppender Ausgabe in das Trace-System
UdpAppender Versenden der Log-Nachrichten per UDP

Quelle: http://www.beefycode.com/post/Log4Net-Tutorial-pt-3-Appenders.aspx

Hinweis: es wurden beileibe nicht alle Möglichkeiten von Log4net aufgezeigt. ZB bestehen diverse Filter-Möglichkeiten bei der Weiterleitung der Log-Events. Weiterführende Informationen finden sich auf der Seite http://logging.apache.org/log4net/release/sdk/

DotNetKicks-DE Image
Dieser Beitrag wurde unter .NET, C#, Logging veröffentlicht. Setze ein Lesezeichen auf den Permalink.

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden /  Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden /  Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden /  Ändern )

Verbinde mit %s