Friday, September 10, 2010

Easy log4net integration into .NET applications

There are plenty of possibilities to integrate log4net logging into your application. You can declare log4net configuration declaratively or imperatively for the whole project, in each separate assembly or even in each separate class. The pattern I describe below assumes that:

  • you want to have a single and possibly the simplest configuration of the log4net for your whole application
  • you do not want to call explicitely any complicated initialization code
  • you do not want to create loggers explicitely (people tend to do that however it’s rather cumbersome)

The idea is as follows – you create a simple proxy class for the logging purposes. The class will have a static constructor responsible for configuring the log4net and two proxy methods for actual logging. It’s up to you to declare this class in the of your assemblies which is then referenced by other solution assemblies.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using log4net;
using log4net.Config;
 
namespace BusinessLibrary.Common
{
    public class Log
    {
        static Log()
        {
            XmlConfigurator.Configure();
        }
 
        public static ILog For( object LoggedObject )
        {
            if ( LoggedObject != null )
                return For( LoggedObject.GetType() );
            else
                return For( null );
        }
 
        public static ILog For( Type ObjectType )
        {
            if ( ObjectType != null )
                return LogManager.GetLogger( ObjectType.Name );
            else
                return LogManager.GetLogger( string.Empty );
        }
    }
 
}

From now on the only way you log anything is to use the proxy class:

Log.For( this ).Info( "Hello from BusinessClass" );

Then, in the application’s configuration file you provide a single configuration for log4net. I usually delegate the configuration to a separate file so that the web.config/app.config contains only:

<configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
    ...
</configSections>
<log4net configSource=".\Configuration\log4net.config"/>

and a separate file, located under \Configuration\log4net.config contains the actual configuration:

<?xml version="1.0" standalone="yes"?>
<log4net>
    <appender name="TestLogFileAppender" type="log4net.Appender.RollingFileAppender">
        <file value="c:\000\test.log" />
        <appendToFile value="true" />
        <rollingStyle value="Size" />
        <filter type="log4net.Filter.LevelRangeFilter">
            <acceptOnMatch value="true" />
            <levelMin value="DEBUG" />
            <levelMax value="FATAL" />
        </filter>
        <maxSizeRollBackups value="10" />
        <maximumFileSize value="10MB" />
        <staticLogFileName value="true" />
        <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
        <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%newline%date [%thread] %-5level - %message" />
        </layout>
    </appender>
    <root>
        <level value="ALL" />
        <appender-ref ref="TestLogFileAppender" />
    </root>
</log4net>

(this is only an example configuration)

That’s all. No other code is required to either configure log4net itself or create logging objects. You’ll find an example, consisting of a web application and an auxiliary assembly here.

No comments: