What is ELMAH?
In case you have been living under a rock I will start this block post by giving you a basic introduction to ELMAH. If you already are familiar with ELMAH then just skip to the next section.
The following description was taken verbatim from the ELMAH website…
ELMAH (Error Logging Modules and Handlers) is an application-wide error logging facility that is completely pluggable. It can be dynamically added to a running ASP.NET web application, or even all ASP.NET web applications on a machine, without any need for re-compilation or re-deployment.
Once ELMAH has been dropped into a running web application and configured appropriately, you get the following facilities without changing a single line of your code:
- Logging of nearly all unhandled exceptions.
- A web page to remotely view the entire log of recoded exceptions.
- A web page to remotely view the full details of any one logged exception.
- In many cases, you can review the original yellow screen of death that ASP.NET generated for a given exception, even with customErrors mode turned off.
- An e-mail notification of each error at the time it occurs.
- An RSS feed of the last 15 errors from the log.
So the next time an end user gets the YSOD (Yellow Screen of Death) ….

You will be able to look at your ELMAH page or read an email to investigate the details! ELMAH FTW

ELMAH was created by Aziz Atif. It is great people like Aziz that make our day to day development tasks a breeze. I am sure all of us have written exception modules at one point or another. However, I am a firm believer of working smart and not hard. So why recreate the wheel when ELMAH does everything that you could possibly imagine in terms of exception handling.
Thanks Aziz! I am grateful for your contribution!
Configuration Steps
Update: Install ELMAH by using the Nuget Package and you can skip almost all of these steps. You can also use SQL Compact as your elmah repository and avoid having to create any stored procedures.
These configuration steps assume that you are interesting in logging to a MSSQL database and sending emails when an exception occurs. Although SQL and Email are probably the most common configuration there are a wide variety of options available. ELMAH also supports logging to Oracle, Access, SQLLite, VistaDB and XML. You can even send notifications to twitter if the mood strikes you!
- Download the appropriate binaries from http://code.google.com/p/elmah/. There are two versions available. An x64 version and an x86 version. Pick the one that is appropriate to your environment.
- In your ASP.NET MVC Web application create a new folder called “Lib”. Copy the files Elmah.dll, Elmah.pdb and Elmah.xml into the directory.
- Add a reference to the ELMAH assembly . Right click on the project --> Add Reference –> c:\Your Project Path\Lib\Elmah.dll.
- Add the following XML to configuration/configSections. The XML below declares the new section groups that we will be creating in the following step. For an application running in Medium trust the requirePermission attribute should be set to false.
<configSections>
<sectionGroup name="elmah">
<section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah"/>
<section name="errorLog" requirePermission="false" type="Elmah.ErrorLogSectionHandler, Elmah"/>
<section name="errorMail" requirePermission="false" type="Elmah.ErrorMailSectionHandler, Elmah"/>
<section name="errorFilter" requirePermission="false" type="Elmah.ErrorFilterSectionHandler, Elmah"/>
</sectionGroup>
</configSections>
- Directly below the configSections node add the following XML
<elmah>
<security allowRemoteAccess="0" />
<errorLog type="Elmah.SqlErrorLog, Elmah" connectionStringName="connectionString" />
<errorMail
from="noreply@somesite.com"
to="<someUnfortunateDeveloper>@somesite.com"
subject="<ApplicationName> Error"
async="true "
smtpPort="25"
smtpServer="smtpserver.somesite.com"
userName="smtpUser"
password="smtpPassword" />
</elmah>
This section gives the configuration details for Email and SQL Logging. The connectionStringName is generally the SQL Connection string that you are using to access your application data. However, you could use a central “Error Logging” database if desired. For most situations the connectionStringName will be equal to the name declared in the connectionStrings section of your web.config:
<connectionStrings>
<add name="connectionString" connectionString="Data Source=<instance name>;Initial Catalog=<database name>;Integrated Security=True" providerName="System.Data.SqlClient"/>
</connectionStrings>
- Under the system.web element add the following XML. The configures the HTTP Handler so when the URL http://<siteURL>/elmah.axd is viewed ELMAH will display the errors. The path attribute should be set the same as you specified it in the previous step. For IIS7 you need to register the Elmah Modules and Handlers in both system.web and system.webServer.
<httpHandlers>
<add verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />
</httpHandlers>
<httpModules>
<add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah"/>
<add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" />
</httpModules>
- In order to avoid emails being sent while developing you can either specify the deliveryMethod in your system.net/mailSettings/smtp element to be “SpecifiedPickupDirectory” or you can add some code to your Global.asax.cs file to filter out emails based on some logic.
Method 1: Specifying the deliveryMethod by adding some XML to the configuration node of your web.config:
<system.net>
<mailSettings>
<smtp deliveryMethod="SpecifiedPickupDirectory" from="noReply@somesite.com">
<specifiedPickupDirectory pickupDirectoryLocation="c:\temp\emails"/>
</smtp>
</mailSettings>
</system.net>
Method 2: Using custom logic in your Global.asax file.
void ErrorMail_Filtering(object sender, ExceptionFilterEventArgs e)
{
if (Request.IsLocal) e.Dismiss();
}
OR
void ErrorMail_Filtering(object sender, ExceptionFilterEventArgs e)
{
SqlConnectionStringBuilder csb = new SqlConnectionStringBuilder();
csb.ConnectionString = ConfigurationManager.ConnectionStrings["connectionString"].ConnectionString;
if( csb.DataSource.Equals( "development", StringComparison.CurrentCultureIgnoreCase )
e.Dismiss();
}
- Create the required tables and stored procedures in the database by running the script SQLServer.sql which was included in the download. You can delete the beginning part of the script that forces the database into 8.0 compatibility mode. Setting the compatibility mode to SQL 2000 is not really necessary.
If you are using a service account which has limited rights, then make sure you grant execute to the following stored procedures so ELMAH can log the errors to the ELMAH_Error table:
grant exec on ELMAH_GetErrorsXML to <SQLUserName>
grant exec on ELMAH_GetErrorXml to <SQLUserName>
grant exec on ELMAH_LogError to <SQLUserName>
- Add the source file HandleErrorWithELMAHAttribute.cs to your project. This will be used to decorate your controller(s) so errors are sent through ELMAH. If you are using a “Base Controller” then you only need to add the [HandleErrorWithELMAH] attribute to the base controller. If you are not using a base controller, then you will want to add the attribute to each controller. Although there are other ways to send the errors to ELMAH this is the easiest method and is used in Nerd dinner.
Warning: Make sure that you remove the [HandleError] attribute from the other controllers if it is specified. If you use the HandleError attribute on the other controllers the errors will not be fed into the ELMAH pipeline and you will not get email/SQL logging support for any errors that occur on that controller.
- All modern browsers check for the existence of favicon.ico. If the file, does not exist a 404 error will be logged to ELMAH which is very annoying. In order to circumvent this issue add a favicon.ico file to the root of your web application and add another route exception to your Global.asax.cs file.
routes.IgnoreRoute("{*favicon}", new {favicon=@"(.*/)?favicon.ico(/.*)?"});
Additional Step for MVC 1.0 Applications
In MVC 1, there was no default filter for *.axd files. Therefore, in order for the elmah.axd page to be displayed you need to ignore the route in the RegisterRoutes method of the Global.asax.cs file:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
Testing Your Configuration
The best way to test ELMAH is to generate an exception. You can do this by entering a non-existent route, or enter some route parameters that will result in an error. After the error is thrown you can navigate to http://<siteUrl>/elmah.axd to view the errors. If you are using SQL Logging you can also query the ELMAH_LogError table.
Related Resources
The ELMAH Project Home Page
Scott Hanselman - ELMAH: Error Logging Modules and Handlers for ASP.NET (and MVC too!)
Coding Horror - Exception-Driven Development