Saturday, March 21, 2009

Error logging in ASP.NET using a HTTP module

I wrote many moons ago about logging errors from an ASP.NET website but even then I knew there was a better way of doing it. The problem with that implementation was that it assumed the ASP.NET application was under my control. What happens if you want to add error logging to somebody’s else application for which you don’t have the source? Or what about an application you’ve written yourself that you’re selling to other people but also using internally, and you don’t want to prescribe to your customers how they should implement their logging? What is required is a more flexible approach to logging, something that can be plugged into any ASP.NET application.

Fortunately ASP.NET provides such a mechanism, via HTTP modules. Another reason I’d never looked at implementing logging this way was that I thought it might be tricky to do, but in fact it is so simple it took me all of an hour to produce a working solution.

The first thing to do is create a new class library and add a class that implements the IHttpModule interface. This interface has only two methods, Init and Dispose. Here's how I implemented it.

  public class ErrorLogger : IHttpModule
  {
    public void Init(HttpApplication context)
    {
      context.Error += new EventHandler(context_Error);
    }

    public void Dispose()
    {
    }

    private void context_Error(object sender, EventArgs e)
    {
      Exception ex = HttpContext.Current.Server.GetLastError();
      // log the exception however you like
    }
  }

Pretty simple. The logging code isn’t shown for brevity’s sake but all the class does is hook up an event handler for the Error event and within that event handler do whatever is necessary to log the error. In our case, we email the error and put it in a database table, but you can log it however you wish. (here’s some exception logging code for you)

Now all that’s required is to drop the assembly in the app’s bin directory and tell the ASP.NET application about the HTTP module. This is done via the web.config file with the following in the <system.web> section

  <httpModules>
    <add type="Utilities.ErrorLogger" name="ErrorLoggingModule"/>
  </httpModules>

type is the .NET type and name is whatever you like. And, er, that’s it.

As you’ve probably realised HTTP modules are powerful little things that can be used to do all kinds of stuff in a flexible manner.

Update – for those not reading the comments, there’s a free logging tool called ELMAH that can do all this for you without needing to write any code.

2 comments:

Anonymous said...

Thanks for the post but ELMAH does the same thing. Anybody can use this without writing a single line of code.

Doogal said...

My Google skills let me down again. ELMAH looks pretty good, here's a link for anybody who's interested.

http://code.google.com/p/elmah/