Introducing the New Health Monitoring System


ASP.NET 2.0 comes equipped with a new system that allows for the raising of health monitoring events (also referred to as web events). The main benefit of this system is that because it is completely manageable through configuration files. Operations and other IT staff can monitor the health of deployed web applications without the direct intervention of developers. The health monitoring system is composed of two primary components:

  • Web event A web event is a derivative of the WebBaseEvent class and is used to contain information pertinent to the event raised and can often contain additional information. For example, several of the event classes that come with the system store information about the application such as its directory, the time of the event, the page in which the event occurred, and so on.

  • Web Event provider A Web Event provider is a special class that can subscribe to web events. When the provider receives an event, it can then store the event in a persistence medium like SQL Server or a file on disk, or it can forward the event by sending an e-mail or a text message to a cellular phone.

Events and providers are linked together in your application's Web.config file. Event types are assigned to named groups in the Web.config's <eventMappings> element. By default, ASP.NET already has several event providers defined as well as event groups.

Table 31.1 shows the web events that come with ASP.NET 2.0.

Table 31.1. ASP.NET 2.0 Web Events

Event Class

Description

WebApplicationLifetimeEvent

Indicates important lifetime events in an application such as startup and shutdown.

WebAuditEvent

Base class for all audit-type web events.

WebAuthenticationFailureAuditEvent

Indicates an authentication failure.

WebAuthenticationSuccessAuditEvent

Indicates successful authentication.

WebBaseErrorEvent

Base class for all error-type web events.

WebHeartbeatEvent

Used as a health monitoring timer. Event is raised once per heartbeatInterval as defined in the healthMonitoring Web.config section.

WebManagementEvent

Base class for web events that contain process details.

WebRequestErrorEvent

Indicates a web request error.

WebRequestEvent

Base class for all web events related to requests.

WebSuccessAuditEvent

Indicates a successful security event.

WebViewStateFailureAuditEvent

Indicates a view state failure.


ASP.NET 2.0 also contains several default web event providers. Those providers are described in Table 31.2.

Table 31.2. ASP.NET 2.0 Web Event Providers

Event Provider Class

Description

EventLogWebEventProvider

Stores web event data in the system event log.

SqlWebEventProvider

Stores web event data in SQL Server. Defaults to the App_Data folder and a SQL Express database but can be configured for other locations.

WmiWebEventProvider

Sends web events to WMI, converting them into WMI events.

SimpleMailWebEventProvider

These providers send e-mail in response to web events.

TemplatedMailWebEventProvider

 

TRaceWebEventProvider

Web event data is passed to the ASP.NET page tracing subsystem.


By default, very little of this system is configured. If you don't specify any other web event information in your application's Web.config file, your application will send the All Errors and Failure Audits events to the EventLogWebEventProvider class.

Using the Health Monitoring System

Using the health monitoring system really boils down to manipulating the Web.config file to determine which events are handled by which event providers. As mentioned earlier, errors and failure audits are sent to the system event log by default. Using the Web.config file, you can use additional ASP.NET Web Event providers to handle additional event types.

This section shows you how to use a SQL Server 2005 database table as the destination for error events such as unhandled exceptions. Although the system event log might be handy in a few circumstances, storing all application errors in a central location that can be queried from remote locations is extremely useful. For example, if your application is running in a web farm scenario (multiple web servers hosting the same application), you will want all of the errors to be accessible in the same place and tagged with the name of the machine that originated the error. Logging errors using the SqlWebEventProvider does exactly that.

To start, create a new ASP.NET web application and add a Web.config file to the project. The SQL Web Event provider uses a table called aspnet_WebEvent_Events that is created when you create an application services database using the aspnet_regsql.exe tool.

Listing 31.1 contains the modified Web.config that will utilize the SQL Web Event provider.

Listing 31.1. A Web.config File Supporting Web Event Persistence in SQL Server

[View full width]

<?xml version="1.0"?> <configuration> <appSettings/> <connectionStrings> <add name="ASPNET_AppServices"    connectionString="server=localhost; initial catalog=ASPNET_AppServices; Integrated  Security=SSPI;"/> </connectionStrings> <system.web> <healthMonitoring enabled="true" heartbeatInterval="0">   <bufferModes>     <add name="SqlDefault" maxBufferSize="1000"        maxFlushSize="10" urgentFlushThreshold="10"        regularFlushInterval="00:05:00" urgentFlushInterval="00:01:00"/>   </bufferModes>   <providers>     <add name="SqlEvents"       type="System.Web.Management.SqlWebEventProvider, System.Web, Version=2.0.0.0,  Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"       connectionStringName="ASPNET_AppServices" buffer="true" bufferMode="Analysis"/>   </providers>   <rules>   <add name="All Errors Rule"     eventName="All Errors" provider="SqlEvents"     profile="Default" minInterval="00:00:30"/>   </rules> </healthMonitoring> <compilation debug="true"/> <authentication mode="Windows"/> </system.web> </configuration> 

Next, add the following line of code to your default.aspx.cs file:

throw new ApplicationException("test error"); 


When you run the application, you will get the application exception and VS 2005 will break. Continue execution and then wait a minute or two. Because the SqlWebEventProvider class uses a buffered system, the error won't appear within the database immediately. Figure 31.1 shows the contents of the aspnet_WebEvent_Events table after an error occurs.

Figure 31.1. Storing web errors in SQL Server.


Also shown in this figure are lifetime events. Lifetime events indicate significant changes that occur in an application's lifetime such as application startup and shutdown. This information can be important when diagnosing problems with a production server. To support lifetime events in your application, change the preceding Web.config to the one shown in Listing 31.2.

Listing 31.2. A Web.config File Supporting Both Errors and Lifetime Events

[View full width]

<?xml version="1.0"?> <configuration> <appSettings/> <connectionStrings> <add name="ASPNET_AppServices"  connectionString="server=localhost; initial catalog=ASPNET_AppServices; Integrated  Security=SSPI;"/> </connectionStrings> <system.web> <healthMonitoring enabled="true" heartbeatInterval="0"> <eventMappings>   <add name="Lifetime"        type="System.Web.Management.WebApplicationLifetimeEvent, System.Web,Version=2.0.0.0 , Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/> </eventMappings> <bufferModes>     <add name="SqlDefault" maxBufferSize="1000" maxFlushSize="10"       urgentFlushThreshold="10" regularFlushInterval="00:05:00"       urgentFlushInterval="00:01:00"/> </bufferModes> <providers> <add name="SqlEvents"    type="System.Web.Management.SqlWebEventProvider, System.Web, Version=2.0.0.0,  Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"     connectionStringName="ASPNET_AppServices" buffer="true" bufferMode="Analysis"/> </providers> <rules>   <add name="All Errors Rule"     eventName="All Errors" provider="SqlEvents"     profile="Default" minInterval="00:00:30"/>   <add name="Lifetime Rule" eventName="Lifetime"     provider="SqlEvents" profile="Default" minInterval="00:00:30"/> </rules> </healthMonitoring> <compilation debug="true"/> <authentication mode="Windows"/> </system.web> </configuration> 

This configuration file adds a new entry to the <eventMappings> section indicating that events in the group "Lifetime" are of the type WebApplicationLifetimeEvent. The <rules> section indicates that all events in the group "Lifetime" are to be handled by the SqlWebEventHandler class. This provides the necessary hooks to get information like application startup and shutdown stored in the SQL Server database.

Note

If you are a tinkerer or just curious, you might try to raise these events manually instead of letting ASP.NET handle them on your behalf. This can't be done, however. All of the default web event classes have an internal protection level so that they cannot be instantiated by code outside the System.Web assembly. This is done deliberately to ensure that only the ASP.NET engine can manually raise the default events. If you want to raise custom events, the next section, "Creating Custom Events," should prove helpful.


Creating Custom Events

Before getting into the details of how to create a custom event, it is important to know when custom events should and should not be created. One important factor to keep in mind is that the developer does not have explicit control over when ASP.NET raises its own default custom events outside of defining event mappings and rules in the Web.config file. In other words, a programmer cannot explicitly raise an "Application Startup" event through code. The following guidelines should help you make the decision as to when to create a custom event:

  • If your event requires the storage of data that is not already being stored by any of the existing event classes, you should create your own event.

  • If you need programmatic control over when to signal the event, you can create your own and inherit from the event you want to manually signal. Keep in mind, however, that ASP.NET already does an excellent job of signaling events at the appropriate time, and you should use the existing events whenever possible.

Tip

A common pitfall that a lot of people run into is that they create a web event that inherits from an existing base event, and then manually fire that event in the same place where ASP.NET would have automatically fired it. For example, if a developer overrides the WebErrorEvent and calls the Raise() method within the catch portion of a TRy/catch block, she is essentially reinventing the wheel. In this situation, the only reason a developer should take manual control over raising such error events is if the developer needs to store more information in the event than the default ASP.NET WebErrorEvent class provides.


The next sample will illustrate the use of a custom web event that will get signaled when a user of a research department's website requests a search. As you'll see in the next section on creating a custom provider, this request can then either be handled automatically via web services or dispatched to a research department employee.

Add a new Class Library project to the solution that contains the website from the previous samples. Add a reference to the System.Web Assembly and add a class to the project called AsyncSearchRequest. Listing 31.3 shows the class that inherits from WebBaseEvent.

Listing 31.3. The AsyncSearchRequest Class

using System; using System.Web; using System.Web.Management; using System.Web.UI; using System.Web.UI.WebControls; using System.Collections.Generic; using System.Text; namespace SampleEvents { public class AsyncSearchWebEvent : WebBaseEvent { private DateTime timeRaised; private string searchCriteria = string.Empty; public AsyncSearchWebEvent(string message,     object eventSource,     int eventCode)     : base(message, eventSource, eventCode) { } public AsyncSearchWebEvent(string message,     object eventSource,     int eventCode,     int eventDetailCode)     : base(message, eventSource, eventCode,     eventDetailCode) { } public override void Raise() {     timeRaised = DateTime.Now;     base.Raise(); } public override void FormatCustomEventDetails(WebEventFormatter formatter) {     formatter.AppendLine("");     formatter.IndentationLevel += 1;     formatter.AppendLine("-- Custom Event Data --");     formatter.AppendLine(string.Format("Search Critera: {0}", searchCriteria));     formatter.AppendLine(string.Format("Event Raised On: {0}", timeRaised.ToString()));     formatter.IndentationLevel -= 1; } public DateTime TimeRaised {     get { return timeRaised; }     set { timeRaised = value; } } public string SearchCriteria {     get { return searchCriteria; }     set { searchCriteria = value; } } } } 

The constructors were created so that you can see where you can inject your own code into the instantiation process. The FormatCustomEventDetails method is used to provide additional text data that will be logged with the event when sent to a provider.

One of the most powerful features of the new ASP.NET Web Management system is that you can plug any of your custom events into any of the existing event providers or any custom providers that you or a third party create.

Listing 31.4 contains a new Web.config for the web application that associates the newly created custom event with the SQL Server Web Event provider.

Listing 31.4. A Modified Web.config File Supporting Custom Web Events

[View full width]

<?xml version="1.0"?> <configuration> <appSettings/> <connectionStrings> <add name="ASPNET_AppServices"    connectionString="server=localhost; initial catalog=ASPNET_AppServices; Integrated  Security=SSPI;"/> </connectionStrings> <system.web> <healthMonitoring enabled="true" heartbeatInterval="0">     <eventMappings>       <add name="Lifetime"            type="System.Web.Management.WebApplicationLifetimeEvent, System.Web, Version=2 .0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>       <add name="SearchEvent"            type="SampleEvents.AsyncSearchWebEvent, SampleEvents"            />     </eventMappings>       <bufferModes>          <add name="SqlDefault" maxBufferSize="1000" maxFlushSize="10" urgentFlushThreshold="10" regularFlushInterval="00:05:00"       urgentFlushInterval="00:01:00"/>     </bufferModes>     <providers>         <add name="SqlEvents"      type="System.Web.Management.SqlWebEventProvider, System.Web, Version=2.0.0.0,  Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"       connectionStringName="ASPNET_AppServices" buffer="true" bufferMode="Analysis"/>     </providers>     <rules>         <add name="All Errors Rule" eventName="All Errors" provider="SqlEvents" profile="Default" minInterval="00:00:30"/>     <add name="Lifetime Rule" eventName="Lifetime" provider="SqlEvents" profile="Default" minInterval="00:00:30"/>     <add name="SearchEvents Rule" eventName="SearchEvent" provider="SqlEvents" profile="Default" minInterval="00:00:30"/>     </rules> </healthMonitoring> <compilation debug="true"/> <authentication mode="Windows"/> </system.web> </configuration> 

To raise this event, you need to do it manually using the Raise() method on the custom event class. Because this class isn't part of the default ASP.NET framework, it won't raise events unless your code forces it to happen, as shown in the following example:

SampleEvents.AsyncSearchWebEvent searchEvent = new SampleEvents.AsyncSearchWebEvent(     "Search Requested", this, WebEventCodes.WebExtendedBase + 1); searchEvent.SearchCriteria = "C#; searchEvent.Raise(); 


Every event requires an event code in order to be raised. Event codes less than 100,000 are the sole property of ASP.NET and cannot be used by custom events. Therefore, your event codes should start at WebExtendedBase and increment from there. Event codes above 100,000 can be reused by any event. After running the preceding code and waiting a few minutes for the event buffer to flush, you will see a new event appear in the aspnet_WebEvent_Events table. The Details column contains the following text:

Event code: 100001 Event message: Search Requested Event time: 1/22/2006 1:45:07 PM Event time (UTC): 1/22/2006 8:45:07 PM Event ID: a0569b9574994157826690f25b38c13f Event sequence: 7 Event occurrence: 1 Event detail code: 0  Application information:     Application domain: c1085da7-1-127824362038281250     Trust level: Full     Application Virtual Path: /HealthMonitor1     Application Path: C:\Documents and Settings\Kevin\My Documents \Writing\SAMS\C# 2005 Unleashed\31\Code\HealthMonitor1\     Machine name: LAB01 Custom event details:               -- Custom Event Data --        Search Critera: C#         Event Raised On: 1/22/2006 1:45:07 PM 


Creating Custom Event Providers

To illustrate how to create a custom Web Event provider, this section will show you how to create a Research Dispatch provider that handles AsyncSearchWebEvent events and dispatches them accordingly. To create a basic Web Event provider, create a class that inherits from the base class BufferedWebEventProvider (you can create an unbuffered one, but this sample uses a buffered provider to provide a comparison with the buffered SqlWebEventProvider class). To see this in action, add a new class called SearchWebEventProvider to the class library that contains the AsyncSearchWebEvent class. This class is shown in Listings 31.5.

Listing 31.5. A Simple Custom Web Event Provider

using System; using System.Web; using System.Web.Management; using System.Web.UI; using System.Web.UI.WebControls; using System.Collections.Generic; using System.Text; namespace SampleEvents { public class SearchWebEventProvider : BufferedWebEventProvider { public override void ProcessEvent(WebBaseEvent eventRaised) {     if (UseBuffering)         base.ProcessEvent(eventRaised);     else         DispatchEvent((AsyncSearchWebEvent)eventRaised); } public override void ProcessEventFlush(WebEventBufferFlushInfo flushInfo) {     foreach (WebBaseEvent evt in flushInfo.Events)         DispatchEvent((AsyncSearchWebEvent)evt); } public void DispatchEvent(AsyncSearchWebEvent webEvent) {     // use this method to decide whether the event     // should dispatch to a code-resolved search or     // a human-resolved search (dispatch to a work queue) } } } 

The code for the provider itself isn't very complex. The complexity can come from choosing the storage medium or notification medium used when handling the event. The preceding sample shows how you can create a simple provider shell to be used with the search event.



Microsoft Visual C# 2005 Unleashed
Microsoft Visual C# 2005 Unleashed
ISBN: 0672327767
EAN: 2147483647
Year: 2004
Pages: 298

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net