Richtige Verwendung von log4net (Logger-Benennung)

82

Es gibt zwei Möglichkeiten, log4net zu konfigurieren und zu verwenden. Der erste ist, wenn ich meinen eigenen Appender und den zugehörigen Logger konfigurieren kann:

<!-- language: xml -->

<appender name="myLogAppender" type="log4net.Appender.RollingFileAppender" >
    <file value="Logs\myLog.log" />
    <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date %level - %message%n" />
    </layout>
</appender>

<logger name="myLog">
    <level value="All"></level>
    <appender-ref ref="myLogAppender" />
</logger>

Und wenn ich dann etwas in ein Protokoll schreiben möchte, kann ich Folgendes tun:

ILog log = LogManager.GetLogger("myLog");
log.Info("message");

Eine andere Möglichkeit, es zu verwenden, besteht darin, root so zu konfigurieren, dass es so detailliert ist, wie ich möchte:

<!-- language: xml -->

<root>
    <level value="Error" />
    <appender-ref ref="myLogAppender" />
</root>

Und in diesem Fall kann ich Nachrichten wie folgt protokollieren:

ILog log = LogManager.GetLogger(typeof(Bar));
log.Info("message");

Der zweite Ansatz bietet den Vorteil, dass Sie einige Nachrichten im laufenden Betrieb aktivieren oder deaktivieren können. Das Problem ist jedoch, dass ich in EPiServer CMS entwickle und es ein eigenes Protokollierungssystem hat, das log4net verwendet. Wenn ich die Informationsprotokollierung auf Stammebene aktiviere, werden viele Systemprotokolle geschrieben.

Wie benutzt man log4net? Jeder Teil eines Systems schreibt in seinen eigenen Logger oder alles wird in den Standardlogger geschrieben, und die Konfiguration entscheidet, was als nächstes zu tun ist.

Schlau
quelle

Antworten:

95

In Bezug darauf, wie Sie Nachrichten im Code protokollieren, würde ich mich für den zweiten Ansatz entscheiden:

ILog log = LogManager.GetLogger(typeof(Bar));
log.Info("message");

Wenn Nachrichten, die an das obige Protokoll gesendet werden, mit dem vollständig qualifizierten Typ "benannt" werden Bar, z

MyNamespace.Foo.Bar [INFO] message

Der Vorteil dieses Ansatzes besteht darin, dass er der De-facto-Standard für die Organisation der Protokollierung ist und es Ihnen auch ermöglicht, Ihre Protokollnachrichten nach Namespace zu filtern. Sie können beispielsweise angeben, dass Sie eine Nachricht auf INFO-Ebene protokollieren möchten, die Protokollierungsstufe jedoch Barspeziell für DEBUG erhöhen möchten :

<log4net>
    <!-- appenders go here -->
    <root>
        <level value="INFO" />
        <appender-ref ref="myLogAppender" />
    </root>

    <logger name="MyNamespace.Foo.Bar">
        <level value="DEBUG" />
    </logger>
</log4net>

Die Möglichkeit, Ihre Protokollierung über den Namen zu filtern, ist eine leistungsstarke Funktion von log4net. Wenn Sie einfach alle Ihre Nachrichten protokollieren "myLog", verlieren Sie viel von dieser Leistung!

In Bezug auf das EPiServer-CMS sollten Sie in der Lage sein, mit dem oben beschriebenen Ansatz eine andere Protokollierungsstufe für das CMS und Ihren eigenen Code anzugeben.

Zur weiteren Lektüre hier ein Artikel zum Codeprojekt, den ich über die Protokollierung geschrieben habe:

ColinE
quelle
5
Sie können sogar einen Teil der Klassennamensräume aus dem Protokoll ausschließen, um das Rauschen in Protokollen zu verringern, indem Sie PatternLayout logging.apache.org/log4net/release/sdk/… verwenden. "Für den Protokollierungsnamen" abc "wird beispielsweise das Muster% logger {2} verwendet Ausgabe "bc". "
AlfeG
7
private static readonly ILog log = LogManager.GetLogger (System.Reflection.MethodBase.GetCurrentMethod (). DeclaringType);
Casper Leon Nielsen
Warum ist der zweite Ansatz besser als der erste?! Der Klassenname ist statisch, und wenn Sie ihn ändern, müssen Sie auch den Namen im Logger aktualisieren. Gibt es einen Grund, einen Reflection-Aufruf zu veranlassen, nur um den Klassennamen zu erhalten?
MeTitus
1
@CasperLeonNielsen Kannst du erklären, wie sich das unterscheidet this.GetType()?
ErikE
2
@ErikE this.GetType () ist beim Definieren einer statischen Eigenschaft, in einer statischen Klasse oder außerhalb eines Konstruktors nicht verfügbar.
Dhochee
11

Meine Antwort kommt vielleicht zu spät, aber ich denke, sie kann Neulingen helfen. Sie werden keine ausgeführten Protokolle sehen, es sei denn, die Änderungen werden wie folgt vorgenommen.

2 Dateien müssen geändert werden, wenn Sie Log4net implementieren.


  1. Fügen Sie im Projekt die Referenz log4net.dll hinzu .
  2. app.config
  3. Class - Datei , wo Sie Protokolle implementieren wird.

In [ app.config ]:

Zunächst müssen Sie unter 'configSections' den folgenden Code hinzufügen.

<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />

Dann müssen Sie unter 'Konfigurationsblock' unter den folgenden Code schreiben. (Dieser Code wird gemäß meinen Anforderungen angepasst, funktioniert aber wie ein Zauber.)

<log4net debug="true">
    <logger name="log">
      <level value="All"></level>
      <appender-ref ref="RollingLogFileAppender" />
    </logger>

    <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
      <file value="log.txt" />
      <appendToFile value="true" />
      <rollingStyle value="Composite" />
      <maxSizeRollBackups value="1" />
      <maximumFileSize value="1MB" />
      <staticLogFileName value="true" />

      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date %C.%M [%line] %-5level - %message %newline %exception %newline" />
      </layout>
    </appender>
</log4net>

Inside Calling Class :

In der Klasse, in der Sie dieses log4net verwenden möchten, müssen Sie den folgenden Code deklarieren.

 ILog log = LogManager.GetLogger("log");

Jetzt können Sie in derselben Klasse anrufen, wo immer Sie möchten. Im Folgenden finden Sie eine der Methoden, die Sie während der Ausführung von Vorgängen aufrufen können.

log.Error("message");
Ankur Soni
quelle
Sie müssen kein ILogInstanzmitglied richtig machen? Ich habe die gleiche Frage hier ausführlicher gestellt , aber vielleicht kann ich Ihre Eingabe erhalten?
Minh Tran
4

Anstatt meine aufrufende Klasse zu benennen, habe ich Folgendes verwendet:

private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

Auf diese Weise kann ich in jeder Klasse, die log4net verwendet, dieselbe Codezeile verwenden, ohne daran denken zu müssen, den Code beim Kopieren und Einfügen zu ändern. Alternativ könnte ich eine Protokollierungsklasse erstellen und jede andere Klasse von meiner Protokollierungsklasse erben lassen.

Agent RhoShambo
quelle
0

Nachteil des zweiten Ansatzes ist ein großes Repository mit erstellten Loggern. Diese Logger machen dasselbe, wenn root definiert ist und Klassenlogger nicht definiert sind. Das Standardszenario auf dem Produktionssystem verwendet nur wenige Logger, die einer Klassengruppe zugeordnet sind. Entschuldigung für mein Englisch.

user1785960
quelle