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?
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();
}