Frage

Ich verwende log4net 1.2.10.0. Ich habe ILog und LogManager erweitert, um eine neue Ebene zu schließen, ‚Audit‘. Ich mag eine AdoNetAppender verwenden, um den %message auf eine Datenbank zu protokollieren. Ich brauche andere Informationen protokolliert und ich versuchte log4net.ThreadContext.Properties verwenden.

Ich bekomme keine Ausgabe, wenn ich versuche, eine Kontexteigenschaft 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>

Die Ausführung von Code ist (unter der Annahme log4net init'ed und einen Logger wurde, 'log', erstellt wurde).

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

Die appender arbeitet mit dem AUDIT-Filter, wenn ich hart Code ein Wert stattdessen einen SQL-Parameter verwendet wird.

...
<commandText value="INSERT INTO table1 VALUES('value', :message)" />
...

Die appender arbeiten mit der Kontexteigenschaft, wenn ich auf einem integrierten Level-Filter, wie INFO.

...
<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>

Was zu

AUDIT [value] - a message

eine globale Kontexteigenschaft Mit arbeitet mit den AdoNetAppender und AUDIT-Filter. Aber, ich brauche Kontextauflösung fädeln.

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

Was zu

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.

War es hilfreich?

Lösung

Das Problem wurde von den frühen Abbruch des Vordergrundthread verursacht. Ich denke, log4net eine Asynchron-Operation ausgeführt wurde. Putting ein Schlaf am Ende der Test-App das Problem behoben

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

oder, wenn sie in einem separaten Thread, auf sie Füge

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

Im Normalbetrieb log4net sollte genügend Zeit zwischen dem letzten AUDIT Ruf hat und Ende der Ausführung.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top