I’ve been using the sample from the asp.net website to log unhandled exceptions using the IExceptionLogger interface.
using System; using System.Net.Http; using System.Web; using System.Web.Http.ExceptionHandling; namespace Elmah.Server.ExceptionHandling { public class ElmahExceptionLogger : ExceptionLogger { private const string HttpContextBaseKey = "MS_HttpContext"; public override void Log(ExceptionLoggerContext context) { // Retrieve the current HttpContext instance for this request. HttpContext httpContext = GetHttpContext(context.Request); if (httpContext == null) { return; } // Wrap the exception in an HttpUnhandledException so that ELMAH can capture the original error page. Exception exceptionToRaise = new HttpUnhandledException(message: null, innerException: context.Exception); // Send the exception to ELMAH (for logging, mailing, filtering, etc.). ErrorSignal signal = ErrorSignal.FromContext(httpContext); signal.Raise(exceptionToRaise, httpContext); } private static HttpContext GetHttpContext(HttpRequestMessage request) { HttpContextBase contextBase = GetHttpContextBase(request); if (contextBase == null) { return null; } return ToHttpContext(contextBase); } private static HttpContextBase GetHttpContextBase(HttpRequestMessage request) { if (request == null) { return null; } object value; if (!request.Properties.TryGetValue(HttpContextBaseKey, out value)) { return null; } return value as HttpContextBase; } private static HttpContext ToHttpContext(HttpContextBase contextBase) { return contextBase.ApplicationInstance.Context; } } }
I recently changed a WebAPI application to use OWIN and later found my logging stopped working. OWIN may not have been to blame but it sure looked guilty.
Debugging through, I noticed that the Properties collection of the ExceptionLoggerContext.Request didn’t contain the MS_HttpContext key. I noticed the Elmah ErrorSignal class had a static class FromCurrentContext as well as the method in use FromContext(HttpContext context) which takes in the MS_HttpContext.
internal class GlobalExceptionLogger : ExceptionLogger { private static readonly ILog Log4Net = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); public override void Log(ExceptionLoggerContext context) { Log4Net.Error(String.Format("Unhandled exception thrown in {0} for request {1}: {2}", context.Request.Method, context.Request.RequestUri, context.Exception)); } } public class ElmahExceptionLogger : ExceptionLogger { public override void Log(ExceptionLoggerContext context) { // Wrap the exception in an HttpUnhandledException so that ELMAH can capture the original error page. Exception exceptionToRaise = new HttpUnhandledException(message: null, innerException: context.Exception); // Send the exception to ELMAH (for logging, mailing, filtering, etc.). ErrorSignal signal = ErrorSignal.FromCurrentContext(); signal.Raise(exceptionToRaise); } }
The logging is now working.