2009-03-05 10 views
0

Ich benutze log4net 1.2.10.0. Ich habe ILog und LogManager um eine neue Stufe erweitert, "AUDIT". Ich möchte eine AdoNetAppender verwenden, um die %message zu einer Datenbank zu protokollieren. Ich brauche andere Informationen protokolliert und ich habe versucht mit log4net.ThreadContext.Properties.ThreadContext Eigenschaft schreibt nicht in AdoNetAppender

Ich bekomme keine Ausgabe, wenn ich versuche, eine context-Eigenschaft als Wert für einen SQL-Parameter zu verwenden.

<log4net> 
    <level> 
    <name value="AUDIT" /> 
    <value value="35000" /> 
    </level> 
    <appender name="AdoNetAppender.Audit" type="log4net.Appender.AdoNetAppender"> 
    <filter type="log4net.Filter.LevelMatchFilter"> 
     <levelToMatch value="AUDIT" /> 
    </filter> 
    <filter type="log4net.Filter.DenyAllFilter" /> 
    <connectionType value="System.Data.OracleClient.OracleConnection, System.Data.OracleClient, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> 
    <connectionString value="data source=db1;User ID=user;Password=pass" /> 
    <commandText value="INSERT INTO table1 VALUES(:custom_prop, :message)" /> 
    <parameter> 
     <parameterName value=":custom_prop" /> 
     <dbType value="String" /> 
     <layout type="log4net.Layout.PatternLayout"> 
     <conversionPattern value="%property{custom_prop}" /> 
     </layout> 
    </parameter> 
    <parameter> 
     <parameterName value=":message" /> 
     <dbType value="String" /> 
     <layout type="log4net.Layout.PatternLayout"> 
     <conversionPattern value="%message" /> 
     </layout> 
    </parameter> 
    </appender> 
    <root> 
    <level value="ALL" /> 
    <appender-ref ref="AdoNetAppender.Audit" /> 
    </root> 
</log4net> 

Der Ausführungscode wird (unter der Annahme log4net hat init'ed worden und ein Logger 'log', erstellt wurde).

log4net.ThreadContext.Properties["custom_prop"] = "value"; 
log.Audit("a message"); 

Die appender arbeitet mit dem AUDIT-Filter, wenn ich einen Wert fest einprogrammieren stattdessen einen SQL-Parameter verwenden.

Der Appender arbeitet mit der context -Eigenschaft, wenn ich auf einer eingebauten Ebene wie INFO filtere.

... 
<filter type="log4net.Filter.LevelMatchFilter"> 
    <levelToMatch value="INFO" /> 
</filter> 
... 

Ein FileAppender arbeitet mit der AUDIT Filter- und Kontexteigenschaft!

<appender name="FileAppender" type="log4net.Appender.FileAppender" > 
    <filter type="log4net.Filter.LevelMatchFilter"> 
    <levelToMatch value="AUDIT" /> 
    </filter> 
    <filter type="log4net.Filter.DenyAllFilter" /> 
    <file value="test.log" /> 
    <layout type="log4net.Layout.PatternLayout" > 
    <conversionPattern value="%-5level [%property{custom_prop}] - %message%newline" /> 
    </layout> 
</appender> 

Resultierende in

AUDIT [value] - a message 

eine globale Kontexteigenschaft Mit arbeitet mit den AdoNetAppender und AUDIT-Filter. Aber ich brauche Thread-Kontextauflösung.

log4net.GlobalContext.Properties["custom_prop"] = "value"; 
log.Audit("a message"); 

in Resultierenden

table1 
custom_prop message 
=========== ======= 
value  a message 

Also, ich weiß nicht, ob es ein Problem mit den AdoNetAppender oder meinen erweiterten Klassen oder meiner Konfiguration ist.

+0

LogicalThreadContext scheint auch mit der AdoNetAppender- und AUDIT-Ebene zu funktionieren. –

+0

Es hat gerade angefangen mit den Eigenschaften von ThreadContext zu arbeiten, ich habe keine Ahnung, was passiert. –

Antwort

0

Das Problem wurde durch frühzeitige Abtreibung des Vordergrundthreads verursacht. Ich denke, log4net hat eine asynchrone Operation ausgeführt. einen Schlaf am Ende des Tests-App Putting das Problem behob

... 
log4net.ThreadContext.Properties["custom_prop"] = "value"; 
log.Audit("a message"); 
... 
Thread.Sleep(1000); 

oder, wenn sie in einem separaten Thread, auf mich Beitritt

Thread t = new Thread(new ThreadStart(delegate 
{ 
    log4net.ThreadContext.Properties["custom_prop"] = "value"; 
    log.Audit("a message");   
})); 
t.Start(); 
... 
t.Join(); 

Im Normalbetrieb sollte log4net genug Zeit zwischen dem letzten hat AUDIT-Aufruf und das Ende der Ausführung.