Search code examples
umbracolog4net

How do I use the log4net aspnet-request conversion pattern for a correlation id


I would like a correlation id assigned to each error placed into the log file generated by log4net. I would like this, so that I can display it to the user in a customised error page, then our ops can match them up and know which error is which.

I set up a no ActionFilterAttribute:

public class RequestModificationForLoggingFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        HttpContext.Current.Request.Headers["correlationid"] = Guid.NewGuid().ToString();
    }
}

and changed the log4net.config to (notice the [%aspnet-request{correlationid}]):

  <conversionPattern value=" %utcdate [%aspnet-request{correlationid}] [P%property{processId}/D%property{appDomainId}/T%thread] %-5level %logger - %message%newline" />

but the log ends up saying [NOT AVAILABLE]:

2017-03-21 14:40:18,151 [NOT AVAILABLE] [P54916/D3/T83] WARN  - blahblahblah

Where am I going wrong?


Solution

  • I ended up creating a module:

    public class LoggingModule : IHttpModule
    {
        public void Dispose()
        {
        }
    
        public void Init(HttpApplication context)
        {
            context.BeginRequest += new EventHandler(OnBeginRequest);
        }
    
        public void OnBeginRequest(Object sender, EventArgs e)
        {
            // When the error event is called, we set a correlation id which gets used in the logging
            ThreadContext.Properties["correlationid"] = Guid.NewGuid().ToString();
        }
    }
    

    And then used this log4net syntax:

    %property{correlationid}
    

    Don't forget that if you want an id for anything that is traced from applicationstartup or something like this, you can put a check in your trace listener like:

    // If correlationid is not set, then this log was thrown from a place where a request was not made. ie. OnApplicationStarting
    if (ThreadContext.Properties["correlationid"] == null)
    {
        // We assign an id here to ensure the log does not show null for id
        ThreadContext.Properties["correlationid"] = Guid.NewGuid().ToString();
    }