2010-10-18 9 views
6

Kann ein log4net-angepasster PatternLayoutConverter erstellt werden, der die Konfiguration eines "Index" -Werts ermöglicht? Ich weiß um die „Eigenschaft“ conversion Zeichenfolge, die Sie Code wie folgt schreiben können:Benutzerdefinierte log4net-Eigenschaft PatternLayoutConverter (mit Index)

ThreadContext.Properties["ID"] = yourID; 

und geben Sie wie folgt aus:

%property{ID} 

, dass der Wert in der Ausgabe enthalten sein sollten.

Was ist, wenn die Werte, die ich protokollieren möchte, in einem anderen "Wörterbuch" sind? Ich nehme an, dass ich eine Logik schreiben könnte, um diese Werte aus dem Wörterbuch in einen der log4net-Kontexte zu kopieren und dann einfach das eingebaute Token %property zu verwenden. Was ist, wenn log4net die Werte direkt aus meinem eigenen "Wörterbuch" basierend auf einem in der Konfigurationsdatei angegebenen Indexwert protokollieren soll?

Kann ich meine eigenen PatternLayoutConverter schreiben, die mir so etwas zu konfigurieren erlauben würde:

%myproperty{ID} 

Und dann die entsprechende „ID“ Wert aus meinem eigenen „Wörterbuch“ ziehen?

Für jeden, der interessiert ist, ist es ziemlich einfach, die gleiche Sache mit NLog zu tun:

[LayoutRenderer("MyGDC")] 
    class GdcLayoutRenderer : LayoutRenderer 
    { 
    [RequiredParameter] 
    [DefaultParameter] 
    public string Item { get; set; } 

    protected override void Append(StringBuilder builder, LogEventInfo logEvent) 
    { 
     string msg = GDC.Get(this.Item); 
     builder.Append(msg); 
    } 

    protected override int GetEstimatedBufferSize(LogEventInfo logEvent) 
    { 
     return 10; 
    } 
    } 

Und wie folgt konfiguriert:

Sagen NLog über alle Baugruppen mit Erweiterungen:

<extensions> 
    <add assembly="NLog.Extensions"/> 
    </extensions> 

Verwenden Sie die Eigenschaft "indexiert" in einem Layout:

In diesem Beispiel verwende ich NLogs GDC-Objekt tatsächlich als mein "Wörterbuch", aber ich zeige, wie ich meinen eigenen "indexierbaren" LayoutRenderer schreiben konnte (mehr oder weniger äquivalent zu log4nets PatternLayoutConverter), um auf einen indexierten Wert zuzugreifen ein Wert in der Konfigurationsdatei.

[EDIT] Ich bekam die Antwort, die ich wollte. Ich habe hier den Code für meinen Beispiel-PatternLayoutRenderer eingefügt. In meinem Test habe ich ein statisches Wörterbuch in meiner Hauptformklasse, wo ich "Anwendungseinstellungen" speichern konnte. Ich habe einen PatternLayoutConverter erstellt, der einen Schlüssel als Parameter akzeptiert, damit der Konverter den richtigen Wert im Wörterbuch nachschlagen kann. Ich könnte vielleicht die gleiche Funktionalität mit den log4net (oder NLog) Kontextobjekten erreichen, aber in unserer Anwendung haben wir vielleicht einige Einstellungen oder Sitzungsinformationen, die die Anwendung für andere Zwecke bereithält, und wir möchten diese zu den Protokollausgabe. Da es sich bereits in einer Lookup-Struktur befindet, wäre es schön, in der Lage zu sein, die Daten direkt zu referenzieren, anstatt sie explizit in das log4net (oder den NLog-Kontext) kopieren zu müssen.

Wie auch immer, hier ist der Code:

namespace Log4NetTest 
{ 
    class KeyLookupPatternConverter : PatternLayoutConverter 
    { 
    protected override void Convert(System.IO.TextWriter writer, LoggingEvent loggingEvent) 
    { 
     //Use the value in Option as a key into the "application settings" stored on the main form. 
     string setting; 
     if (Form1.AppSettings.TryGetValue(Option, out setting)) 
     { 
     writer.Write(setting); 
     } 
    } 
    } 
} 

Layout-Konfiguration:

//Log the "sessionid" and "userid" values from our "application settings" object 
    <layout type="log4net.Layout.PatternLayout"> 
    <param name="ConversionPattern" value="%d [%t] %-5p [session = %KLPC{sessionid}] [user = %KLPC{userid}] %m%n"/> 
    <converter> 
     <name value="KLPC" /> 
     <type value="Log4NetTest.KeyLookupPatternConverter" /> 
    </converter> 
    </layout> 

Antwort

4

ich es nicht versucht haben, aber dies sollte funktionieren.In Log4Net können Sie eine Option Zeichenfolge in ein Muster-Wandler wie folgt passieren:

%converterName{converterOptions} 

Das Datum Musterumwandler kann zum Beispiel wie folgt verwendet werden:

%date{HH:mm:ss,fff} 

Dies bedeutet, dass Sie Ihr Musterumwandler schreiben kann wie du es vorgeschlagen hast. Ein einfaches Beispiel für einen solchen Konverter finden Sie unter here.

In der Convert Methode können Sie auf die Eigenschaft Zeichenfolge mit der Eigenschaft 'Option' (definiert in der PatternConverter Klasse) zugreifen und den Thread-Kontext verwenden, um den gewünschten Eintrag aus dem Wörterbuch zu erhalten. Sie können die Schnittstelle IOptionHandler auch implementieren, wenn Ihre Optionen mehr als nur den Wörterbuchschlüssel umfassen: So können Sie die Optionen bei Aktivierung der log4net-Konfiguration analysieren.

+0

Danke! Das hat genau das gemacht, was ich machen wollte. Ich werde meinen Test LayoutPatternConverter meiner Frage als Referenz hinzufügen, falls jemand anderes interessiert ist. – wageoghe