Log4Net And External Configuration File In ASP.NET 2.0

0 comments suggest edit

Recently I wrote that I could not seem to get Log4Net to work with an external configuration file while running ASP.NET 2.0 in Medium Trust. It turns out that I should have been more explicit. I could not get Subtext to work with Log4Net in Medium Trust, but it had nothing to do with Medium Trust. Mea culpa!

My best guess is that there was a small breaking code change in Log4Net that led to this issue since we hadn’t changed the logging code. Here is a breakdown of what happened just in case you run into this problem.

In Subtext, we wrap the Log4Net classes in our own Log class which is in the Subtext.Framework assembly. This is how we declare a logger within a class.

private readonly static ILog log 
    = new Subtext.Framework.Logging.Log();

In the Subtext.Web project, we have the following attribute in AssemblyInfo.cs which specifies the location of the log4net configuration file.

[assembly: log4net.Config.XmlConfigurator(ConfigFile 
    = "Log4Net.config", Watch = true)]

This worked fine and dandy up until ASP.NET 2.0. When you use the attribute approach, you have to make a log4net call early to jump start the engine so to speak. An attribute just sits there until somebody is told to look at it and do something about it. In our case, the line of code I showed above does the trick within Global.asax.cs.

I started digging into the Log4Net code to figure out how it uses the attribute to find the configuration file. I finally ended up at this code.

public static ILog GetLogger(Type type) 
{
    return GetLogger(Assembly.GetCallingAssembly(), 
        type.FullName);
}

GetLogger searches the attributes on the calling assembly to find out which configuration file to use. Since the calling assembly in our case is always Subtext.Framework (since we wrap all calls to Log4Net), Log4Net searches the Subtext.Framework assembly for the XmlConfiguratorAttribute. Well that won’t work because we have the attribute declared on the Subtext.Web assembly.

My initial fix was to move the attribute declaration to AssemblyInfo.cs within Subtext.Framework. That worked, but I felt like the proper place was to have it within the web project, since that is the natural place to look when you are trying to figure out where the config file is specified. So I updated the code to call log4net directly within Global.asax.cs like so.

//This call is to kickstart log4net.
//log4net Configuration Attribute is in AssemblyInfo
private readonly static ILog log 
    = LogManager.GetLogger(typeof(Global));

static Global()
{
    //Wrap the logger with our own.
    log = new Subtext.Framework.Logging.Log(log);
}

I only point this out to show there are two ways to solve it, both with their plusses and minuses. If you run into this problem, hopefully this guide will help you.

Found a typo or error? Suggest an edit! If accepted, your contribution is listed automatically here.

Comments

avatar

4 responses

  1. Avatar for Rod Dot net
    Rod Dot net November 3rd, 2006

    There is an log4net configuration example at www.dotnetspace.com

  2. Avatar for VisionX
    VisionX August 18th, 2008

    Does anybody know if log4net works with framework 3.5?

  3. Avatar for Syed Jazbi
    Syed Jazbi September 25th, 2008

    I am not able to log in XML file. The following message displayed when I open the XML file:
    Cannot view XML input using XSL style sheet. Please correct the error and then click the Refresh button, or try again later.
    --------------------------------------------------------------------------------
    The operation completed successfully. Error processing resource 'file:///C:/AppLog3.xml'. Line 1, Position 363
    Following is the code in my App.Config file:

    <configuration>
    <configsections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
    </configsections>
    <log4net debug="false">
    <appender name="XmlFile" type="log4net.Appender.FileAppender">
    <file value="C:\AppLog3.xml"/>
    <appendtofile value="true"/>
    <layout type="log4net.Layout.XmlLayout">
    <param name="Prefix" value="log4net"/>
    </layout>
    </appender>
    <root>
    <level value="WARN"/>
    <appender-ref ref="XmlFile"/>
    </root>
    </log4net>
    </configuration>

    I don't know what I am doing wrong, I would really appreciate it if you can help me to resolve this issue.
    Thanks.

  4. Avatar for Uma
    Uma June 13th, 2010

    Hi Phil,
    Could plz guide me to configure ASP.NET MVC with Log4PostSharp. I have followed the steps to configure postsharp 1.5 and have reference to Postsharp.public; postsharp.aspnet;log4postsharp included to my application.
    Regards,
    Uma