Walkthrough: Listening for WMI Events in ASP.NET Health Monitoring

This walkthrough shows how to listen for Windows Management Instrumentation (WMI) events that have been mapped to ASP.NET health monitoring events. Tasks illustrated in this walkthrough include:

  • Building a console application that listens for health monitoring events.

  • Configuring a Web application to be monitored.

  • Testing the console application.

For more information about using WMI to deliver health monitoring events, see Using WMI to Deliver ASP.NET Health Monitoring Events.

Prerequisites

In order to complete this walkthrough, you will need:

  • Access to a server with Microsoft Internet Information Services (IIS) and the .NET Framework version 2.0 installed.

  • Sufficient permissions to be able to create an ASP.NET Web site on the server.

  • Permission to run the application with administrative privileges to access the Web events information.

ASP.NET Health Monitoring Process

The following list describes the main steps that occur during ASP.NET health monitoring if the delivery of event data is configured to be processed through WMI:

  1. ASP.NET raises a health event, according to the configuration settings.

  2. ASP.NET health monitoring, based on the configuration settings, dispatches the event to the WmiWebEventProvider provider.

  3. The WmiWebEventProvider provider, based on the information contained in the WMI Managed Object Format (MOF) file for ASP.NET (Aspnet.mof), passes the event information to the WMI system through an unmanaged call.

  4. Finally, WMI passes the relevant data to the custom application. This application uses the System.Management types to interoperate between the ASP.NET managed and the WMI unmanaged APIs.

The following illustration depicts this process.

ASP.NET health monitoring process using WMI

WMI Listener

Steps Involved in Using WMI to Listen for ASP.NET Health Monitoring Events

Standard steps for using WMI to listen for ASP.NET health monitoring events are as follows:

  1. Create and build a custom listener application. In this walkthrough, your listener application is a console application.

  2. Configure your Web application to allow the custom provider to process health events by enabling health monitoring and specifying a provider. In this walkthrough, your provider is the default WMI provider.

  3. Activate the listener on the server where your Web application runs. Because your listener is a console application, this means running your application from the command line.

  4. Access any page of the monitored Web site in a Web browser.

  5. Verify that the health events issued by the Web site are captured by the listener.

Creating the WMI Event Listener

A WMI event listener processes ASP.NET health events after they have been forwarded to WMI.

The code example in the following procedure is for a WMI event listener console application that accesses the WMI objects that are associated with ASP.NET health events. The following list describes the main steps performed by this application:

  • Get the name of the computer on which the listener and the Web application run.

  • Set the WMI path for the ASP.NET entities.

  • Create a managed object watcher as defined in the System.Management namespace.

  • Set the scope of events to watch to be equal to the previous WMI path.

  • Loop indefinitely to catch the WMI events.

To create a WMI event listener for ASP.NET health events

  1. Create a source file for a console application, and paste in the following code. This code listens for WMI events associated with ASP.NET health monitoring events on the local computer, which is the same computer where the monitored Web application runs.

    Imports System
    Imports System.Text
    Imports System.Management
    
    Namespace SamplesAspNet
    
        Class SampleWmiWebEventListener
            ' Displays event-related information.
    
            Public Shared Sub DisplayEventInformation(ByVal ev As ManagementBaseObject)
    
                ' This will hold the name of the 
                ' event class as defined in the 
                ' Aspnet.mof file.
                Dim eventTypeName As String
    
                ' Get the name of the WMI-raised event.
                eventTypeName = ev.ClassPath.ToString()
    
                ' Process the raised event.
                Select Case eventTypeName
                    ' Process the heartbeat event.  
                    Case "HeartBeatEvent"
                        Console.WriteLine("HeartBeat")
                        Console.WriteLine(vbTab + _
                        "Process: {0}", ev("ProcessName"))
                        Console.WriteLine(vbTab + "App: {0}", _
                        ev("ApplicationUrl"))
                        Console.WriteLine(vbTab + "WorkingSet: {0}", _
                        ev("WorkingSet"))
                        Console.WriteLine(vbTab + "Threads: {0}", _
                        ev("ThreadCount"))
                        Console.WriteLine(vbTab + "ManagedHeap: {0}", _
                        ev("ManagedHeapSize"))
                        Console.WriteLine(vbTab + "AppDomainCount: {0}", _
                        ev("AppDomainCount"))
    
                        ' Process the request error event. 
                    Case "RequestErrorEvent"
                        Console.WriteLine("Error")
                        Console.WriteLine("Url: {0}", _
                        ev("RequestUrl"))
                        Console.WriteLine("Path: {0}", _
                        ev("RequestPath"))
                        Console.WriteLine("Message: {0}", _
                        ev("EventMessage"))
                        Console.WriteLine("Stack: {0}", _
                        ev("StackTrace"))
                        Console.WriteLine("UserName: {0}", _
                        ev("UserName"))
                        Console.WriteLine("ThreadID: {0}", _
                        ev("ThreadAccountName"))
    
                        ' Process the application lifetime event. 
                    Case "ApplicationLifetimeEvent"
                        Console.WriteLine("App Lifetime Event {0}", _
                        ev("EventMessage"))
    
                        ' Handle events for which processing is not
                        ' provided.
                    Case Else
                        Console.WriteLine("ASP.NET Event {0}", _
                        ev("EventMessage"))
                End Select
    
            End Sub 'DisplayEventInformation .
    
            ' The main entry point for the application.
            Public Shared Sub Main(ByVal args() As String)
                ' Get the name of the computer on 
                ' which this program runs.
                ' Note that the monitored application must also run 
                ' on this computer.
                Dim machine As String = Environment.MachineName
    
                ' Define the Common Information Model (CIM) path 
                ' for WMI monitoring. 
                Dim path As String = _
                String.Format("\\{0}\root\aspnet", machine)
    
                ' Create a managed object watcher as 
                ' defined in System.Management.
                Dim query As String = "select * from BaseEvent"
                Dim watcher As New ManagementEventWatcher(query)
    
                ' Set the watcher options.
                Dim timeInterval As New TimeSpan(0, 1, 30)
                watcher.Options = _
                New EventWatcherOptions(Nothing, timeInterval, 1)
    
                ' Set the scope of the WMI events to 
                ' watch to be ASP.NET applications.
                watcher.Scope = _
                New ManagementScope(New ManagementPath(path))
    
                ' Set the console background.
                Console.BackgroundColor = ConsoleColor.Blue
                ' Set the foreground color.
                Console.ForegroundColor = ConsoleColor.Yellow
                ' Clear the console.
                Console.Clear()
    
                ' Loop indefinitely to catch the events.
                Console.WriteLine( _
                "Listener started. Enter CntlC to terminate.")
    
                While True
                    Try
                        ' Capture the WMI event related to 
                        ' the Web event.
                        Dim ev As ManagementBaseObject = _
                        watcher.WaitForNextEvent()
                        ' Display the Web event information.
                        DisplayEventInformation(ev)
    
                        ' Prompt the user.
                        Console.Beep()
    
                    Catch e As Exception
                        Console.WriteLine("Error: {0}", e)
                        Exit While
                    End Try
                End While
    
            End Sub 'Main 
    
        End Class 'SampleWmiWebEventListener 
    
    End Namespace
    
    using System;
    using System.Text;
    using System.Management;
    
    namespace SamplesAspNet
    {
        // Capture WMI events associated with 
        // ASP.NET health monitoring types. 
        class SampleWmiWebEventListener
        {
            // Displays event-related information.
            static void DisplayEventInformation(
                ManagementBaseObject ev)
            {
    
                // This will hold the name of the 
                // event class as defined in the 
                // Aspnet.mof file.
                string eventTypeName;
    
                // Get the name of the WMI-raised event.
                eventTypeName = ev.ClassPath.ToString();
    
                // Process the raised event.
                switch (eventTypeName)
                {
                    // Process the heartbeat event.  
                    case "HeartBeatEvent":
                        Console.WriteLine("HeartBeat");
                        Console.WriteLine("\tProcess: {0}",
                            ev["ProcessName"]);
                        Console.WriteLine("\tApp: {0}",
                            ev["ApplicationUrl"]);
                        Console.WriteLine("\tWorkingSet: {0}",
                            ev["WorkingSet"]);
                        Console.WriteLine("\tThreads: {0}",
                            ev["ThreadCount"]);
                        Console.WriteLine("\tManagedHeap: {0}",
                            ev["ManagedHeapSize"]);
                        Console.WriteLine("\tAppDomainCount: {0}",
                            ev["AppDomainCount"]);
                        break;
    
                    // Process the request error event. 
                    case "RequestErrorEvent":
                        Console.WriteLine("Error");
                        Console.WriteLine("Url: {0}",
                            ev["RequestUrl"]);
                        Console.WriteLine("Path: {0}",
                            ev["RequestPath"]);
                        Console.WriteLine("Message: {0}",
                            ev["EventMessage"]);
                        Console.WriteLine("Stack: {0}",
                            ev["StackTrace"]);
                        Console.WriteLine("UserName: {0}",
                            ev["UserName"]);
                        Console.WriteLine("ThreadID: {0}",
                            ev["ThreadAccountName"]);
                        break;
    
                    // Process the application lifetime event. 
                    case "ApplicationLifetimeEvent":
                        Console.WriteLine("App Lifetime Event {0}",
                            ev["EventMessage"]);
    
                        break;
    
                    // Handle events for which processing is not
                    // provided.
                    default:
                        Console.WriteLine("ASP.NET Event {0}",
                            ev["EventMessage"]);
                        break;
                }
            } // End DisplayEventInformation.
    
            // The main entry point for the application.
            static void Main(string[] args)
            {
                // Get the name of the computer on 
                // which this program runs.
                // Note that the monitored application must also run 
                // on this computer.
                string machine = Environment.MachineName;
    
                // Define the Common Information Model (CIM) path 
                // for WMI monitoring. 
                string path = String.Format("\\\\{0}\\root\\aspnet", machine);
    
                // Create a managed object watcher as 
                // defined in System.Management.
                string query = "select * from BaseEvent";
                ManagementEventWatcher watcher =
                    new ManagementEventWatcher(query);
    
                // Set the watcher options.
                TimeSpan timeInterval = new TimeSpan(0, 1, 30);
                watcher.Options =
                    new EventWatcherOptions(null,
                    timeInterval, 1);
    
                // Set the scope of the WMI events to 
                // watch to be ASP.NET applications.
                watcher.Scope =
                    new ManagementScope(new ManagementPath(path));
    
                // Set the console background.
                Console.BackgroundColor = ConsoleColor.Blue;
                // Set the foreground color.
                Console.ForegroundColor = ConsoleColor.Yellow;
                // Clear the console.
                Console.Clear();
    
                // Loop indefinitely to catch the events.
                Console.WriteLine(
                    "Listener started. Enter Cntl-C to terminate");
    
    
                while (true)
                {
                    try
                    {
                        // Capture the WMI event related to 
                        // the Web event.
                        ManagementBaseObject ev =
                            watcher.WaitForNextEvent();
                        // Display the Web event information.
                        DisplayEventInformation(ev);
    
                        // Prompt the user.
                        Console.Beep();
    
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("Error: {0}", e);
                        break;
                    }
                }
            }
        }
    }
    
  2. Build the console application. You might need to include a reference for the System.Management namespace.

Configuring the Application for WMI Events

The standard WmiWebEventProvider provider contains the logic to generate the WMI events associated with the ASP.NET health events.

To configure an ASP.NET application to use WMI to listen for ASP.NET health monitoring events

  1. Create or open a Web.config file at the root of your application.

    A basic Web.config file looks like the following code example.

    <?xml version="1.0"?>
    <configuration xmlns="https://schemas.microsoft.com/.NetConfiguration/v2.0">
        <appSettings/>
        <connectionStrings/>
        <system.web>
        </system.web>
    </configuration>
    
  2. Enable health monitoring by adding the following lines of code inside the system.web section.

            <healthMonitoring enabled="true">
            </healthMonitoring>
    
  3. Configure the application to use the WmiWebEventProvider provider to deliver health monitoring data by adding the following lines of code inside the healthMonitoring section. Note that the WmiWebEventProvider provider is already configured. To allow the processing of Web events, you just need to define a rule as follows.

               <rules>
                  <add 
                     name="Wmi Listener"
                     eventName="All Events" 
                     provider="WmiWebEventProvider" 
                     profile="Critical"/>
               </rules>
    

    The eventName attribute of the added rule allows for all the Web events to be dispatched to the WmiWebEventProvider provider.

Testing your Listener Application

After you have created and built your listener application and configured a Web site to enable health monitoring through WMI events, you can verify that health events are captured by running your listener application while you request a page from your Web site.

To test your listener console application

  1. Create an ASP.NET page in the same Web application that you configured to enable health monitoring.

  2. From the command line, run your listener application.

    The command window changes color to a blue background with the following yellow text displayed:

    Listener started. Enter CntlC to terminate
    
  3. In a Web browser, request the page from your Web application.

    Before the page finishes rendering, the command window that is running your listener application displays the following text:

    ASP.NET Event URL authorization succeeded for the request.
    ASP.NET Event File authorization succeeded for the request.
    

    This verifies that your listener has caught the URL authorization event and the file authorization event from ASP.NET.

Next Steps

The WMI listener shown is a simple console application, but it illustrates the fundamental steps to build a WMI listener and configure an application to dispatch health events. From this start, you can begin to explore additional ways to monitor your Web applications. Suggestions for more exploration include:

  • Investigate the use of Windows applications to collect WMI events.

  • Explore the use of more complex processing capabilities based on the type of event.

  • Learn about WMI and how the .NET Framework integrates its functionality. For more information, see System.Management, System.Management.Instrumentation.

  • Search the MSDN library for Windows Management Instrumentation (WMI) and Managed Object Format (MOF).

See Also

Reference

healthMonitoring Element (ASP.NET Settings Schema)

WmiWebEventProvider

System.Management

System.Management.Instrumentation

Other Resources

Using WMI to Deliver ASP.NET Health Monitoring Events