2014-04-07

log4net: filtering by logger name with external libraries


When using third-party libraries and Common.Logging, if you are relying on the root logger, you might end up catching the log entries from the third-part library. While this might usefull when debugging, it might also be annoying, specially if the library is quite verbose. One of such libraries is Quartz.NET.

Luckily, log4net is flexible enough to allow us to redirect those entries to a different appender (or to turn them off completely) via the filter mechanism. My first approach was to add the following to all the appenders that I did not want to include Quartz log entries (notice that you must include the namespace for all the classes):

      <filter type="log4net.Filter.LoggerMatchFilter">

        <loggerToMatch value="Quartz.Core.QuartzScheduler" />

        <acceptOnMatch value="false" />

      </filter>

      <filter type="log4net.Filter.LoggerMatchFilter">

        <loggerToMatch value="Quartz.Core.SchedulerSignalerImpl" />

        <acceptOnMatch value="false" />

      </filter>

      <filter type="log4net.Filter.LoggerMatchFilter">

        <loggerToMatch value="Quartz.Impl.AdoJobStore.JobStoreTX" />

        <acceptOnMatch value="false" />

      </filter>

      <filter type="log4net.Filter.LoggerMatchFilter">

        <loggerToMatch value="Quartz.Impl.AdoJobStore.StdRowLockSemaphore" />

        <acceptOnMatch value="false" />

      </filter>

      <filter type="log4net.Filter.LoggerMatchFilter">

        <loggerToMatch value="Quartz.Impl.StdSchedulerFactory" />

        <acceptOnMatch value="false" />

      </filter>

      <filter type="log4net.Filter.LoggerMatchFilter">

        <loggerToMatch value="Quartz.Plugin.Xml.XMLSchedulingDataProcessorPlugin" />

        <acceptOnMatch value="false" />

      </filter>

      <filter type="log4net.Filter.LoggerMatchFilter">

        <loggerToMatch value="Quartz.Util.DBConnectionManager" />

        <acceptOnMatch value="false" />

      </filter>

Then I added the following to a new appender in which I want to catch only the Quartz.NET log entries:

      <filter type="log4net.Filter.LoggerMatchFilter">

        <loggerToMatch value="Quartz.Core.QuartzScheduler" />

      </filter>

      <filter type="log4net.Filter.LoggerMatchFilter">

        <loggerToMatch value="Quartz.Core.SchedulerSignalerImpl" />

      </filter>

      <filter type="log4net.Filter.LoggerMatchFilter">

        <loggerToMatch value="Quartz.Impl.AdoJobStore.JobStoreTX" />

      </filter>

      <filter type="log4net.Filter.LoggerMatchFilter">

        <loggerToMatch value="Quartz.Impl.AdoJobStore.StdRowLockSemaphore" />

      </filter>

      <filter type="log4net.Filter.LoggerMatchFilter">

        <loggerToMatch value="Quartz.Impl.StdSchedulerFactory" />

      </filter>

      <filter type="log4net.Filter.LoggerMatchFilter">

        <loggerToMatch value="Quartz.Plugin.Xml.XMLSchedulingDataProcessorPlugin" />

      </filter>

      <filter type="log4net.Filter.LoggerMatchFilter">

        <loggerToMatch value="Quartz.Util.DBConnectionManager" />

      </filter>

While this works, it seemed at little cumbersome to have to write all the classes that are appenders, so I investigated a little further and found out that you can use only a prefix of the namespace instead of the full class name, so you can just include the following in the appenders in which you want to remove (notice the final dot "." in the namespace):

      <filter type="log4net.Filter.LoggerMatchFilter">

        <loggerToMatch value="Quartz." />

        <acceptOnMatch value="false" />

      </filter>

And the following in the appenders in you wish to include:

      <filter type="log4net.Filter.LoggerMatchFilter">

        <loggerToMatch value="Quartz." />

      </filter>


sources: beefy code tutorial and log4net documentation

No comments:

Post a Comment