0

log4net 1.2.10.0 を使用しています。ILog と LogManager を拡張して、新しいレベル「AUDIT」を含めました。AdoNetAppenderを使用して をデータベースに記録したいと考えて%messageいます。他の情報をログに記録する必要があるため、 を使用してみlog4net.ThreadContext.Propertiesました。

コンテキスト プロパティを SQL パラメータの値として使用しようとすると、出力が得られません。

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

実行コードは次のとおりです(log4netが初期化され、ロガー「log」が作成されていると仮定)。

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

SQL パラメータを使用する代わりに値をハードコーディングすると、アペンダは AUDIT フィルタで動作します。

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

INFO などの組み込みレベルでフィルター処理する場合、アペンダーはコンテキスト プロパティで動作します。

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

FileAppenderAUDIT フィルターとコンテキスト プロパティで動作します。

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

その結果

AUDIT [value] - a message

グローバル コンテキスト プロパティの使用は、AdoNetAppenderおよび AUDIT フィルターで機能します。しかし、スレッド コンテキストの解決が必要です。

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

その結果

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

AdoNetAppenderしたがって、それが拡張クラスまたは構成に問題があるかどうかはわかりません。

4

1 に答える 1

0

この問題は、フォアグラウンド スレッドが早期に中止されたことが原因でした。log4net が非同期操作を実行していたと思います。テストアプリの最後にスリープを置くと、問題が修正されました

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

または、別のスレッドにいる場合は、それに参加します

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

通常の操作では、log4net には、最新の AUDIT 呼び出しと実行の終了の間に十分な時間が必要です。

于 2009-03-06T14:40:50.680 に答える