Blog Home  Home Feed your aggregator (RSS 2.0)  
ASP.NET 2.0 - Health Monitoring - Manuel Abadia's ASP.NET stuff
 
# Thursday, 05 October 2006

The health monitoring in ASP.NET 2.0 is a framework to generate and capture events during the life of the application. The health monitoring uses the provider model. A health monitoring provider can capture events and do any processing with them (log them, send them by email, etc). There are a lot of predefined events and we can create our custom events. As we will see, it is very easy to use the health monitoring system, but we need a solid understanding of the different elements involved.

To configure the health monitoring system we have to use the web.config. The health monitoring section has to be placed inside the <system.web> section and has the following structure:

<healthMonitoring>

  <bufferModes/>

  <providers/>

  <profiles/>

  <rules/>

  <eventMappings/>

</healthMonitoring>

 

The healthMonitoring element has two attributes:
• enabled: specifies if the health monitoring system is enabled or not.
• heartbeatInterval: the system will raise WebHeartbeatEvent with the frequency specified here (more on this later).


Buffer modes:

There are some events that can be buffered so the provider saves some events in memory before doing some work with them. The buffering options are specified in the providers in the bufferModes subsection, and then a buffered provider points to a buffer mode in order to use buffering. The buffer mode specifies the number of events of the buffer and the flushing frequency and intervals.

The default buffer modes are (extracted from the global web.config):

<bufferModes>

  <clear />

  <add name="Critical Notification" maxBufferSize="100" maxFlushSize="20" urgentFlushThreshold="1" regularFlushInterval="Infinite" urgentFlushInterval="00:01:00" maxBufferThreads="1" />

  <add name="Notification" maxBufferSize="300" maxFlushSize="20" urgentFlushThreshold="1" regularFlushInterval="Infinite" urgentFlushInterval="00:01:00" maxBufferThreads="1" />

  <add name="Analysis" maxBufferSize="1000" maxFlushSize="100" urgentFlushThreshold="100" regularFlushInterval="00:05:00" urgentFlushInterval="00:01:00" maxBufferThreads="1" />

  <add name="Logging" maxBufferSize="1000" maxFlushSize="200" urgentFlushThreshold="800" regularFlushInterval="00:30:00" urgentFlushInterval="00:05:00" maxBufferThreads="1" />

</bufferModes>

 

The name attribute is used to associate a buffer mode with a provider. The maxBufferSize attributes specifies the maximum number of events that can be buffered before flushing them.

Usually, events are flushed at constant intervals specified by the regularFlushInterval. However, some times is better to flush events more quickly than the regularFlushInterval. When the number of buffered events is greater or equal than the urgentFlushThreshold, the events will be flushed at an interval specified by the urgentFlushInterval.

The maxFlushSize specifies the maximum number of events to process when flushing.

The maxBufferThreads attribute specifies the maximum number of threads used for flushing.

For example, suppose we are using a provider that saves the events to a DB using the “Logging” buffer mode. The buffer can hold up to 1000 events. Usually, the events will be saved every 30 minutes, but if there are 800 or more events waiting to be logged, they don’t have to wait 30 minutes to be saved, they will be saved at 5 minutes intervals, until there are less than 800 in the buffer, as the provider will save only 200 events at a time.

Providers:

A provider is a class that inherits from System.Web.Management.WebEventProvider. In the providers configuration subsection we can add the providers that we want in order to process the captured events. However, the association of providers and events to capture is made in the rules section that will be explained later. The provider has 2 common attributes, name and type. Each specific provider can have more attributes needed for its respective tasks. The name type is used for referencing the provider in different sections and the type specifies the class and assembly where the provider is located.

This class diagram shows the available providers:

The available providers are:

• SqlWebEventProvider stores events in a Sql Server database.
• EventLogWebEventProvider stores events in the windows event log.
• TraceWebEventProvider passes events to the Trace object.
• WmiWebEventProvider maps events to WMI events.
• SimpleMailWebEventProvider sends emails with event notifications.
• TemplateMailWebEventProvider uses a template to format the emails that sends with event notifications.

To configurate the Sql Server database for the SqlWebEventProvider take a look here.

The WebEventProvider class has 3 abstract methods:

public abstract class WebEventProvider : ProviderBase

{

    protected WebEventProvider();

 

    public abstract void Flush();

    public abstract void ProcessEvent(WebBaseEvent raisedEvent);

    public abstract void Shutdown();

}

The buffered event providers (Sql server provider and the mail providers) inherit from the BufferedWebEventProvider class that provides the basic infrastructure for a buffered provider:

public abstract class BufferedWebEventProvider : WebEventProvider

{

    protected BufferedWebEventProvider();

 

    public string BufferMode { get; }

    public bool UseBuffering { get; }

 

    public override void Flush();

    public override void Initialize(string name, NameValueCollection config);

    public override void ProcessEvent(WebBaseEvent eventRaised);

    public abstract void ProcessEventFlush(WebEventBufferFlushInfo flushInfo);

    public override void Shutdown();

}

A buffered provider has two extra parameters, buffer and bufferMode. Buffering is only used if buffer=”true”. If buffering is used, bufferMode links the provider with a buffer mode that was explained in the previous section.

The default configuration for the providers is (extracted from the global web.config):

<providers>

  <clear />

  <add name="EventLogProvider" type="System.Web.Management.EventLogWebEventProvider,System.Web” />"

  <add name="SqlWebEventProvider" type="System.Web.Management.SqlWebEventProvider,System.Web”" connectionStringName="LocalSqlServer" maxEventDetailsLength="1073741823" buffer="false" bufferMode="Notification" />

  <add name="WmiWebEventProvider" type="System.Web.Management.WmiWebEventProvider” />"

</providers>

 

Profiles:

Some events should be always logged using a provider, but sometimes, an event can happen a lot of times per second if an important error surfaces, so the profile subsection can help to configure if we have to log all events received or if we can ignore the same event for a short period of time.

A group of events can be assigned a concrete profile in the rules section as we’ll see soon.

The default configuration for the profiles is (extracted from the global web.config):

<profiles>

  <clear />

  <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>

 

The name attribute is used to associate an event with the profile. The minInstances indicates the minimum number of occurrences of an event before the event is logged. The maxLimit is used to stop logging an event after the number of occurrences of the event is greater or equal to this value. The minInterval can be used to avoid logging events if the interval between events is less than the minInterval.

The custom attribute can be used to do more complex evaluations to check if the event should be sent to the providers. See the IWebEventCustomEvaluator interface for more information.

As you can see, there are two predefined profile modes: the Critical, that logs every event without exception; and the Default, that avoids logging the same event twice in a minute.

Event Mappings:

In this configuration subsection, we associate a name with an event or group of events.

Without knowing a bit of the event types we can’t understand the health monitoring system, so here it is an introduction to the different event classes:

The WebHeartbeatEvent event can be raised periodically to give information about the status of the application (thread count, managed heap size, number of app domains, requests queued, requests executing, request rejected, information about the working set, etc).

The WebApplicationLifetimeEvent represents an important event in the application life cycle (application start, application shutdown, etc) and the information that can give you is very important, as you can analyze why your site is shutting down. For example, these are some constants that specify the shutdown reason:

ApplicationShutdownUnknown
ApplicationShutdownHostingEnvironment
ApplicationShutdownChangeInGlobalAsax
ApplicationShutdownConfigurationChange
ApplicationShutdownUnloadAppDomainCalled
ApplicationShutdownChangeInSecurityPolicyFile
ApplicationShutdownBinDirChangeOrDirectoryRename
ApplicationShutdownBrowsersDirChangeOrDirectoryRename
ApplicationShutdownCodeDirChangeOrDirectoryRename
ApplicationShutdownResourcesDirChangeOrDirectoryRename
ApplicationShutdownIdleTimeout
ApplicationShutdownPhysicalApplicationPathChanged
ApplicationShutdownHttpRuntimeClose
ApplicationShutdownInitializationError
ApplicationShutdownMaxRecompilationsReached

The WebRequestEvent event is raised at every request and contains information about the IP of the user that makes the request, URL of the request, etc.

The WebBaseErrorEvent class is the base class for all events that report error conditions. The WebErrorEvent event is raise when configuration or code problems arise (for example, when the code throws an unhandled exception). The WebRequestErrorEvent event is raised when there is an error with a request (for example, a deserialization error in the ObjectStateFormatter).

The WebAuditEvent class is the base class for success (WebSuccessAuditEvent) or failure (WebFailureAuditEvent) of security related operations. When an user try to log in the web application, a WebAuthenticationSuccessAuditEvent WebAuthenticationFailureAuditEvent if the login process completed successfully or not. If the view state has been altered, the WebViewStateFailureAuditEvent will be raised.

The default event mappings are (extracted from the global web.config):

<eventMappings>

  <clear />

  <add name="All Events" type="System.Web.Management.WebBaseEvent,System.Web" startEventCode="0" endEventCode="2147483647" />

  <add name="Heartbeats" type="System.Web.Management.WebHeartbeatEvent,System.Web " startEventCode="0" endEventCode="2147483647" />

  <add name="Application Lifetime Events" type="System.Web.Management.WebApplicationLifetimeEvent,System.Web " startEventCode="0" endEventCode="2147483647" />

  <add name="Request Processing Events" type="System.Web.Management.WebRequestEvent,System.Web " startEventCode="0" endEventCode="2147483647" />

  <add name="All Errors" type="System.Web.Management.WebBaseErrorEvent,System.Web " startEventCode="0" endEventCode="2147483647" />

  <add name="Infrastructure Errors" type="System.Web.Management.WebErrorEvent,System.Web " startEventCode="0" endEventCode="2147483647" />

  <add name="Request Processing Errors" type="System.Web.Management.WebRequestErrorEvent,System.Web " startEventCode="0" endEventCode="2147483647" />

  <add name="All Audits" type="System.Web.Management.WebAuditEvent,System.Web " startEventCode="0" endEventCode="2147483647" />

  <add name="Failure Audits" type="System.Web.Management.WebFailureAuditEvent,System.Web " startEventCode="0" endEventCode="2147483647" />

  <add name="Success Audits" type="System.Web.Management.WebSuccessAuditEvent,System.Web " startEventCode="0" endEventCode="2147483647" />

</eventMappings>

The name attribute is used to associate a rule with a provider and a group of events as we’ll see in the rules section. The type specifies a class of event that is mapped to the event group. Note that all derived classes are also mapped by the same event group.

The startEventCode and the endEventCode attributes are used to specify a range of event codes. The event code is also saved with the event and helps in the identification of the event.

As a summary, the default web.config has this mapping:

All Events -> WebBaseEvent
Heartbeats -> WebHeartbeatEvent
Application Lifetime Events -> WebApplicationLifetimeEvent
Request Processing Events -> WebRequestEvent
All Errors -> WebBaseErrorEvent
Request Processing Errors -> WebRequestErrorEvent
All Audits -> WebAuditEvent
Failure Audits -> WebFailureAuditEvent
Success Audits -> WebSuccessAuditEvent

Note that the constructor for these events is protected so you can’t create instances of the predefined events. Instead you should create your custom event inheriting from the appropriate event class.

Rules:

This configuration subsection is where all the associations and entities seen earlier take place.

The default configuration for the rules is (extracted from the global web.config):

<rules>

  <clear />

  <add name="All Errors Default" eventName="All Errors" provider="EventLogProvider" profile="Default" minInstances="1" maxLimit="Infinite" minInterval="00:01:00" custom="" />

  <add name="Failure Audits Default" eventName="Failure Audits" provider="EventLogProvider" profile="Default" minInstances="1" maxLimit="Infinite" minInterval="00:01:00" custom="" />

</rules>

The attributes for each rule are:
 * name: a string representing the name of the rule.
 * eventName: associates an event group with this rule.
 * provider: the provider to use to log the events generated of the eventName group.
 * profile: associates a profile with this rule (this isn’t required).
 * minInstances, maxLimit, minInterval and custom: have the same meaning than in the profile configuration subsection, but if you set its value, these settings override the settings of the profile.

For example, the first rule is called “All Errors Default”, and captures all events from the “All Errors” group, that is, all events derived from WebBaseErrorEvent, to the EventLog provider. The events are logged starting with the first event, but only the first event is saved if there are similar events in the same minute.

The second rule (called “Failure Audits Default”) saves events from the “Failure Audits” event group (events derived from WebFailureAuditEvent, that gets triggered in an unsuccessful login operation) to the EventLog provider, with the same profile properties as the previous rule.

Note that minInstances, maxLimit, minInterval and custom are redundant here because the Default profile has the same attributes.

Example of use:

To use the SqlWebEventProvider in our own application we have to create the necessary tables and stored procedures. One way is to use the aspnet_regsql.exe application. If we have direct access to the server (remote connections are allowed) we can use this:

aspnet_regsql -S MyServer -d MyDataBase -U MyUserName -P MyPassword -A w

If our server doesn't allow remote connections, we can generate the a script to run using:

aspnet_regsql -d MyDataBase -U MyUserName -P MyPassword  -A w -sqlexportonly addwebevents.sql

Another option to generate the required sql infrastructure if we're running in full trust is to execute this code:

System.Web.Management.SqlServices.Install("MyDatabase", System.Web.Management.SqlFeatures.SqlWebEventProvider, ConfigurationManager.ConnectionStrings["MyConnection"].ConnectionString);

 

After the required sql infrastructure has been created, you have to configure the health monitoring system using the web.config. An example of the configuration to log appliaction lifetime events and errors is:

    <healthMonitoring enabled="true" heartbeatInterval="0">

      <providers>

        <add name="MySqlWebEventProvider" type="System.Web.Management.SqlWebEventProvider,System.Web,Version=2.0.0.0, Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="MyConnection" maxEventDetailsLength="1073741823" buffer="true" bufferMode="Notification"/>

      </providers>

      <rules>

        <clear />

        <add name="All Errors Default" eventName="All Errors" provider="MySqlWebEventProvider" profile="Default" />       

        <add name="Application Lifetime Events Default" eventName="Application Lifetime Events" provider="MySqlWebEventProvider" profile="Default" />

      </rules>

    </healthMonitoring>

 

If you have used another event logging library like log4net or the enterprise library you may wonder if it is better to use them instead of the health monitoring system. My advice is that your project has only a web scenario and you don’t have to maintain legacy code that uses log4net or the enterprise library, just use the health monitoring system. Otherwise use log4net, the enterprise library or any other logging solutions that you want.

I think this is enough for an introduction to the health monitoring system. I may post more in depth information about it in a future if time permits.

Thursday, 05 October 2006 18:28:10 (Romance Daylight Time, UTC+02:00)  #    Comments [1]   ASP.NET  | 
Copyright © 2018 Manuel Abadia. All rights reserved.
DasBlog 'Portal' theme by Johnny Hughes.