Thursday 19 June 2008

Write to different files with Log4Net

Logging in dot.Net using Log4Net is rather easy.
We often want to write all standard infos, errors and warnings to one rolling file.
To configure this you do the following
- configure one or more appenders
- add a root logger
- configure the root logger to use your appenders

Now, if you want to write in certain cases to another file, all you need to do is to create an extra named logger and attach the appender of your choice.

Here is the config
<log4net>
  <!-- create all appenders you need here -->
  <appender name="Console" type="log4net.Appender.ConsoleAppender">
  <layout type="log4net.Layout.PatternLayout">
    <!-- Pattern to output the caller's file name and line number -->
    <conversionPattern value="%5level [%thread] (%file:%line) - %message%newline"/>
  </layout>
</appender>

<appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
<file value="MyProject.log"/>
<appendToFile value="true"/>
<rollingStyle value="composite"/>
<datePattern value="yyyyMMdd"/>
<maximumFileSize value="5MB"/>
<maxSizeRollBackups value="20"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %-5level [%thread] %logger - %message%newline"/>
</layout>
</appender>

<appender name="SpecialAuditFile" type="log4net.Appender.RollingFileAppender">
   <file value="SpecialAudit.log"/>
   <appendToFile value="true"/>
   <rollingStyle value="composite"/>
   <datePattern value="yyyyMMdd"/>
   <maximumFileSize value="5MB"/>
   <maxSizeRollBackups value="20"/>
   <layout type="log4net.Layout.PatternLayout">
     <conversionPattern value="%date %-5level [%thread] %logger - %message%newline"/>
   </layout>
</appender>

<!-- These are your loggers: one root which is always there and one named logger -->

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

<logger name="SpecialAudit" additivity="false">
  <level value="ALL" />
  <appender-ref ref= "SpecialAuditFile" />
</logger>

</log4net>

Don't forget to add the section in the configSections region
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />

And here is how you get the one and the other:
// logger for class hierarchy
private static readonly ILog logger = LogManager.GetLogger(typeof(MyClass));
// named logger
private static readonly ILog logAudit = LogManager.GetLogger("SpecialAudit");


In some cases (like Test in NUnit) an explicite call to the conifuration manager is a good idea.

XmlConfigurator.Configure();
...

And again for some test scenarios you should indicate the config filename.
You can do this with an assembly attribute in the AssemblyInfo.cs

...
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "ues.myproject.core.test.dll.config", Watch = true)]
...


The basic intro from Apache is here