Keeping Pulse on Your Site With ASP.NET 2.0 Health Monitoring
One of the best, yet often overlooked, features of ASP.NET 2.0 is health monitoring. I believe it is absolutely essential to be notified of any problems with your web application, and this is where health monitoring comes in handy. A few years ago I wrote an article about custom error pages and demonstrated various ways to tap into error details. Health Monitoring is a natural progression of that approach.
There are three pieces to this puzzle:
You need to decide what you want to be notified about. ASP.NET 2.0 comes with a number of events pre-configured for you. I found just about the best diagram of what events are available out of the box in this how-to (follow the link or click the diagram below).
For example, if you want to know about all events, you’ll get bombarded. Every time your site starts up, shuts down, recompiles, etc, an event will be raised. If your method of delivery is email, your inbox will beg for mercy.
If you only want to know about errors (and you always should!), you will be notified about aborted requests, view state errors, unhandled exceptions, etc. In my opinion, you owe your users to monitor at least this much. On the diagram above, it’s everything next to
You may want to zero in on a specific error. Scott Guthrie showed how to log shutdown events with some hacking. Health monitoring comes with a pre-defined event, ApplicationShutdown (#1002) which you can easily wire to achieve the same.
<eventMappings> <add name="My site shutdown notifications" type="System.Web.Management.WebApplicationLifetimeEvent, System.Web, Version=18.104.22.168, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" startEventCode="1002" endEventCode="1002" /> </eventMappings>
An event will list the shutdown reason along the following lines:
** Events ** --------------- Event code: 1002 Event message: Application is shutting down. Reason: Configuration changed. [...skipped...]
Last, but not least, you can write your own (custom) events. For example, Positive Lookahead raises a custom event every time a review is submitted and sends me an email with detailed information. Implementing and raising custom events is very easy.
Even though I’ve been talking about “defining events,” most likely you won’t need to define anything. Below are listed a handful of interesting events pre-configured for you in 2.0. Class names in parentheses are for your reference. You’ll be able to look them up on the above diagram.
- “All events” (
WebBaseEvent). Anything and everything that happens on your site.
- “Application Lifetime Events” (
WebApplicationLifetimeEvent). Application compilation, start-up and shutdown.
- “All Errors” (
WebBaseErrorEvent). Any and all errors on the site.
- “Infrastructure Errors” (
WebErrorEvent). Compilation, configuration, parse, etc, errors.
- “Request Processing Errors” (
WebRequestErrorEvent). View state and validation errors, as well as all unhandled exceptions.
Once you’ve decided what to monitor, you need to decide what to do with notifications. You can have them written to the system event log, sent to the trace (ASP.NET page tracing system), emailed, written to a database, or passed to the Windows Management Instrumentation (WMI). This is where providers come into picture.
You may write your own provider, for example, to log events via a web service. Below is a diagram of pre-canned providers (click for a bigger image):
Health monitoring allows you to have the same event(s) handled by multiple providers. For example, all site errors can be emailed to you and handed over to a custom provider, should you write one.
If you host a site in a shared environment, you won’t have access to the system event log. This is where email providers, “simple” and “templated”, come to the rescue.
SimpleMailWebEventProvider sends insanely detailed logs. It’s fine as long as you need all that information. To tame the format and content, use
which allows you to design a template and limit the amount of information that gets put in. Send E-mail for Health Monitoring
Notifications shows how to use these two providers. Another extremely helpful how-to, Use Health Monitoring in ASP.NET 2.0, provides additional clues how to set email header, footer, separator, and so on.
Rules bring events and providers together. A rule spells out which events to monitor and how to deliver them.
For example, I’d like to have all errors from my site emailed to me. I’d add the following configuration section to web.config:
<system.web> <healthMonitoring enabled="true"> <providers> <add name="MailWebEventProvider" type="System.Web.Management.SimpleMailWebEventProvider" to="[an email here]" from="[an email here]" buffer="false" subjectPrefix="My site crapped its pants: " /> </providers> <rules> <add name="All errors from my site" eventName="All Errors" provider="MailWebEventProvider" profile="Critical" /> </rules> </healthMonitoring> </system.web> <system.net> <mailSettings> <smtp deliveryMethod="Network"> <network defaultCredentials="true" host="[your SMTP server]" /> </smtp> </mailSettings> </system.net>
You’ll notice I don’t explicitly declare events here. As discussed before, “All errors” is pre-configured. You will find it here under
<eventMappings>. The finer points of what each attribute means are well documented on MSDN. I only want
to draw your attention to the
Out of the box, there are two profiles: default and critical.
<profiles> <add name="Default" minInstances="1" maxLimit="Infinite" minInterval="00:01:00" custom="" /> <add name="Critical" minInstances="1" maxLimit="Infinite" minInterval="00:00:00" custom="" /> </profiles>
Under the default profile
- The minimum number of times an event can occur before an event notification is sent is 1.
- The maximum number of times an event can occur before notifications stop is 2147483647 (infinite).
- The minimum time interval between two events is one minute.
The critical profile doesn’t throttle the flow of event notifications, so there’s no one-minute limitation, and notifications are dispatched right away. I’m deliberately not getting into a discussion about buffering to keep things simple.
I hope this post gives you enough information to get going with health monitoring. I wanted to keep it on a conceptual level, which is why there was no talk of implementation details.