SharePoint – Configuring log4net in a SharePoint Application

Cross-posted from my Clarity blog

Configuring log4net in a SharePoint or ASP.NET application is pretty straightforward, but no matter how many times I do it, I always forget something small and waste time troubleshooting why logging isn’t working.

Here’s a guide to configuring logging using log4net in a SharePoint application. This post will cover:

  • Creating and deploying a log4net configuration file
  • Making the necessary web.config changes to support logging
log4net deployment is documented extensively so I’ll keep this at a high level.

Creating and Deploying a log4net Configuration File

It’s always best to put your log4net configuration in a dedicated config file, this way you get to keep your SharePoint web.config file clean and not have to deal with the SPWebConfigModification class.

The part I always forget is that when you have the log4net configuration in a separate file, you need to tell your assembly the name of the log4net configuration file. You do that by adding the following attribute to the AssemblyInfo class of the SharePoint project or class library where you have your logger.

According to the documentation from Apache, this attribute is read and processed after the first time you invoke log4net. Your logger will call LogManager.GetLogger and look for this attribute and then read the configuration information.

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

You can examine properties of the logger such as isDebugEnabled and isErrorEnabled to check if everything is working properly.

You can then use a SharePoint Timer job to deploy the log4net.config file to the root of your SharePoint web application.

In a Web Application scoped feature, you can run a SharePoint Timer job in the FeactureActivated handler:

var log4NetDeployJob = new log4NetConfigDeploymentJob(
    _jobName, webApplication);
var schedule = new SPOneTimeSchedule(DateTime.Now);
log4NetDeployJob.Schedule = schedule;
log4NetDeployJob.Update();
webApplication.JobDefinitions.Add(log4NetDeployJob);
webApplication.Update();
log4NetDeployJob.RunNow();

The Execute method of the Timer Job extracts the log4net.config file from where it was deployed with your feature and copies it to the virtual directory:

public override void Execute(Guid targetInstanceId)
{
    var webApp = this.Parent as SPWebApplication;
    foreach (KeyValuePair<SPUrlZone, SPIisSettings> setting in webApp.IisSettings)
    {
        var deployTo = setting.Value.Path.FullName + @"\log4Net.config";
        var filePath = SPUtility.GetGenericSetupPath(
            @"TEMPLATE\FEATURES\log4Net\Configuration\log4Net.config");
        File.Copy(filePath, deployTo, true);
    }

    base.Execute(targetInstanceId);
}

SPUtility.GetGenericSetupPath returns the full path to the 14 hive, and “TEMPLATE\FEATURES\log4Net\Configuration\log4Net.config” is the path to the log4Net.config file inside the feature.

Web.config Modifications

You now need to make some changes to the web application’s web.config file.

Add log4Net configuration section in configuration/configSections:

<section name="log4net"
  type="log4net.Config.Log4NetConfigurationSectionHandler, Log4net"/>

Add the following before the end of the configuration section:

<log4net configSource="log4Net.config" />

That’s it! Assuming you created a logger class in your application, you can start logging away. Check out the documentation from Apache for information about how to write a logger.

Leave a Reply

Your email address will not be published. Required fields are marked *