What is log4net
Log4net is an open source library that allows .NET applications to log output to a variety of sources (e.g., The console, SMTP or files). Log4net is a port of the popular log4J library used in Java. Full details of log4net can be found at its project homepage.
In this article, I will give an overview of how the library works and examples of a few of the different logging options.
Downloading the library
The log4net library can be downloaded from the project homepage. The latest distribution comes with versions of log4net for MONO, .NET 1.0 and 1.1, and .NET Compact Framework.
What does log4net provide?
Log4net provides a simple mechanism for logging information to a variety of sources. Information is logged via one or more loggers. These loggers provide 5 levels of logging:
- Debug
- Information
- Warnings
- Error
- Fatal
Hopefully (!!) the amount of logging performed by each level will decrease going down this list (we want more debug information than fatal errors!). The level of logging on a particular logger can be specified, hence during development, all 5 levels of logging can be output to aid development. When your application is deployed, you may decide to only output level 5 � Fatal errors to your log files. It's up to you and it's all easily configurable.
So, where does the logging information go? Well, logging information goes to what is called an Appender. An appender is basically a destination that the logging information will go to. In this article, I will give examples of the ConsoleAppender and the FileAppender. Many other appenders exist to allow data to be logged to databases, email, net broadcasts etc. You are not limited to only using one appender, you can have as many appenders configured for use as you want. Appender configuration is performed outside of code in XML files, so as we shall see later, it is a simple matter to change your logging configuration.
OK, so we know that we can use a logger to output data to a number of appenders, but what format will the information be logged as? Well, log4net has a number of layouts that can be used for each appender. These layouts specify whether the logs are produced as simple textual data or as XML files, or whether they have timestamps on them etc.
Let's get logging
OK, I'm sure you've read enough about logging now, and want to see some code and see how it all works. Well, here goes. Our first (incredibly simple) example program (LogTest.exe) is shown below:
using log4net;
using log4net.Config;
public class LogTest
{
private static readonly ILog logger =
LogManager.GetLogger(typeof(LogTest));
static void Main(string[] args)
{
BasicConfigurator.Configure();
logger.Debug("Here is a debug log.");
logger.Info("... and an Info log.");
logger.Warn("... and a warning.");
logger.Error("... and an error.");
logger.Fatal("... and a fatal error.");
}
}
You can see that there are a few interesting lines within this small application. The first of these is where we create a Logger.
private static readonly ILog logger =
LogManager.GetLogger(typeof(LogTest));
This creates a logger for the class LogTest
. You don't have to use a different logger for each class you have, you can use different loggers for different sections or packages within your code. The class of the logger is output to the log so you know where any logged information has come from.
The next interesting line is:
BasicConfigurator.Configure();
This method initializes the log4net system to use a simple Console appender. Using this allows us to quickly see how log4net works without having to set up different appenders. Don't worry however, setting up appenders isn't difficult and we'll look at that in a minute.
Finally, if you run the application, you can see the different levels of logging output that are performed - in this case, to the console:
0 [2436] DEBUG LogTest - Here is a debug log.
31 [2436] INFO LogTest - ... and an Info log.
31 [2436] WARN LogTest - ... and a warning.
31 [2436] ERROR LogTest - ... and an error.
31 [2436] FATAL LogTest - ... and a fatal error.
Specifying the Appender
Let's now change the test application so that it loads the log4net configuration information from a �.config� file. This is done by removing the BasicConfigurator
and using a DOMConfigurator
as is shown in the sample application LogTest2.
using log4net;
using log4net.Config;
public class LogTest2
{
private static readonly ILog logger =
LogManager.GetLogger(typeof(LogTest2));
static LogTest2()
{
DOMConfigurator.Configure();
}
static void Main(string[] args)
{
logger.Debug("Here is a debug log.");
logger.Info("... and an Info log.");
logger.Warn("... and a warning.");
logger.Error("... and an error.");
logger.Fatal("... and a fatal error.");
}
}
Now that we are using a DOMConfigurator
, we need to specify our appenders and layouts. This is done in the application's .config file, �LogTest2.exe.config�.
="1.0" ="utf-8"
<configuration>
<configSections>
<section name="log4net"
type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<log4net>
<appender name="LogFileAppender" type="log4net.Appender.FileAppender">
<param name="File" value="LogTest2.txt" />
<param name="AppendToFile" value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="Header" value="[Header]\r\n" />
<param name="Footer" value="[Footer]\r\n" />
<param name="ConversionPattern" value="%d [%t] %-5p %c %m%n" />
</layout>
</appender>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
<layout type="log4net.Layout.PatternLayout">
<param name="Header" value="[Header]\r\n" />
<param name="Footer" value="[Footer]\r\n" />
<param name="ConversionPattern" value="%d [%t] %-5p %c %m%n" />
</layout>
</appender>
<root>
<level value="INFO" />
<appender-ref ref="LogFileAppender" />
<appender-ref ref="ConsoleAppender" />
</root>
</log4net>
</configuration>
Within this XML file, you can see that there are two appenders specified, LogFileAppender and ConsoleAppender. We also have a root appender. This specifies what appenders we are using and also what level of output we want to see in our logs � in this case, everything from INFO onwards (i.e., everything except DEBUG). The LogFileAppender specifies which file to use and whether to append onto the end of an existing file or not. Both appenders use a common layout that specifies what information is output to the logs. We can see that the date (%d), time (%t), logging level (%p), the name of the logger (%c) and the message (%m) are output.
If you now run application LogTest2, the following output is shown on the console:
2004-09-10 12:53:48,062 [1216] INFO LogTest2 - ... and an Info log.
2004-09-10 12:53:48,078 [1216] WARN LogTest2 - ... and a warning.
2004-09-10 12:53:48,078 [1216] ERROR LogTest2 - ... and an error.
2004-09-10 12:53:48,078 [1216] FATAL LogTest2 - ... and a fatal error.
If you have a look at the file �LogTest2.txt�, you will see that it contains the same information.
Well, that's a brief overview of what log4net can do, and we've only really scratched the surface here. Log4net provides many other features and I'd recommend grabbing hold of a copy to try them out.