One thing I have to praise about moving from one job to another in the software industry, is all the new tools you pick up or pass on. This is not always the case, but hopefully your move is an equal or better learning experience. Such a simple but powerful tool have I seen, and this is the log4net logging framework for .NET. This framework is actually ported from the benevolent log4j framework which is the Java equivalent. It’s simple, elegant, and gets the job done. Many open source projects for both Java and .NET utilize this framework because it is so powerful. The main points to take away is that it’s easy to configure, easy to add different logging capabilities, and lightweight.
To get log4net working in .NET, you need to do the following easy steps:
1) Download log4net from Apache’s website.
2) Add the correct information in the app.config, in case of a web site this would be the web.config. Below show’s an example of the simplest setup. A section is added to the <configSections>, which allows the log4net framework to be loaded via app.config settings only. This is convenient for web applications since IIS doesn’t need to be restarted for changes to take affect. In the section <log4net>, you define "appenders", which are the classes that handle whatever type of logging that is desired; you can even adjust specific logging for other frameworks such as NHibernate, which utilizes log4net. The SDK describes all the built in appenders which include, but not limited to file types, database, UDP, event log, etc. For each appender that is added, you need to add the appropriate <appender-ref> element to the root element inside the log4net section. The last important item is the logging level which is listed below as well.
Available logging levels: ALL, DEBUG, INFO, WARN, ERROR, FATAL, OFF
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<log4net>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender" >
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %-5level %logger [%ndc] - %message%newline" />
</layout>
<file type="log4net.Util.PatternString" value="C:\SomeDirectoryPath\SomeFileName-%date{yyyyMMdd}.txt" />
<!--<file value="example_log.txt" />-->
<appendToFile value="true" />
<rollingStyle value="Date" />
<datePattern value="yyyyMMdd" />
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="RollingFileAppender" />
</root>
</log4net>
3) Put the logger in your code for use. Using
log4net in your code is even easier. In order to get the logging working, you need to make sure it initializes. Below shows a way to do this for a web app and a windows type service.
//////////////////////////
// for a web app
/////////////////////////
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
// init web.config configured logger before any logging occurs
log4net.Config.XmlConfigurator.Configure();
}
}
//////////////////////////
// for a windows service
/////////////////////////
private void OnStart()
{
// init app.config configured logger before any logging occurs
log4net.Config.XmlConfigurator.Configure();
}
Now to use the logging in your application code add something similar to the following class example. Registering the class with the logger allows the logging to indicate where exactly the information is coming from. This is actually very useful since you don’t have to write statements like “MethodNameXYZ had an error….”.
public class FooBar
{
private static readonly ILog _log = LogManager.GetLogger(typeof(FooBar));
private static readonly bool _isDebugEnabled = _log.IsDebugEnabled;
public void DoSomething()
{
_log.Info("I'm starting to do something really useful.");
// better performance than calling _log.Debug(...); OR (_log.IsDebugEnabled) ...
if (_isDebugEnabled)
_log.Debug("Some extra useful debug info...");
try {...}
catch (Exception x)
{
_log.Error("Oh darn, something bad happened", x);
// you can also do LogManager.GetLogger(typeof(FooBar)).Error(...) if you don't want to have a static.
}
finally {...}
}
}