EventPipe

EventPipe 是執行階段元件,可用來收集追蹤資料,類似於 ETW 或 LTTng。 EventPipe 的目標是讓 .NET 開發人員能輕鬆地追蹤其 .NET 應用程式,而不需要依賴平台專用的 OS 原生元件,例如 ETW 或 LTTng。

EventPipe 是許多診斷工具背後的機制,可用於取用執行階段所發出的事件,以及以 EventSource 撰寫的自訂事件。

本文是 EventPipe 的大略概觀。 其描述使用 EventPipe 的時機和方式,以及如何將其設定為最符合您的需求。

EventPipe 基本概念

EventPipe 會彙總執行階段元件所發出的事件,例如 Just-In-Time 編譯器或記憶體回收行程,以及從程式庫和使用者程式碼中 EventSource 執行個體所撰寫的事件。

事件接著會以 .nettrace 檔案格式序列化,並可直接寫入檔案,或透過診斷連接埠串流處理,以供在處理序外部取用。

若要深入了解 EventPipe 序列化格式,請參閱 EventPipe 格式文件 (英文)。

EventPipe 與ETW/LTTng

EventPipe 是 .NET 執行階段 (CoreCLR) 的一部分,其設計的運作方式與所有 .NET Core 支援的平台上相同。 這可讓以 EventPipe 為基礎的追蹤工具,例如 dotnet-countersdotnet-gcdumpdotnet-trace,在平台之間順暢地運作。

但因為 EventPipe 是執行階段內建元件,因此其範圍僅限於 Managed 程式碼和執行階段本身。 EventPipe 無法用於追蹤某些較低層級的事件,例如解析機器碼堆疊或取得各式核心事件。 如果在應用程式中使用了 C/C++ Interop,或想要追蹤執行階段本身 (以 C++ 撰寫),或希望更深入地診斷需要核心事件的應用程式行為 (也就是原生執行緒內容切換事件),您應該使用 ETW 或 perf/LTTng

EventPipe 和 ETW/LTTng 之間的另一個主要差異,是管理員/根權限的要求。 若要使用 ETW 或 LTTng 追蹤應用程式,您必須是系統管理員/根使用者。 只要追蹤程式 (例如 dotnet-trace) 在執行中,您就能以啟動應用程式的相同使用者身分,利用 EventPipe 來追蹤應用程式。

下表摘要說明 EventPipe 與 ETW/LTTng 之間的差異。

功能 EventPipe ETW LTTng
跨平台 Yes 否 (僅限 Windows 上) 否 (僅限受支援的 Linux 散發版本上)
需要系統管理員/根權限 No .是 Yes
可以取得 OS/核心事件 No .是 Yes
可以解析原生呼叫堆疊 No .是 Yes

使用 EventPipe 追蹤您的 .NET 應用程式

您可以使用 EventPipe,以多種方式追蹤您的 .NET 應用程式:

產生包含您 EventPipe 事件的 nettrace 檔案之後,可以在 PerfView 或 Visual Studio 中,檢視該檔案。 在非 Windows 平台上,可以使用 dotnet-trace convert 命令,將檔案 nettrace 轉換為 speedscopeChromium 追蹤格式,並使用 speedscope 或 Chrome DevTools 加以檢視。

您也可以使用 TraceEvent,以程式設計方式分析 EventPipe 追蹤。

使用 EventPipe 的工具

這是使用 EventPipe 追蹤應用程式最簡單的方式。 若要深入了解如何使用這些工具,請參閱每項工具的文件。

  • dotnet-counters,您可用於監視和收集 .NET 執行階段和核心程式庫所發出的各種計量,以及您可以撰寫的自訂計量。

  • dotnet-gcdump,您可用於收集即時處理序的 GC 堆積傾印,以分析應用程式的受控堆積。

  • dotnet-trace,您可用於收集應用程式的追蹤,以分析效能。

使用環境變數的追蹤

使用 EventPipe 的慣用機制,是使用 dotnet-traceMicrosoft.Diagnostics.NETCore.Client 程式庫。

但您可以使用下列環境變數,在應用程式上設定 EventPipe 工作階段,並讓它將追蹤直接寫入檔案。 若要停止追蹤,請結束該應用程式。

  • DOTNET_EnableEventPipe:將此設定為 1,會啟動直接寫入檔案的 EventPipe 工作階段。 預設值是 0

  • DOTNET_EventPipeOutputPath:當輸出 EventPipe 追蹤檔設定為透過 DOTNET_EnableEventPipe 執行時,進入該追蹤檔的路徑。 預設值為 trace.nettrace,其建立位置和應用程式執行所在的目錄相同。

    注意

    從 .NET 6 開始,DOTNET_EventPipeOutputPath 中字串 {pid} 的執行個體,會取代為所追蹤之處理序的處理序識別碼。

  • DOTNET_EventPipeCircularMB:十六進位值,代表 EventPipe 內部緩衝區大小 (以 MB 為單位)。 只有當 EventPipe 設定為透過 DOTNET_EnableEventPipe 執行時,才會使用此組態值。 預設緩衝區大小為 1024MB,也就是轉譯為此環境變數會設定為 400,因為 0x400 == 1024

    注意

    如果目標處理序太頻繁地寫入事件,可能會溢位此緩衝區,而且可能會卸載某些事件。 如果卸載了太多事件,請加大緩衝區大小,以查看卸載的事件數目是否減少。 如果卸載的事件數目沒有隨著較大的緩衝區大小而減少,可能是因為讀取器緩慢,而無法清除目標處理序的緩衝區。

  • DOTNET_EventPipeProcNumbers:將此設定為 1,啟用擷取 EventPipe 事件標頭中的處理器編號。 預設值是 0

  • DOTNET_EventPipeConfig:設定在利用 DOTNET_EnableEventPipe 啟動 EventPipe 工作階段時,EventPipe 工作階段的組態。 語法如下所示:

    <provider>:<keyword>:<level>

    您也可用逗號串連多個提供者,來指定這些提供者:

    <provider1>:<keyword1>:<level1>,<provider2>:<keyword2>:<level2>

    如果未設定此環境變數,但已用 DOTNET_EnableEventPipe 啟用了 EventPipe,則會藉由使用下列關鍵字和層級來啟用下列提供者,開始追蹤:

    • Microsoft-Windows-DotNETRuntime:4c14fccbd:5
    • Microsoft-Windows-DotNETRuntimePrivate:4002000b:5
    • Microsoft-DotNETCore-SampleProfiler:0:5

    如果要深入了解 .NET 中的某些已知提供者,請參閱已知的事件提供者 (部分機器翻譯)。

注意

.NET 6 會針對設定 .NET Runtime 行為的環境變數,透過前置詞 DOTNET_ (而非 COMPlus_) 進行標準化。 不過,COMPlus_ 前置詞將繼續運作。 如果使用舊版的 .NET 執行階段,則您仍應對環境變數使用 COMPlus_ 前置詞。