Skip to main content

Using Log4Net in 4 Simple Steps

First off, yes, this is a complete rip-off from this blog post, but with value added in that this represents my personal preference when using log4net. This is a simple four step process of adding logging to an application. I prefer log4net over the MS logging application block, primarily as log4net has zero dependencies and NHibernate already references it. IMHO, if you're doing ANY kind of logging, reference log4net into your project and use it instead of Trace.WriteLine() or Debug.WriteLine().

Step 1. Add the following in the AssemblyInfo.cs

[assembly: log4net.Config.XmlConfiguratorAttribute(
ConfigFile = "log4net.xml", Watch = true)]
Step 2. Create the log4net.xml file and add the following to the new file

With respect to the location of this file and SharePoint, this file can exist in the root of the wss root, next to the relevant web.config file for the given site. In general, this should sit next to the app.config or web.config file for the given application.

<appender name="GeneralLog" type="log4net.Appender.RollingFileAppender">
<file value="${TEMP}\\Logs\\AppName_${COMPUTERNAME} " />
<appendToFile value="true" />
<rollingStyle value="Composite" />
<staticLogFileName value="false" />
<datePattern value=".yyyyMMdd.'log'" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="5MB" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%d{HH:mm:ss.fff} [%t] %-5p %c - %m%n" />
<appender name="DebugAppender" type="log4net.Appender.DebugAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%d [%t] %-5level %logger - %message%newline" />
<level value="ALL" />
<appender-ref ref="GeneralLog" />
<appender-ref ref="DebugAppender" />
<!-- Print only messages of level ERROR or above in the package NHibernate -->
<logger name="NHibernate" additivity="true">
<level value="ERROR" />

Step 3. Add the following at the top of your class
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(

Step 4. Add the following line in the code where you want logging to be done

log.Info("Program Started " + DateTime.Now.ToString ());

Apache log4net Home Page -


Anonymous said…
Simple! Clear! Working! This is what I am looking for. Good job!
Anonymous said…
step 4 is better implemented as
if (log.IsInfoEnabled) log.Info("Program Started " + DateTime.Now.ToString ());
to reduce the impact of the string formatting where the log isn't enabled
mnrp said…
Re last comment: If you want to make your (not) logging code as fast as possible, see "What is REALLY the FASTEST way of (not) logging?" in the FAQ section of documentation. Anyway, thanks for the post BigJim.
BigJimInDC said…
Just as a quick follow-up to this, if you're like me, and prefer to use a separate log4net configuration file, rather than storing the configuration info inside the app.config or web.config file, AND if you followed my example to a tee, you created a file named "log4net.xml".

For the record, I would advise changing that to "log4net.config", especially if you are running this on a web server, as the typical IIS/ASP.NET configuration is to NOT serve up ".config" files. That will plug a potential security hole.
Paul Wheeler said…
If you put the configuration from Step2 into the web.config like I do, you need to put a call to XmlConfigurator.Configure() into your Global Application_Start method:
Anonymous said…
Doesn't work.

Popular posts from this blog

MS KB928365, ASP.NET Request.Headers.Add() Hack No Longer Works

So a project that I am currently a part of is using an ASP.NET 2.0 HttpModule to add some additional values to the incoming HTTP request's headers in the DEV environment (i.e., our local disconnected laptops) to simulate what an enterprise single-sign-on solution is performing in the production environment. It has worked like a charm. That is until I installed the new security update for the .NET Framework 2.0 release this past Wednesday, July 10, MS KB928365.

Apparently this "hack"has been disabled with the release of this security update.

When attempting to call Headers.Add(), with or without the above hack in place, you will now receive a PlatformNotSupported exception.

All in all, this post is by no means a rant against the security update, but simply an attempt to add a quick answer to the "Google answer machine" for those searching. I am also already aware of a number of other potentially better solutions than the one currently in place for simulating th…

Temporal Database Design, Soft Deletes, and Ayende's Razor

This is a formal follow-up to a post on Ayende's blog on "Avoiding Soft Delete's" in your database where I question the lack of temporal database solutions being applied to these types of problems.

After Oren claimed the following, I felt it necessary to expand on it in a blog post of my own, rather than continuing to clutter his comments, and hopefully finally bring some traffic to my own blog :-)
Ayende’s RazorThis is a response to a comment on another post:Oren, in all seriousness, I thought that problems that were "(a) complex, (b) hard to understand (c) hard to optimize" were the kinds that folks like you and I get paid to solve...Given two solutions the match the requirements of the problem, the simpler one is the better.I could just as well call that statement "Jim's Razor", as I believe in it as much as you do Oren, so no arguments there.

But in the same vane, "wise" (i.e., experienced) software architects/developers strategical…

The Application of Pareto's Principle to the Adoption of Agile Practices - Part 1 of N

Starting this evening, I will be attending the Agile Coach Camp in Durham, NC. As the only registration fee for attending the ACC is to submit a position paper on a topic of interest to you, I submitted the following abstract.
The Application of Pareto's Principle to the Adoption of Agile Practices
If you believe in Pareto's Principle (otherwise known as the 80-20 Rule), then you believe that it can be applied literally everywhere. At its heart, Agile practices are about doing what works and ignoring the rest (at least until the time is right). In a world where people are constantly searching for silver bullets, getting distracted by zealot turf wars, and feeling the crunch of deadlines, novice adopters of Agile practices need to learn what out of"agile" is immediately important for their situation, and what they can safely ignore until a latter point in time.So I figure why not put some more concrete thoughts together before the ACC starts. This post is the …