I am using log4net 1.2.10.0. I have extended ILog and LogManager to include a new level, 'AUDIT'. I want to use an AdoNetAppender
to log the %message
to a database. I need other information logged and I tried using log4net.ThreadContext.Properties
.
I get no output when I try to use a context property as a value for a SQL parameter.
<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>
The executing code is (assuming log4net has been init'ed and a logger, 'log', has been created).
log4net.ThreadContext.Properties["custom_prop"] = "value";
log.Audit("a message");
The appender works with the AUDIT filter if I hard-code a value instead of using a SQL parameter.
...
<commandText value="INSERT INTO table1 VALUES('value', :message)" />
...
The appender works with the context property if I filter on a built-in level, like INFO.
...
<filter type="log4net.Filter.LevelMatchFilter">
<levelToMatch value="INFO" />
</filter>
...
A FileAppender
works with the AUDIT filter and context property!
<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>
Resulting in
AUDIT [value] - a message
Using a global context property works with the AdoNetAppender
and AUDIT filter. But, I need thread context resolution.
log4net.GlobalContext.Properties["custom_prop"] = "value";
log.Audit("a message");
Resulting in
table1
custom_prop message
=========== =======
value a message
So, I don't know if it's a problem with the AdoNetAppender
or my extended classes or my configuration.