Lately in my projects I’ve been using log4net library which enables great way of logging messages and errors in many different ways and on different levels. I won’t describe exatcly how it works, but if You’re interested You can read about it here http://logging.apache.org/log4net/.

The problem which I had with it,  together with Microsoft SharePoinFoundation 2010, was the permission issue. I created an EventLogAppender which should write all the messages from the code to the Event Viewer. And yes, it worked, but only, when PC Local Adminsitrator was logged into SharePoint. When a “normal” user logged into SharePoint then log4net didn’t work – it didn’t write any messages to Event Viewer. Luckily, I’ve found a very simple solution. You can make log4net to work in the process user context – in SharePoint terms it equals Application Pool identity. To achieve this You have to add below lines to the log4net configuration of EventLogAppender:

<securitycontext type="log4net.Util.WindowsSecurityContext">
        <credentials value="Process">
        </credentials>
      </securitycontext>

The full configuration xml can look like this:


<configuration>
  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
  </configSections>
  <log4net>
    <appender name="EventLogAppender" type="log4net.Appender.EventLogAppender" >
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date %-5level %logger - %message - %location%newline" />
      </layout>
      <securitycontext type="log4net.Util.WindowsSecurityContext">
        <credentials value="Process">
        </credentials>
      </securitycontext>

      <applicationName value="MyCustomSource" />
    </appender>

    <root>
      <level value="WARN" />
      <appender-ref ref="EventLogAppender" />
    </root>
  </log4net>
</configuration>

From the code behind side I often use below template when working with log4net:


public class LogHelper
    {
        private static ILog logger;

        public static ILog Logger
        {
            get
            {
                if (logger == null)
                {
                    string baseAddress = SPContext.Current.Web.Url.TrimEnd('/');
                    log4net.Config.XmlConfigurator.Configure(new Uri(baseAddress + "/_layouts/CustomSolutionFolder/log4net.xml"));
                    logger = LogManager.GetLogger(typeof(LogHelper));
                }

                return logger;
            }
        }
    }

So I can use it in my code:


LogHelper.Logger.Error("ERROR!");