68

Is there a way to have the log4net configuration ignore a specific class? For example, we generally create a log in every class. Similar to this:

private static readonly ILog Log = log4net.LogManager.GetLogger("MyClass");

The problem is MyClass logs an extreme amount of data and it gets hard to find information about other classes. Its another dev that uses MyClass so I cannot just go in and change around the log files, but in my environment I would like to ignore these.

Can I set my configuration file to ignore the messages from a specific class?

Mehrad
  • 4,093
  • 4
  • 43
  • 61
Kyle
  • 17,317
  • 32
  • 140
  • 246

5 Answers5

86

Sure, use a filter.

Here's the snippet posted on the blog, for future reference - all credit to the author of that blog post:

<filter type="log4net.Filter.LoggerMatchFilter">
  <!-- allows this sub-namespace to be logged... -->
  <loggerToMatch value="Noisy.Namespace.But.Important" />
</filter>
<filter type="log4net.Filter.LoggerMatchFilter">
  <!-- ...but not the rest of it -->
  <loggerToMatch value="Noisy.Namespace" />
  <acceptOnMatch value="false" />
</filter>
Jerod Venema
  • 44,124
  • 5
  • 66
  • 109
60

A filter certainly works but I would prefer to turn off the logger (or logger hierarchy) directly like this:

<logger name="YourNameSpace.WithNoLogging" additivity="false">
    <level value="OFF" />        
</logger>
<logger name="MyClass" additivity="false">
    <level value="OFF" />        
</logger>
<root>
    <level value="ALL" />
    <appender-ref ref="YourAppender" />
</root>

Assuming that YourNameSpace.WithNoLogging is a namespace then the shown configuration would disable logging on the entire name space. The second "example" turns off logging for your class (according to your question).

Stefan Egli
  • 17,398
  • 3
  • 54
  • 75
  • 1
    does it work with 3rd party assemblies? I'm trying to ignore RavenDb messages, no luck so far – chester89 Apr 13 '14 at 17:38
  • 1
    I actually managed to do it - by specifying full name of the class that was logging, somehow namespace with an asterisk didn't do it – chester89 Apr 15 '14 at 09:16
  • Stefan, yep, that's on the server side – chester89 Apr 15 '14 at 09:17
  • Wildcards do not work, but you can specify a namespace instead of a class: then all classes in this namespace (and in child namespaces) will be affected – Stefan Egli Apr 15 '14 at 13:10
  • Hi, i think this only works if you use getLogger(myclass) for each Class. If you generate a named logger on applicationstart and use this by reference in your complete application, it will not work. Or am I incorrect in that point? – swe Jan 19 '15 at 11:02
  • @swe: you are correct. I prefer to use different loggers per class since it offers a lot more flexibility. – Stefan Egli Jan 20 '15 at 10:04
  • I like the idea, but I'll go for filters as I don't want the _censorship_ to happen for all appenders, only for the DB one. – Thibault D. Jan 20 '17 at 12:06
  • Based on [documentaion](https://logging.apache.org/log4net/release/manual/configuration.html#loggers), the `aditivity` attribute must be `true` (default value) for logger to inherit appenders from parent logger. If you specify it as `false` then you need to specify also the appender. Your code might seem to work as you specify level `OFF` but if you used e.g. `WARNING` to only reduce the logging, there will be still no entries in the log for `YourNameSpace.WithNoLogging` and `MyClass` loggers unless you remove the `aditivity` attribute. – eXavier Jul 13 '18 at 15:04
16

I would suggest using Filters as well. However, since I struggled finding the whole picture when I was trying to implement the filter I am posting a sample snippet of the Configutation file I created which points out where filters go.

The filter you are going for in this case would be

log4net.Filter.LoggerMatchFilter ----(Matches against a the start of the logger name.)

Hint: In the config file for Log4Net it is important where you put your tags and the priority of them actually matters. So in this case <filter> tag comes after the <appender>opening tag and before it's <file value = ... /> tag.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
    </configSections>
    <log4net>
        <appender name="RollingFile.PassedDevices" type="log4net.Appender.RollingFileAppender">
            <filter type="log4net.Filter.LoggerMatchFilter">
                <loggerToMatch value="Foo.namespace.bar.mySubclass" />
                <acceptOnMatch value="false" />
            </filter>
            <file value="myPassedDevices.log" />
            <appendToFile value="true" />
            <maximumFileSize value="100KB" />
            <maxSizeRollBackups value="2" />
            <layout type="log4net.Layout.PatternLayout">
                <conversionPattern value="%timestamp    %level  - %message  [%thread]       %logger%newline" />
            </layout>
        </appender>
        <root>
            <level value="DEBUG" />
            <appender-ref ref="RollingFile" /> <!-- My other appender which logs all and I cut it out in this snippet. Remember that you should reference all your appenders in this tag to make them work.-->
            <appender-ref ref="RollingFile.PassedDevices" />
        </root>
    </log4net>
</configuration>

In this technique you can have multiple appenders which you can redirect the logging results of a specific logger to a separate appender instead of ignoring them. Such as one appender for all logs and one for the filtered out logs for a specific class.

yohosuff
  • 1,359
  • 1
  • 11
  • 19
Mehrad
  • 4,093
  • 4
  • 43
  • 61
2

You might want to try to apply a category to your own messages Try this thread: How to add category prefix to log4net message?

Community
  • 1
  • 1
Orin
  • 351
  • 5
  • 13
  • I appreciate your hint. My filter was not working until I moved it before the 'file value =...' – leem Mar 17 '16 at 20:04
1

Just wanted to post the common exclusions if you are using NHibernate and log4net. Note that each filter needs its own element.

<filter type="log4net.Filter.LoggerMatchFilter">
    <loggerToMatch value="NHibernate.Engine.StatefulPersistenceContext.ProxyWarnLog" />
    <acceptOnMatch value="false" />
  </filter>
  <filter type="log4net.Filter.LoggerMatchFilter">
    <loggerToMatch value="NHibernate.LazyInitializationException" />
    <acceptOnMatch value="false" />
  </filter>
  <filter type="log4net.Filter.LoggerMatchFilter">
    <loggerToMatch value="NHibernate.Cache.NoCacheProvider" />
    <acceptOnMatch value="false" />
  </filter>
Juls
  • 658
  • 6
  • 15