Configuring and customizing the health monitoring system of ASP.NET

This article illustrates how to configure and customize the health monitoring system of ASP.NET.

Custom errors and early error-logging effort

In the beginning, webs were just "webs", webs of interconnected links to static HTML pages. Now webs resemble more of communities bustling with activities, with members of different roles, media in all forms and shapes, etc. As a web site grows more complex, the opportunities for errors and exceptions multiply. As it attracts more users, it becomes a bigger target of malicious attacks. Now it has become a must for a website to have a systematic approach to log web events, monitor the ebbs and flows of user activities, locate traffic bottlenecks, and handle exceptions and errors gracefully.

For ASP pages, programmers generally do not have many choices but sprinkle response.write statements to check the inner working mechanism of a segment of code.

With ASP .NET 1.x, programmers are equipped with a set of tools for tracing and error handling. And it became a standard to configure custom error pages whenever an error occurs. Errors are part of programming life, however it is not acceptable to have an application crash and throw at users' face an ugly yellow page filled with obtuse non-English words. It could also be dangerous, if critical technical details are exposed to "evil" eyes.

To use custom error pages, we use the customerErrors section in the web.config (For .asp pages, the way to do it is going to the IIS administration console to specify the path for different custom error pages for different error codes, however if you do not have access to the IIS, it would not be an option).

There are three modes in the customErrors section, Off, On and RemoteOnly. Off means to disable custom errors and show the yellow page with raw error details, which is only recommended to programmers in developing stage; On means shut off raw error message completely and display custom errors only; RemoteOnly will display designated custom error pages to remote clients, however original error pages to whoever (the debugging programmer hopefully) is using the website hosting computer.

While the customErrors section takes care of setting up a friendlier client-side front, the more important step is to log errors for later review and debugging. In ASP .NET 1.x, for logging and trapping errors, we could write some custom code in the page's Error event handler, or in a custom page base class, as in the following:

We can also trap and log error details on application level by coding the Application_Error event handler, in the Global.asax.cs code behind file:

Configuring the health monitoring system

All of the above, customErrors section in the web.config file, coding to log error details in either the Application_Error or Page_Error event handler, works for ASP.NET 1.x and above. However, with ASP .NET 2.0, there is something much better, more comprehensive and systematic. This is the health monitoring system.

The system can log a plethora of events that all drive from WebBaseEvent.

Figure 1: Web Events

Table 1: Health monitoring events that can be logged

Name

Examples

WebHeartbeatEvent

overall application health, such as number of active threads, requests. It is raised at a periodic interval, as defined by the web.config file.

WebRequestEvent

A class that includes all web request information. Requests queued, processing, or rejected.

The health monitoring system has a group of built-in providers for logging.

Table 2: Health monitoring event providers

Name

Logging source

EventLogWebEventProvider

the Windows Event Log

TraceWebEventProvider

trace listener, can be viewed by using trace.axd.

WmiWebEventProvider

the Windows Management Instrumentation (WMI) subsystems

SqlWebEventProvider

SQL server database, 7.0 and above

SimpleMailWebEventProvider

plain email

TemplatedMailWebEventProvider

a customizable emil with external email template

The configuration settings of the Health Monitoring sytem in the web.config file have five sections to specify the type of events to be logged and their corresponding names (eventMappings), logging destinations (providers), logging rules (rules) with different frequencies, internals and buffer modes (profiles and buffermodes).

Figure 2: The ASP.NET Health Monitoring System

For example, the following section instructs the application to log application lifetime events to the Windows Event log.

With the above instrumentation, we get the following result from the Windows Event log:

Figure 3: The Windows Event Log

The eventMapping subsection allows you to assign different names to any type of events, the providers lists all of the event providers that the system needs to use, the rules hook up different events with different event providers with the frequency, minimum number of an event must occur before logging and the maximum number of logging efforts.

We can also have a separate profiles section to define different logging fashions.

bufferModes is another section to allow us to fine tune our system. We can set different buffer modes for different providers.

Setting Up SQL providers

It is a good idea to use a database as the logging destination, because it gives us the greatest degree of flexibility (unless the database crashes). However, to do so, the database must have a predefined schema with a table named aspnet_WebEvent_Events and a stored-procedure called apsnet_WebEvent_LogEvent.

No actions are needed if the default ASPNETDB.MDF database in the App_Data folder is set as the source of the SqlWebEventProvider other than needing to specify appropriate connection string in the web.config file.

With ASP .NET 1.x, database connection string is typically stored in the appSettings section. In ASP .NET 2.0, it is in a dedicated section: connectionStrings, as the following:

The above section defines a connectionString named "LocalSqlServer" and sets the AttachDBFilename to aspnetdb.mdf, so that at runtime the default database can be dynamically attached to a SQL Server instance. The |DataDirectory| in the connectionString instructs the application to fetch the database file from its APP_Data folder.

However if we decide to use our own database, we need to execute aspnet_regsql.exe to create the necessary table and procedure. The aspnet_regsql.exe is located at the %WINDOWS%\Microsoft.NET\Framework\version directory. The same tool can also be used to configure the data objects needed for other systems such as membership, role and profile.

We can run the command as the following:

Once the database is set up, and the events table and logging procedure are in place, we can add the SqlWebeventProvider to the provider list and assign it the type of events to log.

In the following example, we use two gridviews (one general, one detailed) and two SqlDataSources (one with a filter expression to distill to individual events) to display the web events emitted by the application.

With the above code, we get the following output:

Figure 4: Output

Logging Events to Email

Email is a perfect notification tool to alert administers of any application anomaly. It is better than phones, because it is much more easily programmable (and it is less annoying).

As we mentioned above, there are two types of email event providers: SimpleMailWebEventProvider and TemplatedMailWebEventProvider. The later affords more control over formatting and content. To use either, we need to configure the email settings in the web.config file as such:

Then in the healthMonitoring section, we specify the email event provider and common email parameters such as sender, receiver, email subject, etc.

The TemplatedMailWebEventProvider uses an email template where we can programmatically control how to format and phrase our message, what to include and omit. For example, in the email template, we could send an email notification with only the source of the error event, the time it occurred and a simple message.

Configuring a TemplatedMailWebEventProvider is the same as with SimpleMailWebEventProvider except you need to specify the name of the email template.

Logging a custom event

Despite the wide range of events the health monitoring system logs and the layers of nuances it covers, somewhere, at some point, we would have our problem of our own, and it is at this "some point", we will need to raise a custom event and log it into the system.

To be able to do so, the first thing is to create a custom event class from a class library project; then we compile the project and reference it from our web application by put the .dll file in the bin folder. Unlike the pre-defined web events, we must explicitly raise the custom events.

The custom event must inherit one of the existing web events; in our case we just create a SampleCustomEvent that inherits WebBaseEvent and add some of our own customized messages:

After we compile the class, we can instruct web.config with regards to the custom event and the logging rules:

We can log the same type of events to different event providers, for instance, the same custom event can be sent to both Sql server and an administrator's email.

Summary

It is a must for any serious web applications to log errors, watch out for malicious attacks, and monitor general web application health. With ASP .NET 2.0's health monitoring system, we are equipped with a comprehensive, flexible and powerful tool for just such logging requirement.

You might also be interested in the following related blog posts

Open SQL Port for specific IP by ASP.NET Website
read more
Update to Logging in to DotNetNuke from a Silverlight Application with RIA Authentication
read more
SQL 2008 CLR Triggers, use a .NET class library in SQL using WPF
read more
Logging in to DotNetNuke from a Silverlight Application with RIA Authentication
read more
WSE, DIME; WCF, MTOM; OH My!
read more
Exposing Custom WCF Headers through WCF Behaviors
read more
Twitterjecting
read more
Silverlight SVC Web Service problems on IIS
read more
The Twitter Search API made easy with Linq to XML
read more
Creating Extension Methods in VB
read more