Thursday, October 9, 2014

Logging for .Net: ELMAH

Intro

For those of you who work with me or know about the place where I work, we take logging seriously. It's almost a combination of science, art, and religion. We log all kinds of things, some might even say we log too much data. When you log this much data, there are 3 key things you have to do to stay sane: 1) Make the logging of the data easier. 2) Make managing that much data easier. 3) Make it easy to turn the data into useful information.

I won't speak about items 2 and 3, at least not right now. This blog post is all about a library for making it easier to log data in .Net. This library is called ELMAH, or Error Logging Modules and Handlers. It allows you to automatically log unhandled exceptions (this is extremely important for any web site/service), manually log exceptions, and creates a web page for you to view the exceptions that it has logged. All this for free and with a minimal amount of work compared to what it would take to create this functionality yourself!



Example - Logging Unhandled Exceptions


Start by firing up Visual Studio 2013 and create a new ASP.Net Web Application. I've named mine BlogElmah but name yours whatever you like.


Choose "Web Forms" and change the authentication scheme to "No Authentication".


After a little bit of a wait (decently long wait for me, my computer is slow) you'll have a brand new Asp.Net webforms project. Now let's add some ELMAH to it! You'll be happy to know that ELMAH is a NuGet package which makes it easier to plug into your projects. Right-click on the new solution in the Solution Explorer window in Visual Studio and select "Manage NuGet Packages for Solution...".


Locate and install the package named ELMAH.


Your setup is complete. ELMAH by default logs errors to memory which isn't necessarily a good long-term choice, but it'll do for our testing purposes. Just keep in mind that you'll want to move this into a database at some point, or failing that at least some XML files for basic persistence. Anyways, onwards...

Let's throw an exception in code so you can see what the ELMAH do. Open up your default.aspx and toss in a button. Here's mine:

 Now give it an OnClick event that throws an exception, like this:

using System;
using System.Web.UI;

namespace BlogElmah1
{
    public partial class _Default : Page
    {
        protected void ExceptionButton_Click(object sender, EventArgs e)
        {
            throw new Exception("hey, an exception!");
        }
    }
}


Causing an error is probably the easiest part of the process! Run the site and click your brand new button there on the default page. You should end up with an unhandled exception page like this:

Ahh, the dreaded Yellow Page of Death. But hey, that's what we wanted right?

Example - Viewing the Log

Now that we've thrown an exception, let's view the log. This part is super-simple. You still have your browser open from the last step right? Change the destination url to http://localhost:[port]/elmah.axd, where [port] is the port your development server is running on. You're now looking at the elmah exception log which should look like this:




Play around with the links in there, this log is pretty nice. Specifically try out the Details link...yay stack trace! This handling and log make troubleshooting a site much easier with very little work involved.

Example - Manually Logging Exceptions

OK that's all fine and dandy, but you might now say "Hey, we're professionals right? We handle our exceptions already so that we can display a nice message to the user, or decide which programmer needs a flogging, or whatever. We just want to add the ability to log the exceptions we're already handling!". Well ELMAH won't disappoint. Let's see how to do that with a little bit of code...open back up your Default.aspx.cs file and modify the button click event slightly as per the following:

using Elmah;
using System;
using System.Web.UI;

namespace BlogElmah1
{
    public partial class _Default : Page
    {
        protected void ExceptionButton_Click(object sender, EventArgs e)
        {
            try
            {
                throw new Exception("hey, an exception!");
            }
            catch (Exception ex)
            {
                //...do some stuff that's business related...
                //log exception
                ErrorSignal.FromCurrentContext().Raise(ex);
            }
        }
    }
}


First, add a using statement for Elmah. You need to use stuff from that namespace. The next key part is down in the catch statement, ErrorSignal.FromCurrentContext().Raise(ex). This tells ELMAH to log the exception ex. Run the project and click the exception throwing button again. You'll notice no YPOD this time around since we're handling the exception. Point your browser at the local project elmah.axd again and you'll still see your newly thrown exception in the log. Huzza!


What's Next?

Well, them's the key points of ELMAH. There is still a whole lot more you can do though and I encourage you to explore. Here is some of what you can do to enhance your ELMAH experience:
  • Log exceptions to sql or some other backend store
  • Setup an RSS feed of exceptions
  • Get email notifications of exceptions
  • Play with user rights and the exception log viewer web page
  • Allow viewing of exceptions remotely
  • Filter out exceptions you don't want to log
  • Browse the ELMAH website (link below)

Resources

elmah home page

No comments:

Post a Comment