Click here to Skip to main content
Click here to Skip to main content

Using SharePoint and log4net in Harmony

By , 18 Nov 2009
 

Introduction

With traditional .NET applications, configuring log4net is relatively straightforward by simply changing the web.config and using xcopy deployment. In SharePoint, however, things become a little more complicated, and getting log4net working effectively takes a little more effort.

Firstly, it's not recommended that you modify the web.config manually or use xcopy deployments when working with SharePoint. This breaks the whole SharePoint model, and is likely to cause issues later on (for instance, when joining a new FTE server to the farm or extending an application). I'm a firm believer in repeatable builds and deploying everything via solutions and features, so this is not an option.

Secondly, not all code executes within the web application context. Take feature receivers and jobs, for example; depending on how they are invoked, these could run within the stsadm process or within OWSTimer. Setting up your log4net settings in the web.config can therefore be somewhat futile for debugging these components.

Solution

The solution I recommend is to deploy log4net into the GAC, and log4net.config to the 12 hive (using WSPBuilder). It's then possible to pass the location of the config file to log4net on initialize by simply adding the following line to your AssemblyInfo.cs file.

[assembly: log4net.Config.XmlConfigurator(ConfigFile = 
  @"C:\Program Files\Common Files\Microsoft Shared\" + 
  @"Web Server Extensions\12\CONFIG\log4net.config", Watch = true)]

Note that although this requires hard-coding the location of your previously deployed config file, I feel that it's acceptable as the path never changes between SharePoint installations. I would deploy the log4net assembly and config within a globally scoped solution rather than packaging with your main application codebase. The reasons for this are discussed briefly in a previous article here, and will reduce risk with managing shared resources in the farm.

Often, you may wish to have different log4net configurations per environment. If this is the case, I recommend using a different technique for configuring the location of the log4net config file within your codebase. This allows you to inject some additional application logic to determine the location of your config file.

public static void InitializeLog4Net(string environment)
{ 
   string configFile = string.Concat("log4net.",environment,".config");
   FileInfo configFileInfo = new FileInfo(@"C:\Program Files\Common Files\" + 
     @"Microsoft Shared\Web Server Extensions\12\CONFIG\log4net\"+ configFile);
   log4net.Config.XmlConfigurator.ConfigureAndWatch(configFileInfo);
}

Summary

The beauty of this solution is that log4net settings may be managed across the entire farm centrally. It also doesn't matter how your code is executed or what process it's running in, all log messages will be processed according to your settings. Use filters to customize log messages for different applications from the one config file.

For debugging feature receivers and jobs, I highly recommend configuring the log4net OutputDebugStringAppender and using the Sysinternals DebugView. This allows you to see your debug code in real-time, and can easily be switched on in various environments without the need for a debug build.

History

  • 18th November, 2009: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

TheCodeKing
Architect
United Kingdom United Kingdom
Member
Mike Carlisle - Technical Architect with over 10 years experience in a wide range of technologies.
 
@TheCodeKing

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionFile lockmemberThomas Stoller9 Sep '10 - 0:08 
This seems not to work in my environment.
 
Once used the OWSTimer process does not release the logfile configured in my log4net.config in 12\CONFIG so none of the w3wp processes can access the log file to write.
 
Is there any special configuration I can make this possible? I can't write a file for every running process.
AnswerRe: File lockmemberTheCodeKing9 Sep '10 - 12:11 
Hi Thomas, are you saying you have multiple applications on a single server all writing to the log? I think that's always going to be an issue and not necessarily specific to this particular deployment strategy. What is your set up exactly?

GeneralUse built-in method to get 12 hive path.memberJānis Veinbergs27 Aug '10 - 4:38 
Just a minor enchancment.
 
I would recommend using SPUtility.GetGenericSetupPath(@"CONFIG\log4net.config") to get SharePoint path. In this case it won't matter if SharePoint is on C drive or not.
GeneralRe: Use built-in method to get 12 hive path.memberTheCodeKing27 Aug '10 - 14:18 
Thanks, good suggestion!

GeneralAssemblyInfo.csmemberMember 440544719 Nov '09 - 3:47 
Hi,
 
I am new sharepoint development. Where is the location of the assemblyinfo.cs for SharePoint? And the same config file would work for webapplication, features, jobs?
 
Thanks for your help.
GeneralRe: AssemblyInfo.csmemberTheCodeKing19 Nov '09 - 5:47 
The AssemblyInfo.cs in not part of SharePoint. It's a file auto-generated by Visual Studio when setting up your project, and is used to compile meta-data into your assemblies such as version number. It's normally located within a properties folder within the project.
 
Yes using the technique described above would allow you to use the same config for webapplication, features, and jobs provided each deployed assembly explicitly loads the net4net config file as show in the examples. This also means you don't need to worry about deploying changes to the web.config file for the purpose of deploying logging settings.
 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130523.1 | Last Updated 18 Nov 2009
Article Copyright 2009 by TheCodeKing
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid