Windows 事件追蹤 (ETW) 是 Windows 內建的高速追蹤設施。 ETW 使用在作業系統核心中實作的緩衝和記錄機制,為使用者模式(應用程式)和核心模式元件(驅動程式)所引發的事件提供基礎結構。 ETW 可用於系統和應用程式診斷、疑難解答和效能監視。
在過去,追蹤是用來診斷硬體和應用程式中非預期的行為。 不過,最近,管理及監視系統穩定性和效能的需求不斷增加,以滿足商務需求。 因此,開發和生產環境中的效能分析已成為運算界的重要部分。 相較於失敗和錯誤,效能相關問題很難偵測和診斷,因為它們通常相依於組態和工作負載。 在生產環境中追蹤可提供寶貴的數據來偵測根本原因效能相關問題,以及容量規劃和評估。
ETW 機制可讓您動態控制追蹤會話,讓您能夠在生產環境中擷取詳細的追蹤,而不需要重新啟動系統或重新啟動應用程式。
下一節示範如何使用 ETW 來執行精確的效能測量和分析:
- 內核模式驅動程式程式代碼
- 傳統桌面程序和服務
- Microsoft市集應用程式 (C#)
概觀
下列清單顯示 ETW 的一些有益特性:
- 強固
-
它提供有效率的緩衝和記錄機制。 追蹤緩衝區是由核心所管理。 透過 ETW 追蹤不受應用程式當機和停止響應的影響。 如果系統失敗,記憶體轉儲檔案中可以存取未儲存的事件。
- 動態
-
追蹤會話可以動態啟動、停止、重新設定及暫停,而不需要重新啟動系統或應用程式。 ETW 提供多種模式以符合各種需求。
- 內建至 Windows
-
除了控制器應用程式之外,您不需要其他工具。 Windows 有一些收件匣控制器以及取用者應用程式。
- 輕
-
由於歷程記錄追蹤和儲存的記錄檔的額外負荷已高度優化,因此不會影響應用程式或系統效能。 記錄機制會使用由個別寫入器線程寫入磁碟的核心模式緩衝區,讓追蹤的額外負荷受到限制。
在 Windows 2000 之前,只有基本的文字型追蹤機制可在 Windows 中使用: DbgPrint() 和 DebugPrint() API。 它們需要調試程式,而且通常無法動態控制。 Windows 追蹤機制會隨著時間而演進;目前有四種不同的追蹤機制可供使用。 ETW 和事件記錄 API 集合已合併至 Windows Vista 中的整合事件記錄 API 集合,可為使用者提供引發事件的統一機制。
事件有三種類型:
Windows 軟體追蹤預處理器 (WPP) 和傳統 ETW
Managed 物件格式 (MOF):MOF 是描述 WMI 物件並啟用和譯碼事件的一種方式。
指令清單型:Windows Vista 中引進了以 XML 為基礎的統一追蹤定義。 XML 檔案包含提供者寫入之事件的元素。 如需詳細資訊,請參閱 撰寫檢測指令清單。
注意
本節中的指引僅著重於以指令清單為基礎的事件檢測。
ETW 具有下列重要特性:
開發人員可以根據預期的使用方式來選擇正確的實作集(例如 Printf,例如 WPP 實作,很容易新增以進行偵錯目的事件)。
基礎結構會管理常用的資訊,例如時間戳、函式名稱和原始程式檔行號。
相同的實作用於使用者模式應用程式和核心模式元件。
ETW 可在損毀傾印和即時偵錯中存取。
ETW 可以重新導向至核心調試程式,以取得實時檢視。
ETW 具有實時檢視。
記錄檔會儲存在二進位記錄檔中(ETL 檔案)。
ETW 支援多個進程記錄。
ETW 的輸送量很高。
記錄檔可以在另一部計算機上檢視。
ETW 支援連續記錄和監視的循環緩衝處理。
ETW 可以根據目標物件分組為其中一個通道。
ETW 架構
ETW 中有四個主要元件:提供者、工作階段、控制器和取用者。
提供者
提供者是產生事件的已檢測元件。 提供者可以是使用者模式應用程式、核心模式驅動程式或 Windows 核心本身。 除了固定事件數據(標頭),事件還可以攜帶用戶數據。
事件 是以事件 為基礎的數據表示法。 數據可用於深入分析。 事件也可以用來產生計數器。 計數器會提供以樣本為基礎的數據檢視。 它們通常包含一組小型數據來顯示目前狀態,例如每秒 I/O 位元組和每秒中斷。
提供者必須向 ETW 註冊,並藉由呼叫 ETW 記錄 API 來傳送事件。 提供者註冊啟用和停用通知的回呼函式,以便動態啟用和停用追蹤。
會議
ETW 會話基礎結構可作為中繼代理程式,將事件從一或多個提供者轉送給取用者。 會話是一個核心物件,可將事件收集到核心緩衝區,並將其傳送至指定的檔案或即時取用者進程。 多個提供者可以對應至單一會話,讓用戶能夠從多個來源收集數據。
控制器
控制器會啟動、停止或更新追蹤會話。 會話是追蹤的單位。 提供者會對應至特定會話(或啟用)。 控制器會啟用和停用提供者,以便他們開始將事件傳送至 ETW。 您可以使用Microsoft所提供的工具叫用控制器功能,也可以撰寫自己的應用程式。
Logman.exe是內建控制器應用程式。 Windows Performance Toolkit 中的 Windows Performance Recorder (WPR) 是建議的控制器程式。
消費者
取 用者 是應用程式,可讀取記錄的追蹤檔案(ETL 檔案)或即時擷取使用中追蹤會話中的事件,並處理事件。 事件檢視器 和資源監視器是內建 ETW 取用者應用程式。
Windows Performance Toolkit 中的 Windows 效能分析器 (WPA) 是建議的取用者程式。
實作 ETW 檢測
規劃您的檢測
決定在您的程式代碼中記錄 ETW 事件的位置。 此記錄應該與重要的使用者案例或您想要測量、分析及最終改善的使用案例相互關聯。 下列清單顯示可偵測專案的一些範例:
- 狀態變更
- 重大作業的開始/結束
- 資源建立/刪除
- 與效能或可靠性相關的其他事件
- 偵錯事件
建立指令清單檔案並實作您的提供者
指令清單型 ETW 事件可以使用稱為事件指令清單的 XML 檔案,在使用者模式應用程式中實作,包括服務,以及在驅動程式等核心模式元件中實作。 如需詳細資訊,請參閱 事件追蹤函式。
事件指令清單分成下列各節:
- 提供者定義: < 提供者 >
-
包含您要建立之提供者的名稱和 GUID,以及所檢測的二進位檔位置(最終包含 ETW 架構所需的檢測資源)。
- 事件承載: <範本>
-
包含數據型別的定義,這些數據類型將包含在事件中作為承載。 可用的類型包括:
-
帶正負號和不帶正負號的 8 位、16 位、32 位和 64 位整數
-
ANSI 和 Unicode 字串
-
浮點數和雙精度浮點數
-
布爾值、二進位、GUID、指標、FILETIME、SYSTEMTIME、SID 和 HexInt32
-
- 靜態事件數據
-
用來協助解譯、排序和分組事件。
- 定義正在檢測的作業名稱(或工作)。
- 定義您想要為事件建立的作業類型,例如 Start 事件、用於及時分隔作業的 Stop 事件、記錄偵錯數據的資訊事件等等。
-
事件定義: <事件>
將承載和靜態數據系結在一起。 您的程式代碼會發出事件,如本節所列的專案所定義。
以下是事件指令清單的範例:
<provider
guid="{3877cf22-0702-4dfc-965e-7fdc7780cd74}"
name="MyEventProvider"
symbol="MY_EVENT_PROVIDER"
messageFileName="%temp%\MyProviderBinary.exe"
resourceFileName="%temp%\MyProviderBinary.exe“
>
<templates>
<template tid="T_MyProvider_1">
<data inType="win:Int32" name="Operation Id" />
<data inType="win:Int32" name="Memory Allocated (MB)" />
</template>
</templates>
<opcodes>
<opcode name="DebugInfo" symbol="_DebugInfo" value="10"/>
</opcodes>
<tasks>
<task name="OpMemAllocation" symbol="OpMemAllocation_Task" value="1“
eventGUID="{87ebca33-bf25-442c-9256-82ba484586e8}"/>
</tasks>
<events>
<event symbol="DebugInfo" template="T_MyProvider_1" value="200"
task="OpMemAllocation" opcode="DebugInfo" />
</events>
若要撰寫指令清單檔案,您可以使用:
平臺 SDK 中提供的指令清單產生器 (ECManGen.exe)
Visual Studio (Eventman.xsd),可在平臺 SDK 中使用
編譯事件指令清單
下一個步驟是使用 平臺 SDK 中提供的訊息編譯程式工具 (mc.exe)編譯指令清單。 此工具會產生一些檢測、編譯及建置已檢測程序代碼所需的檔案:
- ManifestFileName.h
- 包含要用於程式代碼的事件描述項。
- ManifestFileName.rc
- 資源編譯程式腳本。
- MSG00001.bin
- 語言資源。
- ManifestFileNameTEMP.bin
- 範本資源(提供者和元數據)。
若要編譯使用者模式程序代碼,請輸入下列命令:
mc.exe -um [ManifestFileName]
若要編譯核心模式程序代碼,請輸入下列命令:
mc.exe -km [ManifestFileName]
若要編譯 Managed 或 JavaScript 程式代碼,請輸入下列命令:
mc.exe -cs [ManifestFileName]
mc.exe -css [ManifestFileName]
mc.exe -generateProjections [ManifestFileName]
更新您的程式碼
下一個步驟是將檢測新增至您的程序代碼。 執行 Visual Studio、新增訊息編譯程式所產生的頭檔,並將資源檔建置至您的程式。
在標頭中搜尋下列內容,以尋找程式代碼中要呼叫的巨集(或類別方法):
EventRegister<YourProviderName>
用來註冊您的提供者(在應用程式啟動時)。
EventUnregister<YourProviderName>
用來取消註冊您的提供者(在應用程式完成時)。
EventWrite
每個事件的一個巨集(或方法)定義於指令清單中(事件>節點中<)。
正確檢測程式代碼之後,您可以建置二進位檔。
針對驅動程式,請檢閱 MSDN 上可用的 EventDrv 範例。 使用 ETW 核心模式 EtwRegister 函式,將驅動程式註冊為事件提供者:
在建立和初始化裝置物件的程式代碼之後,於 DriverEntry 例程中新增此函式。
比對 EtwRegister 函式的呼叫,並在驅動程式的 Unload 例程中呼叫 EtwUnregister。
記錄和視覺化事件
在您擁有正確檢測的元件之後,就可以開始在測試系統上記錄事件。 您必須先使用收件匣工具 wevtutil 註冊提供者,以準備該系統以進行記錄。
將元件複製到 resourceFileName 屬性在指令清單中指定的位置:
xcopy /y MyProviderBinary.exe %temp%
註冊提供者:
wevtutil um etwmanifest.man
wetvutil im etwmanifest.man確認提供者是否可見:
logman 查詢提供者
您的提供者名稱/GUID 會出現在清單中。
請注意,事件元數據會儲存在已檢測的二進位檔中,而不是儲存在指令清單檔中。 使用 wevtutil 在電腦上安裝指令清單,會將連結放入登錄中,將提供者 GUID 連接到包含事件元數據的二進位檔。 該二進位檔的名稱和路徑取自提供的指令清單檔。 之後,您可以捨棄指令清單檔案。
因為它位於您用來譯碼的計算機上,所以包含事件元數據的二進位檔也必須可供存取和載入。 WPR/xperf 藉由在追蹤中插入元數據,讓進程更具可移植性。
在此系統上正確安裝提供者之後,您可以啟動追蹤會話,將元件的事件收集到 ETL 檔案中。 您可以使用 Windows Performance Recorder (WPR) 或 Xperf,這是 Windows Performance Toolkit 中可用的命令行工具:
開始追蹤:
xperf -start MySession -on MyEventProvider -f MySession.etl
在該命令行中, -start 會提供事件收集會話的名稱,而 -on 會告知 ETW 您想要在此會話中從提供者收集事件。 (可以有多個 -on 自變數。
執行您的工作負載。
停止追蹤:
xperf -stop MySession
擁有 ETL 檔案之後,您可以使用 Windows 效能分析器 工具開啟它,並使用一般事件圖形和數據表將事件可視化。