tags:

views:

238

answers:

2

In my application, I use log4net, with all types creating their own logger based on their type - e.g. :

private static readonly ILog Log = LogManager.GetLogger(typeof(Program));

As I am developing, I leave the root logger on DEBUG so as to catch all log output from my code.

However, a third party component also uses this same approach, but is generating 100s of log messages a second, none of which I am interested in.

Is it possible to use some sort of wildcarding in the logger configuration, to force all their loggers to only log at WARN, e.g. :

 <logger name="com.thirdparty.*">
    <level value="WARN"/>
  </logger>

[The exact example above, using a * doesn't work]

A: 

Can't you do the opposite of what you're asking. What I mean is just set the default log level to warn and then set the specific loggers you have defined to DEBUG.

Also, you could set the threshold of your appender to DEBUG and have the other appender set the WARN.

For example

<appender name="EventLogAppender" type="log4net.Appender.EventLogAppender">
    <applicationName value="Application" />
    <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
    </layout>
    <threshold value="WARN" />
</appender>

<appender name="SmtpAppender" type="log4net.Appender.SmtpAppender,log4net">
    <to value="[email protected]" />
    <from value="[email protected]" />
    <subject value="Notification" />
    <smtpHost value="server01" />
    <bufferSize value="1" />
    <lossy value="false" />
    <layout type="log4net.Layout.PatternLayout,log4net">
        <conversionPattern value="%property{log4net:HostName} :: %level :: %message %newlineLogger: %logger%newlineThread: %thread%newlineDate: %date%newlineNDC: %property{NDC}%newline%newline" />
    </layout>
    <threshold value="DEBUG" />
</appender>
Brian Hasden
@Brian - Thanks for the reply. Yes - I *could* but the problem is that I have many types. To take a whitelist approach to logging would make my logging configuration huge and unwieldy, which is why I was wondering about a blacklist approach.
Rob Levine
Understood. I was just giving a possible approach depending on how many other loggers you have defined. I updated my answer to suggest defining a threshold at the appender level. Then just change the 3rd party library to use an appender with the appropriate threshold while your appender is still set to DEBUG.
Brian Hasden
@Brian - thanks for the suggestion in any case - it is a good approach if you only have a few loggers. As for your second part of the suggestion - in my case I want the to both go to the same target (a single log file, or a console window). Would this approach still work there?
Rob Levine
No, if you change the threshold on an appender it applies to every logger logging to it. What that means is if you're going to point all loggers to the same appender then they're all going to have the same threshold. It wouldn't work for your situation.
Brian Hasden
+4  A: 

You can just specify part of a namespace so it will apply to all messages within that namespace (including nested).

Here is the example I often use:

  <root>
    <level value="FATAL" />
    <appender-ref ref="RollingFile" />
  </root>

  <logger name="MyCompany.Web" >
    <level value="WARN" />
    <appender-ref ref="WebErrors" />
  </logger>

  <!-- Will log all FATALs from NHibernate, including NHibernate.SQL and all the nested -->
  <logger name="NHibernate" >
    <level value="FATAL" />
  </logger>

Additionally I would recommend to read the manual. It provides a lot of explanation. For example you can read about Logger Hierarchy. Here is the quote from there:

A logger is said to be an ancestor of another logger if its name followed by a dot is a prefix of the descendant logger name. A logger is said to be a parent of a child logger if there are no ancestors between itself and the descendant logger. The hierarchy works very much in the same way as the namespace and class hierarchy in .NET.

and also:

Level Inheritance: The inherited level for a given logger X, is equal to the first non-null level in the logger hierarchy, starting at X and proceeding upwards in the hierarchy towards the root logger.

Dmytrii Nagirniak
@Dmitriy - You're right. I never knew that! I almost feel kinda silly for asking now :). Thanks for the answer.
Rob Levine
Wow, me either. That's great information.
Brian Hasden
BTW, all that is well documented on the log4net website. I added the link to the answer.
Dmytrii Nagirniak
Thanks for the link Dmitriy. I can't help but wonder where Stack Overflow would be if everyone just read the manual.
Brian Hasden