演练:侦听 ASP.NET 运行状况监视过程中的 WMI 事件

更新:2007 年 11 月

本演练说明如何侦听已映射到 ASP.NET 运行状况监视事件的 Windows Management Instrumentation (WMI) 事件。本演练中阐释的任务包括:

  • 生成用于侦听运行状况监视事件的控制台应用程序。

  • 配置要监视的 Web 应用程序。

  • 测试控制台应用程序。

有关使用 WMI 发送运行状况监视事件的更多信息,请参见使用 WMI 传送 ASP.NET 运行状况监视事件

先决条件

若要完成本演练,您需要:

  • 对已安装 Microsoft Internet 信息服务 (IIS) 和 .NET Framework 版本 2.0 的服务器的访问权限。

  • 能够在服务器上创建 ASP.NET 网站的足够权限。

  • 具有以管理员特权运行应用程序以访问 Web 事件信息的权限。

ASP.NET 运行状况监视过程

下面的列表描述了当将事件数据的发送配置为通过 WMI 处理时在 ASP.NET 运行状况监视过程中发生的主要步骤:

  1. ASP.NET 根据配置设置引发一个运行状况事件。

  2. ASP.NET 运行状况监视根据配置设置将该事件调度到 WmiWebEventProvider 提供程序。

  3. WmiWebEventProvider 提供程序根据 ASP.NET 使用的 WMI 托管对象格式 (MOF) 文件 (Aspnet.mof) 中包含的信息通过一个非托管调用将事件信息传递到 WMI 系统。

  4. 最后,WMI 将相关的数据传递到自定义应用程序。此应用程序使用 System.Management 类型在 ASP.NET 托管 API 和 WMI 非托管 API 之间交互操作。

下图描绘了此过程。

使用 WMI 的 ASP.NET 运行状况监视过程
WMI 侦听器

使用 WMI 侦听 ASP.NET 运行状况监视事件时所涉及的步骤

使用 WMI 侦听 ASP.NET 运行状况监视事件的标准步骤如下:

  1. 创建和生成自定义侦听器应用程序。在本演练中,侦听器应用程序是一个控制台应用程序。

  2. 通过启用运行状况监视和指定提供程序将 Web 应用程序配置为允许自定义提供程序处理运行状况事件。在本演练中,提供程序是默认的 WMI 提供程序。

  3. 在运行 Web 应用程序的服务器上激活侦听器。由于侦听器是控制台应用程序,因此这意味着需要从命令行运行应用程序。

  4. 在 Web 浏览器中访问受监视网站的任何页面。

  5. 验证网站发出的运行状况事件是否由侦听器捕获。

创建 WMI 事件侦听器

当 ASP.NET 运行状况事件转发到 WMI 之后,WMI 事件侦听器将处理这些事件。

以下过程中的代码示例针对的是访问与 ASP.NET 运行状况事件相关联的 WMI 对象的 WMI 事件侦听器控制台应用程序。下面的列表描述此应用程序执行的主要步骤:

  • 获取运行侦听器和 Web 应用程序的计算机的名称。

  • 为 ASP.NET 实体设置 WMI 路径。

  • 创建在 System.Management 命名空间中定义的托管对象观察程序。

  • 将要观察的事件范围设置为前一个 WMI 路径。

  • 无限循环以捕获 WMI 事件。

为 ASP.NET 运行状况事件创建 WMI 事件侦听器

  1. 为控制台应用程序创建一个源文件,并将以下代码粘贴到该文件中。这些代码侦听与本地计算机上的 ASP.NET 运行状况监视事件相关联的 WMI 事件,在该计算机上同时运行着受监视的 Web 应用程序。

    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. 生成控制台应用程序。您可能需要包含对 System.Management 命名空间的引用。

为 WMI 事件配置应用程序

标准的 WmiWebEventProvider 提供程序包含用于生成与 ASP.NET 运行状况事件相关联的 WMI 事件的逻辑。

将 ASP.NET 应用程序配置为使用 WMI 侦听 ASP.NET 运行状况监视事件

  1. 在应用程序的根目录下创建或打开 Web.config 文件。

    基本的 Web.config 文件看起来类似于下面的代码示例。

    <?xml version="1.0"?>
    <configuration xmlns="https://schemas.microsoft.com/.NetConfiguration/v2.0">
        <appSettings/>
        <connectionStrings/>
        <system.web>
        </system.web>
    </configuration>
    
  2. 通过在 system.web 节中添加下面几行代码启用运行状况监视。

            <healthMonitoring enabled="true">
            </healthMonitoring>
    
  3. 通过在 healthMonitoring 节中添加下面几行代码将应用程序配置为使用 WmiWebEventProvider 提供程序发送运行状况监视数据。注意,WmiWebEventProvider 提供程序已经配置。若要允许处理 Web 事件,只需按如下方式定义一个规则。

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

    所添加的规则的 eventName 属性允许将所有 Web 事件调度到 WmiWebEventProvider 提供程序。

测试侦听器应用程序

在创建和生成侦听器应用程序并将网站配置为通过 WMI 事件启用运行状况监视之后,您可以在从网站请求页面时通过运行侦听器应用程序验证是否已捕获运行状况事件。

测试侦听器控制台应用程序

  1. 在已配置为启用运行状况监视的同一个应用程序中创建一个 ASP.NET 网页。

  2. 从命令行运行侦听器应用程序。

    命令窗口的背景色将变为蓝色,同时显示下面的黄色文本:

    Listener started. Enter CntlC to terminate
    
  3. 在 Web 浏览器中,从 Web 应用程序请求页面。

    在页面完成呈现之前,运行侦听器应用程序的命令窗口会显示以下文本:

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

    这证明侦听器已从 ASP.NET 捕获 URL 授权事件和文件授权事件。

后续步骤

所显示的 WMI 侦听器是一个简单的控制台应用程序,但是它阐释了用于生成 WMI 侦听器和配置应用程序调度运行状况事件的基本步骤。自此,您可以开始研究其他的方法来监视 Web 应用程序。建议研究的其他方面包括:

  • 研究如何使用 Windows 应用程序收集 WMI 事件。

  • 研究如何使用更为复杂的基于事件类型的处理能力。

  • 了解 WMI 以及 .NET Framework 集成其功能的方式。有关更多信息,请参见 System.ManagementSystem.Management.Instrumentation

  • MSDN library 中搜索 Windows Management Instrumentation (WMI) 和托管对象格式 (MOF)。

请参见

参考

healthMonitoring 元素(ASP.NET 设置架构)

WmiWebEventProvider

System.Management

System.Management.Instrumentation

其他资源

使用 WMI 传送 ASP.NET 运行状况监视事件