log4net filter by threadcontext property (.NET Core)

882 views Asked by At

I am trying to create mulitple appenders each logging only certain messages. Filtering should be performed based on the selected property set to the ThreadContext. What I did is as follows (log4net.config)

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <section name="log4net" type="System.Configuration.IgnoreSectionHandler" />
  </configSections>
  <log4net>

    <appender name="FileAppender" type="log4net.Appender.RollingFileAppender">
      <file value="MyLog_"/>
      <appendToFile value="true"/>
      <rollingStyle value="Composite"/>
      <datePattern value="yyyy-MM-dd.\l\o\g"/>
      <maximumFileSize value="100MB"/>
      <staticLogFileName value="false"/>
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date{HH:mm:ss.fff} [%4thread] [%property{Category}] %-5level %logger - %message%newline"/>
      </layout>
      <filter type="log4net.Filter.PropertyFilter">
        <Key value="Category" />
        <StringToMatch value="3" />
        <acceptOnMatch value="true" />
      </filter>
    </appender>

    <appender name="SecurityFileAppender" type="log4net.Appender.RollingFileAppender">
      <file value="MyLog_Security_"/>
      <appendToFile value="true"/>
      <rollingStyle value="Composite"/>
      <datePattern value="yyyy-MM-dd.\l\o\g"/>
      <maximumFileSize value="100MB"/>
      <staticLogFileName value="false"/>
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date{HH:mm:ss.fff} [%4thread] [%property{Category}] %-5level %logger - %message%newline"/>
      </layout>
      <filter type="log4net.Filter.PropertyFilter">
        <key value="Category" />
        <stringToMatch value="1" />
        <acceptOnMatch value="true" />
      </filter>
    </appender>

    <root>
      <level value="ALL" />
      <appender-ref ref="FileAppender" />
      <appender-ref ref="SecurityFileAppender" />
    </root>

  </log4net>
</configuration>

In order to set the property value prior to logging a message I issue the following line of code:

    log4net.ThreadContext.Properties["Category"] = "3";
    _log.Info("Normal info");
    log4net.ThreadContext.Properties["Category"] = "1";
    _log.Info("Security info");

I tried configuring log4net with and without 'acceptOnMatch'. In each case seems like the filter by thread context isn't working. Both messages appear in both files.

How should I fix the configuration in order to make filter by thread context property working? Is it doable at all?

Thanks, Radek

1

There are 1 answers

0
Radek Strugalski On

To fix it I needed to add second filter configuration beneath each filter already defined as follows:

<filter type="log4net.Filter.DenyAllFilter" />

This makes the filter above working. Strange but this is how it works.

Example fixed appender looks like this:

<appender name="SecurityFileAppender" type="log4net.Appender.RollingFileAppender">
   ...
      <file value="MyLog_Security_"/>
      <filter type="log4net.Filter.PropertyFilter">
        <key value="Category" />
        <stringToMatch value="1" />
        <acceptOnMatch value="true" />
      </filter>
      <filter type="log4net.Filter.DenyAllFilter" />
    </appender>