Home
Atom Feed

Logging with Log4Net in C#

Over the past years I've been asked quite a number of times how to configure Log4Net in C#.

There are some examples out there, but I've found that most of are either too complicated or are too specific.
In the end I decided that the only way to fix the problem is to write a general tutorial on Log4Net configuration myself.

Basics

Use NuGet to download and install the latest version of Log4Net.

Config files

Now you need to configure Log4Net.

First off you need to add a configuration section to your web.config or app.config (for NUnit tests, use app.config).

<configuration>
  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
  </configSections>
  ...
</configuration>

 Then you need to add the actual configuration, in one or two ways:

  1. In a separate file
    Create a file called log4net.config in your project and write "<log4net></log4net>" in it.
    Add "<log4net configSource="log4net.config" />" under the <configSections/> element.
  2. In the web.config / app.config file
    Add "<log4net></log4net>" under the <configSections/> element.

Then add the following code in the <log4net /> element (I will explain what it does later):

<appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
    <param name="File" value="MyFirstLogger.log"/>
    <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
    <appendToFile value="true" />
    <rollingStyle value="Size" />
    <maxSizeRollBackups value="2" />
    <maximumFileSize value="1MB" />
    <staticLogFileName value="true" />
    <layout type="log4net.Layout.PatternLayout">
            <param name="ConversionPattern" value="%d [%t] %-5p %c %m%n"/>
    </layout>
</appender>

<root>
    <level value="ALL" />
    <appender-ref ref="LogFileAppender" />
</root>

The <appender /> element specifies name and logger type. In this instance I'm using a rolling file appender, but there are numerous other types available.

<param name="File" ... />  specifies the file name and path. In this case it will log to a file called MyFirstLogger.log in the application root directory.

The <lockingModel /> element is very important. Without it, your application will lock the file, preventing you from doing anything with it unless you shut down the application/website.

<appendToFile value="true"/> tells Log4Net to put new entries at the end of the file.

<rollingStyle value="Size" /> is specific for the RollingFileAppender, and specifies the criteria type for when it should "roll" i.e. create a new file. In this case we will specify a max file size.

<maxSizeRollBackups value="2" /> is for specifying the maximum number of log files to keep. In this case, it will not keep more than two log files.

The <maximumFileSize value="1MB" /> element lets us set a log file size limit, which is nice if you want to keep control of disk space usage. In combination with the above element, it will keep two files with a maximum size each of 1MB.

<staticLogFileName value="true" /> means that it will not change the file name, just the extension.

The <layout/> element tells Log4Net how each log line should look like. You can read more about the possibilities here
I find that the layout specified above suits all of my needs, and is clear and concise. 

<root> is the root logger. If set, then all logger instances in your application will turn up in the logger specified in the <appender-ref />element (I will show you how to tweak this later). The <level/> element specifies the log level.

"Booting" Log4Net

Now that everything is configured, we need to get the application to read in the configuration.

There are several ways to do this, the main one is to insert the following line in your application startup code:

XmlConfigurator.Configure();

Now Log4Net is primed and ready to be used.

Logging

In the class you want to use logging, add the following property:

private readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

This will create a logger with the same name as the full name of your class. I will show you how to utilize that later.

To perform logging now, you can just do like this:

this.log.Debug("Debug message");
this.log.Info("Info message");
this.log.Warn("Warning message");
this.log.Error("Error message");
this.log.Fatal("Fatal message");

 

Advanced logging

Now that we've been through the basics, it's time to do some more advanced logging.

More appenders

Add the following code to your <log4net/> section:

<appender name="SecondLogFileAppender" type="log4net.Appender.RollingFileAppender">
    <param name="File" value="MySecondLogger.log"/>
    <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
    <appendToFile value="true" />
    <rollingStyle value="Size" />
    <maxSizeRollBackups value="3" />
    <maximumFileSize value="2MB" />
    <staticLogFileName value="true" />
    <layout type="log4net.Layout.PatternLayout">
            <param name="ConversionPattern" value="%d [%t] %-5p %c %m%n"/>
    </layout>
</appender>

<logger name="MyNamespace.MySecondClass">
    <level value="DEBUG" />
    <appender-ref ref="SecondLogFileAppender" />
</logger>

The name attribute of the <logger/> element is used to capture logs. That means if your class is named "MyNamespace.MyClass" then it will log to the "MyNamespace.MySecondClass" logger.

If the logger name would have been just "MyNamespace", then it would get the logs from all classes with that namespace.

You can also create a logger with a name like "MyAwesomeLogger" and use the following code when instantiation the logger in your class:

private readonly ILog log = LogManager.GetLogger("MyAwesomeLogger");

Configuring Log4Net without application startup code 

This is a valid scenario for plugins and other things where you don't have control over the application startup code. 

It can be done in one of two ways:

  • WebActivator (only valid if the root application is a web application)
    Then you can use the following code to boot Log4Net:
    [assembly: WebActivator.PreApplicationStartMethod(typeof(MyNamespace.App_Start.Bootstrapper), "Start")]
    
    namespace MyNamespace.App_Start
    {
        public static class Bootstrapper 
        {
            public static void Start()
            {
                XmlConfigurator.Configure();
            }
        }
    }
    
  • Assembly attributes
    Add the following to your AssemblyInfo.cs file:
    [assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]
    

Ninject bonus tip

Even if you're using Ninject.Extensions.Logging, you still have to configure log4net after the tutorials above.
Unfortunately, it doesn't magically work out of the box.

 

This should be enough to get you started with Log4Net in C#. Feel free to comment below if you find anything unclear or wrong.