LibrarySites.Banner

Add Requested URL (and Context User) to Error Messages in Sitecore ASP.NET CMS Logs

This blog post provides a solution that adds the requested URL to warning, error, and exception messages that appear in system log files generated by the Sitecore ASP.NET web Content Management System (CMS). I compiled this against a recent build of Sitecore 7.

When diagnosing issues that appear as warnings and errors in the Sitecore log, it can be useful to see the URL that may have triggered the problem. For issues with permissions, it could also be helpful to know the login of the user placing the request. You can implement a solution based on the following untested prototype that overrides the default log appender provided with Sitecore to, when possible, adds that information to these types of log messages.

namespace Sitecore.Sharedsource.log4net.Appender
{
  using System.Web;
 
  using SC = Sitecore;
 
  public class UrlLogFileAppender : global::log4net.Appender.SitecoreLogFileAppender
  {
    protected override void Append(global::log4net.spi.LoggingEvent loggingEvent)
    {
      // assume we don't care about the requested URL
      // for anything lower than warning
      if (loggingEvent.Level != global::log4net.spi.Level.WARN
        && loggingEvent.Level != global::log4net.spi.Level.ERROR
        && loggingEvent.Level != global::log4net.spi.Level.FATAL)
      {
        base.Append(loggingEvent);
        return;
      }
 
      string url;
 
      if (HttpContext.Current != null)
      {
        // includes the protocol and hostname, so try that first
        url = HttpContext.Current.Request.Url.AbsoluteUri;
      }
      else if (!string.IsNullOrEmpty(SC.Context.RawUrl))
      {
        // this does not, but is probably always empty
        // if HttpContext.Current is null
        url = SC.Context.RawUrl;
      }
      else
      {
        // if we can't determine the URL, don't change anything
        base.Append(loggingEvent);
        return;
      }
 
      global::log4net.spi.LoggingEventData data = loggingEvent.GetLoggingEventData();
      data.Message += " URL: " + url;
 
      if (SC.Context.User != null)
      {
        // context user might be relevant for diagnosing permission issues
        data.Message += " (" + SC.Context.User.Name + ')';
      }
 
      global::log4net.spi.LoggingEvent ev =
        new global::log4net.spi.LoggingEvent(data);
      base.Append(ev);
    }
  }
}

To compile this code, your Visual Studio project should reference the Sitecore.Logging.dll assembly in the /bin subdirectory of the document root of your Sitecore solution. I recommend that you set the Copy Local property of that reference to false.

Because the /configuration/log4net section is not within the /configuration/sitecore section of the Web.config file, you must update the /web.config file rather than using a Web.config include file. Specifically, update the type attribute of the /configuration/log4net/appender element named LogFileAppender to specify your class and assembly:

<appender name="LogFileAppender" type="Sitecore.Sharedsource.log4net.Appender.UrlLogFileAppender, Sitecore.Sharedsource">

If you implement a solution using this approach, please comment on this blog post, especially if it raises any new problems.

Resources