I just started using ELMAH and am a fan. My team supports a large number of web applications and I'm particularly excited that ELMAH lets us save exceptions from each application to the same MS SQL database table.
We also support a few console, DLL and desktop applications. Is it possible to use the ELMAH DLL to log exceptions in these apps to that same location?
We needed the ability to log from a console app and a windows service in addition to our ASP.NET site. I used the answer (ErrorLog.GetDefault(null);
) which worked well until I needed to email too.
So, here is my solution. It handles the log, email, tweet and filtering (both in the config file and in code). I have also wrapped the main call as an extension to Exception so it can be called like: catch(Exception ex) { ex.LogToElmah(); }
To filter in code, hook the corresponding .Filtering event: ElmahExtension.ErrorLog.Filtering += new ExceptionFilterEventHandler(ErrorLog_Filtering);
Code:
using System;
using System.Web;
using Elmah;
namespace System
{
public static class ElmahExtension
{
public static void LogToElmah(this Exception ex)
{
if (HttpContext.Current != null)
{
ErrorSignal.FromCurrentContext().Raise(ex);
}
else
{
if (httpApplication == null) InitNoContext();
ErrorSignal.Get(httpApplication).Raise(ex);
}
}
private static HttpApplication httpApplication = null;
private static ErrorFilterConsole errorFilter = new ErrorFilterConsole();
public static ErrorMailModule ErrorEmail = new ErrorMailModule();
public static ErrorLogModule ErrorLog = new ErrorLogModule();
public static ErrorTweetModule ErrorTweet = new ErrorTweetModule();
private static void InitNoContext()
{
httpApplication = new HttpApplication();
errorFilter.Init(httpApplication);
(ErrorEmail as IHttpModule).Init(httpApplication);
errorFilter.HookFiltering(ErrorEmail);
(ErrorLog as IHttpModule).Init(httpApplication);
errorFilter.HookFiltering(ErrorLog);
(ErrorTweet as IHttpModule).Init(httpApplication);
errorFilter.HookFiltering(ErrorTweet);
}
private class ErrorFilterConsole : ErrorFilterModule
{
public void HookFiltering(IExceptionFiltering module)
{
module.Filtering += new ExceptionFilterEventHandler(base.OnErrorModuleFiltering);
}
}
}
}
In addition, you will need to add a reference to the System.Web.dll
in your project for this to work.
EDIT: As per the comments, this code will send emails only if your config file has <errorMail async="false"/>
. Refer to this code snippet should you want to keep <errorMail async="true"/>
in your config file (to be used when HttpContext.Current is available).