Thursday, August 11, 2011

IIS 7.5, ASP.NET and log4net FileAppender lock error

Logging is a big part of any application.  In a recent MVC3 web application, I was having trouble getting my log4net configuration to log successfully to a file.  At first I had no idea why nothing was logging.  The symptoms I saw were that the destination file was being created, but nothing was getting logged to it.

Step 1:  Turn on log4net internal debugging.
Visit the Log4net FAQ and look under the troubleshooting section.  There you will find a faq on turning on the log4net internal debugging feature.  Basically it uses the windows trace system and then logs those trace alerts to a file.

Step2: Inspect the debugging
After taking a look at the debugging output, I noticed the following error.

log4net:ERROR [RollingFileAppender] Unable to acquire lock on file xxxxx. Access to the path 'xxxxx' is denied.

At least now I had a place to look.

Solution
There are two things that I had to do to make this solution work.
1)  In a web environment, there could be multiple threads trying to write to the logging file at once (depending on how you have things setup).  By default, log4net tries to acquire an exclusive lock to the files it is trying to write to.  You can override this default behaviour by telling log4net to use minimalistic locking.  You can find out more information in the faq by looking for "How do I get multiple process to log to the same file".

In any event, the configuration you want to add to your fileappender is

<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />

2) Make sure the application pool you are trying to use has file permission access to write to that file.  In IIS 7.5, you can setup your application pools to use application pool identities, instead of networkservice or another named account.  You can find more information about this here.  Basically, an application pool identity is kind of a "virtual account".  In order to give access to the file, you have to give the user "IIS AppPool\<AppPoolName>" permission to write to that file.

Happy logging!