Thursday, January 25, 2007

Health Monitoring in ASP.NET 2.0

Health Monitoring in ASP.NET 2.0 helps monitor problems in your application. Here's nice MSDN article about it:
How To: Use Health Monitoring in ASP.NET 2.0
In particular,
System.Web.Management.SqlWebEventProvider works quite good out of the box.

Note, that Health Monitoring designed for web forms applications and does not target winforms applications.
For example, if you want logging Windows Services, Log4Net 3rd party component, or through embedded System.Diagnostics.EventLog component are the ways to go.

If you want to get error messages from your site through email, read this:
How to: Send E-mail for Health Monitoring Notifications

Note, however, that SimpleMailWebEventProvider has some unpleasant limitations:
1) You cannot send emails using SSL SMTP, so Gmail's SMTP is not available for you. The reason here is that uses standard SMTP ASP.NET provider, and standard SMTP ASP.NET provider is not fully configurable through web.config.
There is no way for you to specify:
smtpClient.EnableSsl = true;
As a result, emails sent through Google's SMTP are simply dissappear.

2) You cannot override SimpleMailWebEventProvider provider, because it's sealed.
So, you have to write your own mail provider from scratch.

Implementing your own isn't very hard.
I tried to inherit my EmailEventProvider from MailWebEventProvider, but I couldn't even make the code compile. It seems that MailWebEventProvider if poorly written (yeap, not every developer at MS is good).

But inheriting from BufferedWebEventProvider worked like a charm.
Here's the C# code:
using System;
using System.Text;
using System.Web;
using System.Web.Management;
using System.Configuration;
using System.Collections.Specialized;

namespace MyNameSpace
sealed class EmailEventProvider : BufferedWebEventProvider
private string _to;
private string _subject;

public override void Initialize(string name, NameValueCollection config)
GetAndRemoveStringAttribute(config, "to", ref this._to);
GetAndRemoveStringAttribute(config, "subject", ref this._subject);
if (string.IsNullOrEmpty(this._to))
throw new ConfigurationErrorsException(string.Format("Recipient must be defined for {0}provider", name));
base.Initialize(name, config);

private static void GetAndRemoveStringAttribute(NameValueCollection config, string attrib, ref string val)
val = config.Get(attrib);

public override void ProcessEventFlush(WebEventBufferFlushInfo flushInfo)
StringBuilder sb = new StringBuilder();
// Write flushInfo.Events:
foreach (WebBaseEvent wbe in flushInfo.Events)
sb.AppendFormat("{0}\r\n", wbe.ToString(true, true));

SendMail(DateTime.Now.ToString(), _to, _subject, sb.ToString());

Here's web.config's code:
<healthMonitoring enabled="true" heartbeatInterval="0" >
    <add name="MyEmailEventProvider" type="MyNameSpace.EmailEventProvider" buffer="false"
         subject="Crash in MyAspNet app" />
    <add name="All Errors by Email" eventName="All Errors" provider="MyEmailEventProvider" />


About Me

My photo
Email me: