Logging With Log4Net

Jumping back to a bit of .Net development this week.

As techniques go, logging is one of the simplest and most useful in a developer’s toolbox. Once your code is out and running in the wild, it becomes a lot harder to track down issues without being able to jump into the debugger. Logging to the rescue!

There are a number of logger implementations for the .Net Framework, including nLog, Microsoft’s Enterprise Library, and my personal choice, log4net.

log4net is a very flexible logging library that provides the ability to log to a number of different outputs, which can be changed easily through configuration files, even at run time.

Setting Up

In your AssemblyInfo.cs add the following to have the config picked up:

[assembly: log4net.Config.XmlConfigurator(ConfigFile = "Log4Net.config", Watch = true)]

Specifying the watch option will cause log4net to monitor the configuration file for changes. This is fantastically useful, allowing you to change the logging level dynamically without needing to restart your application.

Speaking of configuration, add a file named log4net.config to the root of your project:

<log4net debug="false">
  <!-- Define some output appenders -->
  <appender name="rollingFile" type="log4net.Appender.RollingFileAppender,log4net" >
    <param name="File" value="logs/log.txt" />
    <param name="AppendToFile" value="true" />
    <param name="RollingStyle" value="Size" />
    <param name="MaximumFileSize" value="250KB" />
    <param name="StaticLogFileName" value="true" />
    <param name="MaxSizeRollBackups" value="10" />

    <layout type="log4net.Layout.PatternLayout,log4net">
      <param name="ConversionPattern"
        value="%d{dd/MM/yy HH:mm:ss} %-5p %m%n" />
    </layout>
  </appender>

  <!-- Setup the root category, add the appenders and set the default priority -->
  <root>
    <priority value="INFO" />
    <appender-ref ref="rollingFile" />
  </root>
</log4net>

This specifies a logger that will output to a file in the logs directory, along with a default logger that will log anything above an info message.

Start Logging

Once that’s done, start logging!

ILog logger = log4net.LogManager.GetLogger("Logger");
logger.Info("Testing logging");

Bonus: NHibernate

NHibernate has built in support for log4net which can be really helpful when trying to debug issues.

To enable logging for NHibernate, all you need to do is add the following loggers to the log4net.config file:

<logger name="NHibernate" additivity="false">
    <level value="INFO"/>
    <appender-ref ref="rollingFile" />
  </logger>

  <logger name="NHibernate.SQL" additivity="false">
    <level value="INFO"/>
    <appender-ref ref="rollingFile" />
  </logger>

Alter the level value to change how much detail you get. Info will get you a lot of detail on queries being run, whilst Warn or Error will limit output to just those messages that are fired off when things are going wrong.

*Update*

I’ve just been bashing my head against the wall trying to get some logging out of NHibernate, whilst not actually logging anything else.

It seems that because I wasn’t instantiating a logger anywhere in code, this was preventing anything being logged by NHibernate.

All I ended up doing was placing the following in my MVCApplication class:

private static ILog logger = log4net.LogManager.GetLogger("default");

*Another Update*

Just for my own sanity so that I don’t forget again, you will also need to give write access to the log folder for the user that will be writing there. In the case of ASP .Net MVC, this will be the user setup in the app pool, which is usually something like “IIS AppPool\DefaultAppPool” or “IIS AppPool\ASP.Net v4.0”.

Leave a Reply

Your email address will not be published. Required fields are marked *