25

I have seen at least two ways to include an external log4net config file in an ASP.NET web application:

Having the following attribute in your AssemblyInfo.cs file:

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

Calling the XmlConfigurator in the Global.asax.cs:

protected void Application_Start()
{
    XmlConfigurator.Configure(new FileInfo("Log.config"));
}

What would be the best practice to do it?

Martin Buberl
  • 45,844
  • 25
  • 100
  • 144

2 Answers2

46

At startup, call:

XmlConfigurator.Configure();

In your Web.config, specify log4net.Config in appSettings:

<add key="log4net.Config" value="Log.config" />

This special setting allows you to change the log configuration without having to recompile. Especially helpful for moving between multiple environments.

Example

Consider the following project file structure:

\config\log4net\debug.config
\config\log4net\staging.config
\config\log4net\release.config
\config\appSettings\debug.config
\config\appSettings\staging.config
\config\appSettings\release.config

Application and logging configurations are distinguished for each environment. References to the logging configurations are maintained in the application settings.

\config\appSettings\debug.config:

<appSettings>
    <add key="log4net.Config" value="config\log4net\debug.config" />
    ...
</appSettings>

\config\appSettings\staging.config:

<appSettings>
    <add key="log4net.Config" value="config\log4net\staging.config" />
    ...
</appSettings>

\config\appSettings\release.config:

<appSettings>
    <add key="log4net.Config" value="config\log4net\release.config" />
    ...
</appSettings>

Changing environments is a simple matter of updating the appSettings file in Web.config.

<appSettings file="config\appSettings\staging.config">
    ...
</appSettings>
Anton
  • 4,554
  • 2
  • 37
  • 60
  • That's a good point, but i really don't like this "magic" configuration thing. What I did now, is declare three keys with filenames in the appSettings of Web.config for Debug, Stage, Release and use preprocessor directives in ApplicationStart for choosing automatically the right one depending on which configuration the assemblies were deployed. What's your opinion? Is there anything wrong with that solution? – Martin Buberl Nov 13 '09 at 21:53
  • @Martin: I added an example to illustrate. The only downside to your solution is the inflexibility of build versions over web.config alterations. – Anton Nov 13 '09 at 22:35
  • 1
    Realize this is an old thread, but this still works great today. I did a slight change in that instead of placing the configure call in Global.asax, I used a bootstrap file and used WebActivator to initialize it. Works like a charm!! – Ed DeGagne May 07 '12 at 20:33
  • Does this mean I cannot use log4net's ability to automatically give me the class name in the logging output? See my related question here: http://stackoverflow.com/questions/11185726/how-to-use-log4net-in-asp-net-from-multiple-assemblies – Darren Jun 27 '12 at 05:23
  • 3
    You can also use [SlowCheetah config transforms](http://visualstudiogallery.msdn.microsoft.com/69023d00-a4f9-4a34-a6cd-7e854ba318b5) to manage different configurations without creating redundant settings in different files. – Mrchief Jul 05 '13 at 22:29
  • @Mrchief: Thanks for the link to SlowCheetah! Wasn't around when I posted this, but it sure looks cool. – Anton Jul 10 '13 at 17:16
4

I was dissatisfied with the "magic" configuration approach, because I wanted to specify my configuration in a path with an environment variable (%PUBLIC%\MyApp\MySettings.config).

So instead, I have this in my app.config:

<add key="MyLog4NetConfigFile" value="%PUBLIC%\MyApp\MySettings.config"/>

And do this to set my log4net configuration:

var configFile = ConfigurationManager.AppSettings.Get("MyLog4NetConfigFile");
if( !string.IsNullOrEmpty(configFile))
{
    configFile = Environment.ExpandEnvironmentVariables(configFile);
    XmlConfigurator.Configure(new FileInfo(configFile));
}
pduncan
  • 1,330
  • 2
  • 15
  • 26