문제

log4net 1.2.10.0을 사용하고 있습니다. 새로운 수준의 '감사'를 포함하도록 ILOG 및 LOGMANAGER를 확장했습니다. 나는 사용하고 싶다 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");

Appender는 SQL 매개 변수를 사용하는 대신 값을 하드 코딩하는 경우 감사 필터와 함께 작동합니다.

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

Appender는 정보와 같이 내장 수준에서 필터링하면 컨텍스트 속성과 함께 작동합니다.

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

FileAppender 감사 필터 및 컨텍스트 속성과 함께 작동합니다!

<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 감사 필터. 그러나 스레드 컨텍스트 해상도가 필요합니다.

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

를 야기하는

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

그래서 나는 그것이 문제인지 모르겠습니다. AdoNetAppender 또는 내 확장 클래스 또는 구성.

도움이 되었습니까?

해결책

문제는 전경 스레드의 초기 낙태로 인해 발생했습니다. 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은 최신 감사 호출과 실행 종료 사이에 충분한 시간이 있어야합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top