收集及檢視 EventSource 追蹤
本文適用於:✔️.NET Core 3.1 和更新版本 ✔️ .NET Framework 4.5 和更新版本
使用者入門指南說明如何建立最少的 EventSource,並在追蹤檔案中收集事件。 本教學課程說明不同的工具如何設定在追蹤中收集哪些事件,然後檢視追蹤。
範例應用程式
您將會使用下列範例應用程式來產生本教學課程的事件。 編譯包含下列程式碼的 .NET 主控台應用程式:
using System.Diagnostics.Tracing;
namespace EventSourceDemo
{
public static class Program
{
public static void Main(string[] args)
{
DemoEventSource.Log.AppStarted("Hello World!", 12);
DemoEventSource.Log.DebugMessage("Got here");
DemoEventSource.Log.DebugMessage("finishing startup");
DemoEventSource.Log.RequestStart(3);
DemoEventSource.Log.RequestStop(3);
}
}
[EventSource(Name = "Demo")]
class DemoEventSource : EventSource
{
public static DemoEventSource Log { get; } = new DemoEventSource();
[Event(1, Keywords = Keywords.Startup)]
public void AppStarted(string message, int favoriteNumber) => WriteEvent(1, message, favoriteNumber);
[Event(2, Keywords = Keywords.Requests)]
public void RequestStart(int requestId) => WriteEvent(2, requestId);
[Event(3, Keywords = Keywords.Requests)]
public void RequestStop(int requestId) => WriteEvent(3, requestId);
[Event(4, Keywords = Keywords.Startup, Level = EventLevel.Verbose)]
public void DebugMessage(string message) => WriteEvent(4, message);
public class Keywords
{
public const EventKeywords Startup = (EventKeywords)0x0001;
public const EventKeywords Requests = (EventKeywords)0x0002;
}
}
}
設定要收集的事件
大部分的事件收集工具會使用這些組態選項來決定追蹤中應包含哪些事件:
- 提供者名稱 - 這是一或多個 EventSource 名稱的清單。 只有在此清單中 EventSources 上定義的事件才有資格包含。 若要從上述範例應用程式中的 DemoEventSource 類別收集事件,您必須在提供者名稱清單中包含 EventSource 名稱 "Demo"。
- 事件詳細程度層級 - 對於每個提供者,您可以定義詳細程度層級,而詳細程度高於該層級的事件將會從追蹤中排除。 如果您指定上述範例應用程式中的 "Demo" 提供者應該在資訊詳細程度層級收集,則會排除 DebugMessage 事件,因為其具有較高的層級。 指定 EventLevel LogAlways (0) 是一個特殊案例,表示應該包含任何詳細程度層級的事件。
- 事件關鍵字 - 對於每個提供者,您可以定義一組關鍵字,而且只會包含至少以其中一個關鍵字標記的事件。 在上述範例應用程式中,如果您指定 Startup 關鍵字,則只會包含 AppStarted 和 DebugMessage 事件。 如果未指定關鍵字,這是特殊案例,表示應該包含具有任何關鍵字的事件。
描述提供者組態的慣例
雖然每個工具都會決定自己用來設定追蹤組態的使用者介面,但許多工具在將組態指定為文字字串時會使用一般慣例。 提供者清單會指定為分號分隔清單,而清單中的每個提供者元素是由名稱、關鍵字和以冒號分隔的層級所組成。 例如,"Demo:3:5" 會使用關鍵字位元遮罩 3 來識別名為 "Demo" 的 EventSource (Startup
位元和 Requests
位元),以及 EventLevel 5,這是 Verbose
。 如果不需要層級或關鍵字篩選,許多工具也可讓您省略層級和關鍵字。 例如,"Demo::5" 只會進行層級型篩選,"Demo:3" 只會進行關鍵字型篩選,"Demo" 則不會進行關鍵字或層級篩選。
Visual Studio
Visual Studio 分析工具同時支援收集和檢視追蹤。 也可以檢視其他工具事先收集的追蹤,例如 dotnet-trace。
收集追蹤
大部分的 Visual Studio 分析工具都使用為特定用途提供服務的一組預先定義事件,例如分析 CPU 使用量或配置。 若要使用自訂事件收集追蹤,您將會使用事件檢視器工具。
若要在 Visual Studio 中開啟效能分析工具,請選取 Alt+F2。
選取 [事件檢視器] 核取方塊。
選取 [事件檢視器] 右側的小齒輪圖示,以開啟設定視窗。
在下表的 [其他提供者] 中,按一下 [已啟用] 核取方塊,然後輸入提供者名稱、關鍵字和層級,為您想要設定的每個提供者新增一個資料列。 您不需要輸入提供者 GUID;其會自動計算。
選取 [確定] 以確認組態設定。
選取 [開始] 開始執行應用程式並收集記錄。
選取 [停止收集] 或結束應用程式以停止收集記錄並顯示收集的資料。
檢視追蹤
Visual Studio 可以檢視本身所收集的追蹤,也可以檢視在其他工具中收集的追蹤。 若要檢視來自其他工具的追蹤,請使用 [檔案] > [開啟],然後在檔案選擇器中選取追蹤檔案。 Visual Studio 分析工具支援 .etl 檔案 (ETW 的標準格式)、.nettrace 檔案 (EventPipe 的標準格式),以及 .diagsession 檔案 (Visual Studio 的標準格式)。 如需在 Visual Studio 中使用追蹤檔案的詳細資訊,請參閱 Visual Studio 文件。
注意
Visual Studio 會自動從 ETW 或 EventPipe 收集某些事件,即使未明確設定也一樣。 如果您在 [提供者名稱] 或 [事件名稱] 資料行中看到無法辨識的事件,而且想要篩選,請使用右邊的篩選圖示,只選取您想要檢視的事件。
PerfView
PerfView 是由 .NET 小組所建立的效能工具,可收集和檢視 ETW 追蹤。 也可以檢視其他工具以各種格式收集的追蹤檔案。 在本教學課程中,您將會收集示範應用程式的 ETW 追蹤,然後在 PerfView 的事件檢視器中檢查收集的事件。
收集追蹤
從版本頁面下載 PerfView。 本教學課程是使用 PerfView 2.0.76 版完成,但任何最新版本應該都能夠運作。
以系統管理員權限啟動 PerfView.exe。
注意
ETW 追蹤集合一律需要系統管理員權限,不過如果您只使用 PerfView 來檢視預先存在的追蹤,則不需要任何特殊權限。
從 [收集] 功能表中,選取 [執行]。 這會開啟新的對話方塊,您要在其中輸入示範應用程式的路徑。
若要設定收集哪些事件,請展開對話方塊底部的 [進階選項]。 在 [其他提供者] 文字方塊中,使用先前所述的傳統文字格式輸入提供者。 在此案例中,您會輸入 "Demo:1:4",這表示關鍵字位元 1 (
Startup
事件),和詳細程度 4 (Informational
)。若要啟動應用程式並開始收集追蹤,請選取 [執行命令] 按鈕。 當應用程式結束時,追蹤 PerfViewData.etl 會儲存在目前的目錄中。
檢視追蹤
在左上方的主視窗下拉式文字方塊中,選取包含追蹤檔案的目錄。 然後按兩下下方樹狀檢視中的追蹤檔案。
若要顯示 [事件檢視器],請按兩下追蹤檔案下方樹狀檢視中顯示的 [事件] 項目。
追蹤中的所有事件型別都會顯示在左側的清單中。 按兩下事件型別,例如 Demo\AppStarted,在資料表右側顯示該型別的所有事件。
深入了解
若要深入了解如何使用 PerfView,請參閱 PerfView 影片教學課程。
dotnet-trace
dotnet-trace 是一種跨平台命令列工具,可使用 EventPipe 追蹤從 .NET Core 應用程式收集追蹤。 不支援檢視追蹤資料,但其他工具可以檢視其所收集的追蹤,例如 PerfView 或 Visual Studio。 dotnet-trace 也支援將其預設 .nettrace 格式追蹤轉換為其他格式,例如 Chromium 或 Speedscope。
收集追蹤
下載並安裝 dotnet-trace。
在命令列上,執行 dotnet-trace collect 命令:
E:\temp\EventSourceDemo\bin\Debug\net6.0>dotnet-trace collect --providers Demo:1:4 -- EventSourceDemo.exe
這麼做應該會顯示類似於以下的輸出:
E:\temp\EventSourceDemo\bin\Debug\net6.0> dotnet-trace collect --providers Demo:1:4 -- EventSourceDemo.exe Provider Name Keywords Level Enabled By Demo 0x0000000000000001 Informational(4) --providers Launching: EventSourceDemo.exe Process : E:\temp\EventSourceDemo\bin\Debug\net6.0\EventSourceDemo.exe Output File : E:\temp\EventSourceDemo\bin\Debug\net6.0\EventSourceDemo.exe_20220317_021512.nettrace [00:00:00:00] Recording trace 0.00 (B) Press <Enter> or <Ctrl+C> to exit... Trace completed.
dotnet-trace 會使用傳統文字格式來描述
--providers
引數中的提供者組態。 如需如何使用 dotnet-trace 取得追蹤的詳細資訊,請參閱 dotnet-trace 文件。
EventListener
System.Diagnostics.Tracing.EventListener 是一種 .NET API,可用來從程序中接收由 System.Diagnostics.Tracing.EventSource 產生的事件回呼。 此 API 可用來建立自訂記錄工具,或分析記憶體中的事件,而不需要進行序列化。
若要使用 EventListener
,請宣告衍生自 EventListener
的型別,叫用 EnableEvents 以訂閱任何感興趣的 EventSource 的事件,並覆寫 OnEventWritten ,每當有新的事件可用時就會呼叫。 覆寫 OnEventSourceCreated 對於探索哪些 EventSource 物件存在通常很有用,但這並非必要項目。 以下是在收到訊息時列印至主控台的範例 EventListener
實作:
將此程式碼新增至示範應用程式。
class ConsoleWriterEventListener : EventListener { protected override void OnEventSourceCreated(EventSource eventSource) { if(eventSource.Name == "Demo") { EnableEvents(eventSource, EventLevel.Informational); } } protected override void OnEventWritten(EventWrittenEventArgs eventData) { Console.WriteLine(eventData.TimeStamp + " " + eventData.EventName); } }
修改
Main
方法以建立新接聽程式的執行個體。public static void Main(string[] args) { ConsoleWriterEventListener listener = new ConsoleWriterEventListener(); DemoEventSource.Log.AppStarted("Hello World!", 12); DemoEventSource.Log.DebugMessage("Got here"); DemoEventSource.Log.DebugMessage("finishing startup"); DemoEventSource.Log.RequestStart(3); DemoEventSource.Log.RequestStop(3); }
建置並執行應用程式。 先前沒有輸出,但現在會將事件寫入主控台:
3/24/2022 9:23:35 AM AppStarted 3/24/2022 9:23:35 AM RequestStart 3/24/2022 9:23:35 AM RequestStop