逐步解說:在 ASP.NET 健康監視中接聽 WMI 事件

更新:2007 年 11 月

這個逐步解說會示範如何接聽對應到 ASP.NET 健康監視事件的 Windows Management Instrumentation (WMI) 事件。逐步解說將說明的工作包括:

  • 建置接聽健康監視事件的主控台應用程式 (Console Application)。

  • 設定要監視的 Web 應用程式。

  • 測試主控台應用程式。

如需使用 WMI 傳遞健康監視事件的詳細資訊,請參閱使用 WMI 傳遞 ASP.NET 健康監視事件

必要條件

若要完成這個逐步解說,您必須要有:

  • 存取已安裝 Microsoft Internet Information Services (IIS) 和 .NET Framework 2.0 版的伺服器。

  • 可以在伺服器上建立 ASP.NET 網站的足夠使用權限。

  • 使用系統管理員權限執行應用程式,以存取 Web 事件資訊的使用權限。

ASP.NET 健康監視處理過程

下列清單描述將事件資料設定為傳遞透過 WMI 處理時 ASP.NET 健康監視期間發生的主要步驟:

  1. ASP.NET 會根據組態設定引發健康事件。

  2. ASP.NET 健康監視會基於組態設定,將事件分派至 WmiWebEventProvider 提供者 (Provider)。

  3. WmiWebEventProvider 提供者會根據 ASP.NET (Aspnet.mof) 之 WMI Managed 物件格式 (MOF) 檔案中包含的資訊,透過 Unmanaged 呼叫將事件資訊傳遞至 WMI 系統。

  4. 最後,WMI 會將相關資料傳遞至自訂應用程式。這個應用程式會使用 System.Management 類型,在 ASP.NET Managed 和 WMI Unmanaged API 間相互溝通。

下圖所描述的就是這個處理過程。

使用 WMI 的 ASP.NET 健康監視處理過程

使用 WMI 接聽 ASP.NET 健康監視事件的步驟

使用 WMI 接聽 ASP.NET 健康監視事件的標準步驟如下:

  1. 建立並建置自訂接聽應用程式。在這個逐步解說中,您的接聽應用程式是主控台應用程式。

  2. 藉由啟用健康監視並指定提供者,設定 Web 應用程式允許自訂提供者處理健康事件。在這個逐步解說中,您的提供者是預設 WMI 提供者。

  3. 在執行 Web 應用程式的伺服器上啟動接聽程式。因為您的接聽程式是主控台應用程式,所以這表示從命令列執行您的應用程式。

  4. 存取 Web 瀏覽器中受監視網站的任何網頁。

  5. 驗證由網站發出的健康事件是否由接聽程式擷取。

建立 WMI 事件接聽程式

在 ASP.NET 健康事件轉送至 WMI 之後,WMI 事件接聽程式會對事件進行處理。

下列程序中的程式碼範例用於WMI 事件接聽主控台應用程式,該應用程式會存取與 ASP.NET 健康事件關聯的 WMI 物件。下列清單描述這個應用程式所執行的主要步驟:

  • 取得執行接聽程式和 Web 應用程式之電腦的名稱。

  • 設定 ASP.NET 實體 (Entity) 的 WMI 路徑。

  • 建立 System.Management 命名空間中定義的 Managed 物件監看員。

  • 將要監看的事件範圍設為等同於先前的 WMI 路徑。

  • 以無窮迴圈攔截 WMI 事件。

若要建立 ASP.NET 健康事件的 WMI 事件接聽程式

  1. 建立主控台應用程式的原始程式檔 (Source File),並貼入下列程式碼。這個程式碼會接聽本機電腦 (Local Machine,執行受監視之 Web 應用程式的同一電腦) 上與 ASP.NET 健康監視事件關聯的 WMI 事件。

    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. 在設定用於啟用健康監視的同一個 Web 應用程式中建立 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) 和 Managed 物件格式 (MOF)。

請參閱

參考

healthMonitoring 項目 (ASP.NET 設定結構描述)

WmiWebEventProvider

System.Management

System.Management.Instrumentation

其他資源

使用 WMI 傳遞 ASP.NET 健康監視事件