I found this extremely useful post by Mitch on Log4Net, .Net Logging Tool. A must read post for someone trying to use log4net in their projects. Since this blog acts as my repository of my learnings. I am reproducing a significant amount of content from Mitch's post here. I would recommend you go there for details.
The main part I am reproducing here deals with configuring log4net configuration in a separate file from app.config or web.config.
Add the log4net assembly to your project
It’s good practice to include third party assemblies under source control as part of a project. That way, performing a get latest on a new PC includes everything.
If your project does not already contain a source-controlled external libs folder for third party assemblies:
- Right click on project
- Select “Add -> New Folder”, call it “ThirdPartyDlls” or “libs” or whatever your in-house standards specify.
OK, now add log4net:
- Right click on your external libs folder, select “Add Existing Item…” and browse to where you unzipped log4net and choose the release version of log4net.dll (\bin\net\2.0\release\log4net.dll)
- Right click on References, select “Add Reference …” and browse to your libs folder and pick the log4net.dll you just added.
Configure log4net: Creating and Specifying the Log4Net Config File
Although it is possible to add your log4net configuration settings to your project’s
app.config or
web.config file, it is preferable to place them in a separate configuration file. Aside from the obvious benefit of maintainability, it has the added benefit that log4net can place a
FileSystemWatcher object on your config file to monitor when it changes and update its settings dynamically.
To use a separate config file, add a file named
Log4Net.config to your project and add the following attribute to your
AssemblyInfo.cs file:
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "Log4Net.config", Watch = true)]
Note: for web applications, this assumes Log4Net.config resides in the web root. Ensure the log4net.config file is marked as “Copy To Output” -> “Copy Always” in Properties.
Here is an sample log4net config file with several appenders defined:
xml version="1.0" encoding="utf-8" ?>
<log4net>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="..\\Logs\\CurrentLog" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="10000" />
<staticLogFileName value="true" />
<filter type="log4net.Filter.LevelRangeFilter">
<acceptOnMatch value="true" />
<levelMin value="INFO" />
<levelMax value="FATAL" />
filter>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5level %date [%thread] %-22.22c{1} - %m%n" />
layout>
appender>
<appender name="LogFileAppender" type="log4net.Appender.FileAppender">
<file value="log-file.txt" />
<appendToFile value="true" />
<layout type="log4net.Layout.PatternLayout">
<header value="[Your Header text here]" />
<footer value="[Your Footer text here]" />
<conversionPattern value="%date [%thread] %-5level %logger [%ndc]
<%property{auth}> - %message%newline" />
layout>
appender>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
layout>
appender>
<appender name="EventLogAppender" type="log4net.Appender.EventLogAppender" >
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger
[%property{NDC}] - %message%newline" />
layout>
appender>
<root>
<level value="DEBUG" />
<appender-ref ref="LogFileAppender" />
<appender-ref ref="ConsoleAppender" />
<appender-ref ref="RollingFileAppender" />
root>
<logger name="ConsoleApp.LoggingExample">
<level value="ERROR" />
<appender-ref ref="EventLogAppender" />
logger>
log4net>
In the “RollingFileAppender“ defined above, as Phil Haack points out: “Note that the file value (with backslashes escaped) points to ..\Logs\CurrentLog. [In Web Applications] this specifies that log4net will log to a file in a directory named Logs parallel to the webroot. You need to give the ASPNET user write permission to this directory, which is why it is generally a good idea to leave it out of the webroot. Not to mention the potential for an IIS misconfiguration that allows the average Joe to snoop through your logs.”
Using the Logger
At the start of each class declare a logger instance as follows:
public class ClassWithLoggingExample
{
private static readonly ILog log =
LogManager.GetLogger( System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
...
}
You will need to add a “
using log4net;" statement to each class file. By defining a logger in each class you have the ability to control the logging level on a class by class basis, simply by using the config file.
Once you have instantiated a logger, you can call its logging methods. Each method is named for the logging level. For example:
// In ascending order of severity (descending level of verbosity)
log.Debug("This is a DEBUG level message. The most VERBOSE level.");
log.Info("Extended information, with higher importance than the Debug call");
log.Warn("An unexpected but recoverable situation occurred");
log.Error("An unexpected error occurred, an exception was thrown, or is about to be thrown", ex);
log.Fatal("Meltdown!", ex);
Whether or not a message shows up in your logs depends on how you have configured your appenders and the logging level you have set. If you want to avoid the overhead of string construction and a call to a logging method, you can first test to see if the appropriate level is active:
// If you are concerned about performance, test the appropriate
// log level enabled property (one for each of the log level methods)
if (log.IsInfoEnabled)
log.Info("Performance sensitive Info message");
The format of the logged output can be adjusted in the config file. See the log4net documentation that came in the zipped download (\doc\release\sdk\log4net.Layout.PatternLayout.html).
For web applications, add the following line to the
Application_Error method in the
Global.asax.cs file:
protected void Application_Error(
object sender,
EventArgs e)
{
log.Fatal("An uncaught exception occurred", this.Server.GetLastError());
}
Read more!