I’ve started an example-application which is a simple Console application. Using this application I will try to show you how to set up, configure and use log4net.
To use log4net in your application, add it as a reference (right-click on the References-folder, navigate to where you’ve extracted the log4net-DLL, select it and click ‘OK’ ). And in the code, add the following using-statement on top of the page:
using log4net;
Now we need to add a configuration file to the project. Here we will have the necessary configuration settings for log4net. So right-click on the project, Add, New Item and in the Add New Item window, select the “Application Configuration File”. Leave the default name (App.config) and click “Add”.

When you open up the App.config file, you will see an empty configuration section.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
</configuration>
First of all we need to define a new configuration section for log4net. We also need to mention by what DLL the configuration section will be handled. We do this by adding a configSections-section in the configuration-section of the App.config:
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
Do note that we haven’t done any configuration for log4net. At this point, we’ve just told .NET that in the App.config-file there will be a section called “log4net” that will be handled by the Log4NetConfigurationSectionHandler found in the log4net assembly.
As said in Log4Net – Part I, log4net allows you to output log-information to several targets. This goes from obvious logging targets such as files, console- and trace-window, Windows Event log, database, email,… to less used output targets such as in memory buffers, Telnet sessions,… For a full list of output targets, check the “Output to multiple logging targets”-section on the features-page. Of course, it’s possible to define multiple output targets in the configuration (write a log-entry to a log-file and send an email to someone with the log-entry).
For this example I will log to both a flat file and the console-windows of my application. So now, in the App.config file I will configure log4net to do just that. The configuration will be placed in a section with the same name as I previously defined in the configSections-section (and still within the <configuration>-tags).
<log4net>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file type="log4net.Util.PatternString"
value="Log4NetSampleApp-%appdomain_%property{log4net:HostName}.log"/>
<rollingStyle value="Composite"/>
<datePattern value="yyyyMMdd"/>
<maxSizeRollBackups value="10"/>
<maximumFileSize value="2MB"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %-5level %logger: %message%newline" />
</layout>
</appender>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<threshold value="ERROR" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
</appender>
</log4net>
The RollingFileAppender
<appender>: Here I define the name and type (the library used in log4net to correctly interpret this configuration)
<file>: You can just set the value property to set the name and location of the log file like so:
<file value="C:\logfile.log" />
But it’s more interesting to define your own name using a pattern. Doing so allows you to add some information to the filename. In my case it will set the name to Log4NetSampleApp-Log4netSample.vshost.exe_DimitriPC.log. Of course, the HostName will always be my PC, but when developing applications that might run on several machines, it’s interesting to see which log file comes from which machine. Note that I haven’t set a path for the file, just a filename. The file will be dropped where the executable is: \Log4netSample\Log4netSample\bin\Debug
<rollingStyle>: This setting will tell log4net to roll files on a the date pattern defined in <datePattern>. This means that it create a new log file per day and append the date as described in the date pattern to the file. So log4net will detect that there isn’t a log file for today, and create one. If it sees that there was a log file for yesterday, it will append yesterday’s date to that file:
Log4NetSampleApp-Log4netSample.vshost.exe_DimitriPC.log20100202
Also, for each day it will only keep the last 2MB of log data (the amount of data is defined in the <maximumFileSize>-tag. The value defined in <maxSizeRollBackups> says how many files will be kept per day. In this configuration it will only keep the last 10 files (of max 2MB each).
<layout>: This is where we define the layout of the messages that are written to the log-target. The type defines what log4net-class will interpret what we define in the <conversionPattern>-tag. Do note that every parameter starts with a % (percent sign).
- First we set a timestamp (to the milisecond) which will look something like this: 2010-02-04 07:40:37,624.
- After that comes the level of the logging event. When writing informational logs this will say INFO, when writing errors it will say ERROR. When we look at the code, we will see how to specify the level of the logging event.
The –[number] defines how many characters can be used to specify this information. Here the level can be 5 characters maximum.
- Now we set the logger which is the type of class that actually logs the event. In this case: Log4netSample.Program
- As final piece of information we set the message that we set in the code appended by a newline.
For an informational logging event, it gives something like this:
2010-02-04 07:40:37,624 INFO Log4netSample.Program: test
For an error logging event (meaning that an exception was thrown in the code):
2010-02-04 07:41:11,995 ERROR Log4netSample.Program: Problem: System.Exception: something happened
at Log4netSample.Program.Main(String[] args) in D:\projects\MyProjects\Log4netSample\Log4netSample\Program.cs:line 20
Here the stacktrace of the exception is also written to the log file.
For a complete overview of all the settings you can use to create your own layout, I refer to the PatternLayout documentation page.
The ConsoleAppender
<treshold>: This setting can be used to define what logging level you want for this appender. In this case, only the errors will be written to the console window.
Some of the predefined levels recognized by the system are: Off, Fatal, Error, Warn, Info, Debug, All.
The configuration is practically the same for the consoleAppender. The only thing different is the layout of the log message. In the console we will also see the thread number and the NDC-property which is the Nested Diagnostic Context associated with the thread (if any, else it will be null).
Now that the configuration is done, we can use log4net in our code. In my class I’ve defined a variable to hold the logger.
private static ILog log = LogManager.GetLogger(typeof(Program));
To make it easier, you can look up the type-parameter used by the GetLogger() method using reflection:
private static ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
In my Main method, I will let log4net know it needs to read the App.config to load my configuration:
log4net.Config.XmlConfigurator.Configure();
And now for some code that will use log4net:
try
{
Console.WriteLine("program started");
throw new Exception("something happened");
}
catch (Exception ex)
{
log.Info("test");
log.Error("Problem: ", ex);
//so we can check the output to the console
Console.Read();
}