Friday, September 4, 2009

Logging with log4net

Log4net is a very powerful tool to get information from running application. After deployment your code has to deal with environment that is more or less different than on your development machine. Log4net not only provides your application with powerful logging where you can specify a lot of options and levels, but you can even dynamically turn on and off logging for different classes while the application is running at the same time.


The homepage of the project is:
http://logging.apache.org/log4net/index.html

I’m about to show you the way I’m usually using log4net in my projects.



Step one



The very first step is to add reference to log4net.dll to the project.



Initialization of log4net



It has to be done once in your application. You can prepare and run static initializer in the manner of:

 
public class Initializer
{
private static object _locked = new object();
protected static bool initialized = false;

public static Initializer() { Init(); }

public static void Init()
{
lock (_locked)
{
if (initialized)
return;

log4net.Config.XmlConfigurator.Configure(); // run once at app startup
...
}
}
}



Then call Initializer.Init() at application start-up from your Global.aspx or Main() for example.




Add logger for one class



One possibility to use log4net is to create separate logger for one class only. Thereof you can:

a/ write to separate and dedicated for that class only log file,
b/ or you can have different formating for logging messages from that class,
c/ or you can set different log level for the log messages from that class,
d/ or just because the class name could be written along with the logging messages so it will be easy to localize the part of the code from where the message comes.

Here is part of declaration of class named "McChannel" for which class we will define class logger.

 

// (1) add using directives:
...
using log4net;
using log4net.Config;

[ActiveRecord("mc_channels")]
public class McChannel : ActiveRecordBase
{
// (2) declare and initialize static per class logger
private static readonly ILog log = LogManager.GetLogger(typeof(McChannel));
...
}




From inside the body of that class you can use the logger "log" like:

 

log.Debug("Selecting channel names at.");
log.DebugFormat("Addiding channel {0}", one.Channel_name_official);








You have log.Debug(), log.Info(), log.Warn(), log.Error(), log.Fatal() methods you use for logging and they all have the corresponding extended with string formatting methods: log.DebugFormat(), log.InfoFormat(), log.WarnFormat(), log.ErrorFormat(), log.FatalFormat(). In the exact priority order as listed here the Debug() has the lowermost priority.

In your configuration (see below) you have to set which level of logging you want to log. The logging levels as they are defined in order of decreasing priority are:

OFF: no logging at all.
FATAL: only log.Fatal() messages will be logged
ERROR: log.Error()and higher will be logged
WARN: log.Warn() and higher will be logged
INFO: log.Info()and higher will be logged
DEBUG: log.Fatal()and higher will be logged
ALL: all logging methods will be logged.



Configuration of log4net in App.config or Web.config



Let's prepare simple configuration for log4net.

First in configSections we add element section with attribute name="log4net".
Then we add sub element "log4net" to element "configuration".

We create appender "RollingFileAppender" which defines where we write logging messages and what the pattern for formatting the log messages is. Furthermore the files will be rotated.

We can have more than one appender in your configuration.

Then we default set priority levels for the whole application to "ERROR" - see element "root" - but we define for class "McChannel" priority level of "DEBUG".

Here is the complete example:


 

<?xml version="1.0"?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
</configSections>
<log4net>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="D:\Logfile.txt" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="100" />
<maximumFileSize value="1024KB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %-5level %logger - %message%newline" />
</layout>
</appender>
<root>
<!-- ALL DEBUG INFO WARN ERROR FATAL OFF -->
<!-- Setup the root category, add the appenders and set the default level to ERROR -->
<priority value="ERROR" />
<!-- Set the default logger -->
<appender-ref ref="RollingFileAppender" />
</root>
<logger name="McChannel">
<!-- Only for the logger for class McChannel we set level to DEBUG -->
<level value="DEBUG" />
</logger>
</log4net>
</configuration>




The output of logging messages from class McChannel goes to D:\Logfile.txt after we run the application.


this.Dispose()



Log4net is very flexible. You can add the logging messages into a database table, you can use the TraceContext of ASP.NET, the console appender can produce colorized output, you can append to the Application event log in Windows, address Windows Messenger Service, send emails with logging messages and many more.

Have a nice weekend!

Atanas Hristov

No comments:

Post a Comment