Monday, April 11, 2011

How do I Filter on a custom Level in log4net?

I copied the log4net samples to implement a custom log level, AUDIT. I defined AUDIT to have a value of 35000, between DEBUG 30000 and INFO 40000.

The following is my configuration section. I have one appender that logs all levels and one that is supposed to log only AUDIT levels (this is just for testing)

<log4net>
  <appender name="FileAppender" type="log4net.Appender.FileAppender" >
    <file value="testrun.log" />
    <layout type="log4net.Layout.PatternLayout" >
      <conversionPattern value="%date{HH:mm:ss:fff} [%thread] %-5level %logger{1} - %message%newline" />
    </layout>
  </appender>
  <appender name="FileAppender.Audit" type="log4net.Appender.FileAppender" >
    <filter type="log4net.Filter.LevelMatchFilter">
      <levelToMatch value="AUDIT" />
    </filter>
    <file value="testrun.audit.log" />
    <layout type="log4net.Layout.PatternLayout" >
      <conversionPattern value="%date{HH:mm:ss:fff} [%thread] %-5level %logger{1} - %message%newline" />
    </layout>
  </appender>  
  <root>
    <level value="ALL" />
    <appender-ref ref="FileAppender" />
    <appender-ref ref="FileAppender.Audit" />
  </root>
</log4net>

The test method is

private static readonly IAuditLog log = AuditLogManager.GetLogger(typeof(Program));
public static void Main()
{
    log.Debug("Debug");
    log.Audit("Audit");
    log.Info("Info");
}

However, the output of the appenders is the same...

13:09:11:540 [9] DEBUG Program - Debug
13:09:11:560 [9] AUDIT Program - Audit
13:09:11:560 [9] INFO  Program - Info

The log4net debug output when parsing the LevelMatchFilter is

log4net: Loading Appender [FileAppender.Audit] type: [log4net.Appender.FileAppender]
log4net:ERROR XmlHierarchyConfigurator: Unknown Level Specified [AUDIT]
log4net:WARN Unable to set property [levelToMatch] on object [log4net.Filter.LevelMatchFilter] using value [AUDIT] (with acceptable conversion types)
log4net: Setting Collection Property [AddFilter] to object [log4net.Filter.LevelMatchFilter]
From stackoverflow
  • You will need to add

    <level>
      <name value="AUDIT" />
      <value value="35000" />
    </level>
    

    in your log4net config section.

  • Responding to olle...

    I added the level to my configuration section

    <level>
      <name value="AUDIT" />
      <value value="35000" />
    </level>
    

    and the internal debug output shows

    log4net: Setting Property [Name] to String value [AUDIT]
    log4net: Setting Property [Value] to Int32 value [35000]
    

    and when setting up the FileAppender.Audit appender

    log4net: Loading Appender [FileAppender.Audit] type: [log4net.Appender.FileAppender]
    log4net: Setting Property [LevelToMatch] to Level value [AUDIT]
    log4net: Setting Collection Property [AddFilter] to object [log4net.Filter.LevelMatchFilter
    

    But, the output of both appenders is still

    13:36:42:254 [9] DEBUG Program - Debug
    13:36:42:274 [9] AUDIT Program - Audit
    13:36:42:274 [9] INFO  Program - Info
    
    olle : Can you post the code for AuditLogManager I think there must be an issue in there.
    Anthony Mastrean : If you have access to the log4net source, I literally find/replaced AUDIT over their TRACE extension example...
  • log4net version 1.2.10 requires that you end a LevelMatchFilter chain with a DenyAllFilter if you want the behavior I described in the question.

    <appender name="FileAppender.Audit" type="log4net.Appender.FileAppender" >
      <filter type="log4net.Filter.LevelMatchFilter">
        <levelToMatch value="AUDIT" />
      </filter>
      <filter type="log4net.Filter.DenyAllFilter" />
      <file value="testrun.audit.log" />
      <layout type="log4net.Layout.PatternLayout" >
        <conversionPattern value="%date{HH:mm:ss:fff} [%thread] %-5level %logger{1} - %message%newline" />
      </layout>
    </appender>
    

0 comments:

Post a Comment

Note: Only a member of this blog may post a comment.