Every app you ever build should have some easy way to access a log of recent exceptions. An easy way to accomplish this is to use the ELMAH library. ELMAH stands for Error Logging Modules and Handlers. In its simplest form ELMAH takes care of logging unhandled exceptions as well as giving you an easy way of accessing that log, which tends to be a quite good starting point.
Installation
To add ELMAH to your MVC application you simply install the Elmah.Mvc nuget package. This adds references to the needed assemblies and adds a bunch of stuff to your web.config.
Just by adding that nuget package you now have added logging of unhandled exceptions to your application. To see the error log, and check that everything is working you simply open up your site on localhost and go to the uri /elmah. You should now see a page with a list of the recent log entries (probably empty, since you just added ELMAH).
The default configuration is such that the logging is made in-memory, which is good since it minimizes the need for configuration, but bad since you will lose the log when you app pool is recycled. It is also set up to only allow requests from localhost to access the log page, which is a good idea from a security point of view, but might be unpractical.
Enabling Remote Access
To enable remote access of the ELMAH page you need to add the following to the ELMAH section of you Web.config:
<elmah>
<security allowRemoteAccess="yes" />
</elmah>
By doing that you open up the page to be accessible by anyone, which is NOT a good idea, so you need to do some further web.config tweaking to make it secure.
Securing the ELMAH page
If you start googling how to make the ELMAH page secure you will most likely find advice on how to set up location entries in you web.config to restrict access to elmah.axd. This does not play well with Elmah.Mvc, which uses a slightly differrent approach. Elmah.Mvc adds a bunch of app settings to your web.config which lets you control the security of the page in an easy manner:
<appSettings>
<!-- snip -->
<add key="elmah.mvc.disableHandler" value="false" />
<add key="elmah.mvc.disableHandleErrorFilter" value="false" />
<add key="elmah.mvc.requiresAuthentication" value="true" />
<add key="elmah.mvc.IgnoreDefaultRoute" value="false" />
<add key="elmah.mvc.allowedRoles" value="*" />
<add key="elmah.mvc.allowedUsers" value="someadminusername" />
<add key="elmah.mvc.route" value="elmah" />
</appSettings>
The first step is to set the elmah.mvc.requiresAuthentication value to true, which ensures that the user is authenticated by Forms Authentication when accessing the ELMAH page. But that alone is not enough, so you need to add either allowedUsers or allowedRoles. Those settings tells Elma.Mvc to check that the user accessing the page has one of the listed usernames or roles, depending on what you have specified.
Configuring where ELMAH Saves the Log Entries
As I mentioned earlier, ELMAH stores the log in-memory by default, but you can configure it to use XML files or a SQL database instead if you want to avoid losing the log every now and then.
To enable XML file logging you need to do some further web.config tweaking by adding a setting to the ELMAH section of the web.config:
<elmah>
<security allowRemoteAccess="yes" />
<errorLog type="Elmah.XmlFileErrorLog, Elmah" logPath="~/App_Data" />
</elmah>
If you choose this approach you need to make sure that your application has write permissions on the path you specify as logPath.
If you would rather have ELMAH save the log to a database you modify the config to look like this instead:
<elmah>
<security allowRemoteAccess="yes" />
<errorLog type="Elmah.SqlErrorLog, Elmah" connectionStringName="YourConnectionStringName" />
</elmah>
Since it writes stuff to the database you also have to make some schema changes in the database to which you pointed ELMAH with the connection string you chose above. To find the latest SQL script you go to the ELMAH downloads page, navigate to the latest release, and scroll down until you find the links called "DDL Script". There you chose the appropriate database provider and download that script.
The script creates a table and three stored procedures. You now have to make sure that the database user you use for the application has access to the table and execute access to the stored procedures. Here is how to add the execute persmissions:
GRANT EXECUTE ON [dbo].[ELMAH_GetErrorXml] TO yourdatabaseusername;
GRANT EXECUTE ON [dbo].[ELMAH_GetErrorsXml] TO yourdatabaseusername;
GRANT EXECUTE ON [dbo].[ELMAH_LogError] TO yourdatabaseusername;
That should be it! To make sure everything works, force an error in some way (I added an action which simply raises an exception), navigate to /elmah on your site and make sure the error appeared in the log.
Comments