ELMAH – a great way of Troubleshooting Web Applications
Recently I found an incredible useful solution that will be able to help you troubleshooting errors and especially exceptions of web applications like the MDT Web FrontEnd (Sadly not for pure web services). One typical way of troubleshooting them is to write all important information into a log file as the Deployment web service does (see the last post for more information on the implementation of NLog in the Deployment web service). While often pretty useful it covers just the “expected” part of the problem. The more difficult ones are the “unexpected” errors, or better called exceptions. Those are often raised in situations a developer has never thought about or simply did not avoid by former verification of required conditions.
It can be added dynamically to any (even running) ASP.Net Web applications without changing any line of code. All it takes is dropping a dll into the bin directory and adding a couple entries to the web.config file and it will give you the following:
- 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 exceptions
- 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
- Log errors to several back-end storages:
- Microsoft SQL Server
- Microsoft Access
- Loose XML files
and a lot more features.
To show you how easy it is to implement we will now add ELMAH to the MDT Web FrontEnd.
First we need to download the newest version of ELMAH. The binaries are enough.
Extract the content to a temporary location. It will contain a couple folders with the necessary dlls, the sql scripts to create the necessary tables to log to a database server, plus several tools and samples. It also contains a default web.config you can take to copy&Paste the necessary entries shown below into your current web.config.
OK, now take the elmah.dll file from the bin folder and drop it to the bin folder of the MDT Web FrontEnd. Then add a new SectionGroup for elmah to the ConfigSections part of the web.config as shown in the below example:
<configSections> ... <sectionGroup name="elmah"> <!-- NOTE! If you are using ASP.NET 1.x then remove the requirePermission="false" attribute from the section elements below as those are only needed for partially trusted applications in ASP.NET 2.0 --> <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"/> <section name="errorTweet" requirePermission="false" type="Elmah.ErrorTweetSectionHandler, Elmah"/> </sectionGroup> </configSections> .... <elmah> <errorLog type="Elmah.XmlFileErrorLog, Elmah" logPath="~/App_Data" /> </elmah> ...
This is common over IIS 6 and IIS 7.
Now we need to add Elmah to the http modules and register it as a new handler. In IIS6 you do this in the httpHandlers and httpModules sections of the system.web section:
<System.web> ... <httpHandlers> ... <add verb="POST,GET,HEAD" path="/elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" /> </httpHandlers> <httpModules> ... <add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah"/> </httpModules> </System.web>
In IIS 7 more or less identical items are required in the System.webServer section. I would recommend having it configured at both places so you have a more versatile config file:
<system.webServer> <validation validateIntegratedModeConfiguration="false" /> <modules> <add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" preCondition="managedHandler" /> <add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah" preCondition="managedHandler" /> <add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" preCondition="managedHandler" /> <add name="ErrorTweet" type="Elmah.ErrorTweetModule, Elmah" preCondition="managedHandler" /> </modules> <handlers> <add name="Elmah" path="elmah.axd" verb="POST,GET,HEAD" type="Elmah.ErrorLogPageFactory, Elmah" preCondition="integratedMode" /> </handlers> </system.webServer>
Here I registered also a couple additional modules like the EMail function or to tweet exceptions. Just remove them if you don’t need it.
Finally you should add some basic security as you probably don’t want to enable everybody having access to such sensitive information. To restrict the use of elmah to the local machine, you could add the following to the “elmah” section shown above (It’s actually the default. You have to explicitly allow remote access if required):
<elmah> ... <security allowRemoteAccess="0" /> ... </elmah>
And you can restrict it also to authenticated Users only (or even better to specific Users or Roles.)
<location path="elmah.axd"> <system.web> <authorization> <deny users="?"/> </authorization> </system.web> </location>
As said, the download contains an example web.config file that is far more extensive then these examples shown. It might take a few minutes and some changes to get everything running the way you would like to have it. On default it writes the exceptions to xml files in the App_Data directory. But as mentioned, it can easily log to databases etc. Working examples are available in the download.
But as soon as configured, the daily usage is as easy and painless as it can be. Just open http://localhost/elmah.axd (or whatever path you specified) and you get something like:
This is already great as you now get information about what happened on specific User requests. No more screenshots from Users, no more fiddling around to try to redo what might have caused the error etc. No more adding thousands of additional logging lines into your code to get more information on specific problems.
You can now easily redirect your users to a more meaningful error page like “An error happened but we logged all information, we are aware it happened and will do our best to solve the problem….” and still collect all the necessary data. And even better, if you now click on the “Details…” link you will see a screen similar to the “yellow screen of death” plus all information that has been logged for this particular exception:
And as you can see, the amount of information available for each individual exception is just incredible. And even if you say “wtf is all this stuff about?”, if you add elmah to a custom web application and forward this information to the developers if something happens, they will immediately fall down on their knees thanking you for such useful feedback.
Elmah is the perfect addition to default logging (some even created a new way of coding called “Exception Driven Development” 😉 ) and can even be implemented if the developers did not add anything like this. It is unobtrusive, easy to add and flexible to configure. There is a whole lot more information about this topic and as it is with every topic, digging deeper into it might take some time but it’s definitely worth it. I will supply a couple links at the end of this post. I hope you enjoyed this post and gave some ideas. Don’t hesitate with your comments on MyITForum (you need to be signed on before being able to post!) or CodePlex.
Elmah (and NLog) will be part of the next release of the MDT Web Front End. There is no realofficial release date yet but I will keep you updated. Anyway, with this post you should be able to already integrate it yourself and maybe you can supply me with more information on problems that arise in your environment. And yes, if you want I will also fall on my knees to appreciate this 😉
Finally here some additional links for more information:
- ELMAH, project hosting on google code
- ELMAH: Error Logging Modules and Handlers for ASP.NET (and MVC too!)
- Using HTTP Modules and Handlers to Create Pluggable ASP.NET Components
- Exception-Driven Development
- ELMAH and Exception Driven Development FTW
- Securely Implement ELMAH For Plug And Play Error Logging
- Setup email alerts from ELMAH when exceptions are raised