EventPipe
EventPipe 是类似于 ETW 或 perf_events 的运行时组件,可用于收集跟踪数据。 EventPipe 的目标是使 .NET 开发人员能够轻松地跟踪其 .NET 应用程序,而无需依赖于平台特定的高特权组件(如 ETW 或 perf_events)。
EventPipe 是众多诊断工具背后的一种机制,可用于接收运行时发出的事件以及通过 EventSource 编写的自定义事件。
本文是对 EventPipe 的简要概述。 文章说明何时以及如何使用 EventPipe,以及如何对其进行配置以最大程度地满足你的需求。
EventPipe 基础知识
EventPipe 聚合由运行时组件发出的事件(例如实时编译器或垃圾回收器)以及从库和用户代码中的 EventSource 实例编写的事件。
然后,事件以 .nettrace
文件格式序列化,可以直接写入文件,也可以通过诊断端口流式传输,以便在进程外使用。
若要了解有关 EventPipe 序列化格式的详细信息,请参阅 EventPipe 格式文档。
EventPipe 与 ETW/perf_events
EventPipe 是 .NET 运行时的一部分,旨在跨 .NET Core 支持的所有平台以相同的方式工作。 这将允许基于 EventPipe 的跟踪工具(例如 dotnet-counters
、dotnet-gcdump
和 dotnet-trace
)无缝地跨平台工作。
但是,因为 EventPipe 是一个运行时内置组件,所以它的作用域仅限于托管代码和运行时本身。 EventPipe 事件仅包含附带托管代码帧信息的堆栈跟踪。 如果需要从其他非托管用户模式库生成的事件、本机代码的 CPU 采样或内核事件,则应使用特定于 OS 的跟踪工具(如 ETW 或 perf_events)。 在 Linux 上,perfcollect 工具有助于自动使用 perf_events 和 LTTng。
EventPipe 和 ETW/perf_events 之间的另一个主要区别是管理员/根用户权限要求。 若要使用 ETW 或 perf_events 跟踪应用程序,你需要是管理员/根用户。 可使用 EventPipe 跟踪应用程序,前提是跟踪器(如 dotnet-trace
)是由启动该应用程序的同一用户运行的。
下表汇总了 EventPipe 和 ETW/perf_events 之间的差异。
功能 | EventPipe | ETW | perf_events |
---|---|---|---|
跨平台 | 是 | 否(仅在 Windows 上) | 否(仅在受支持的 Linux 发行版上) |
需要管理员/根用户权限 | 否 | 是 | 是 |
可获取 OS/内核事件 | 否 | 是 | 是 |
可解析本机调用堆栈 | 否 | 是 | 是 |
使用 EventPipe 跟踪 .NET 应用程序
可通过多种方式使用 EventPipe 跟踪 .NET 应用程序:
使用基于 EventPipe 构建的诊断工具之一。
使用 Microsoft.Diagnostics.NETCore.Client 库来编写自己的工具,以配置和启动 EventPipe 会话。
使用环境变量来启动 EventPipe。
生成包含 EventPipe 事件的 nettrace
文件之后,可在 PerfView 或 Visual Studio 中查看该文件。 在非 Windows 平台上,可使用 dotnet-trace convert 命令将 nettrace
文件转换为 speedscope
或 Chromium
跟踪格式,并使用 speedscope 或 Chrome DevTools 查看该文件。
还以通过 TraceEvent 以编程方式分析 EventPipe 跟踪。
使用 EventPipe 的工具
这是使用 EventPipe 跟踪应用的最简单方法。 若要详细了解如何使用这些工具,请参阅每个工具的文档。
dotnet-counters 使你能够监视和收集由 .NET 运行时和核心库发出的各种指标,以及可以编写的自定义指标。
dotnet-gcdump 使你能够收集实时进程的 GC 堆转储以分析应用程序的托管堆。
dotnet-trace 使你能够收集应用程序的跟踪以进行性能分析。
使用环境变量进行跟踪
使用 EventPipe 的首选机制是使用 dotnet-trace 或 Microsoft.Diagnostics.NETCore.Client 库。
但是,可使用以下环境变量在应用上设置 EventPipe 会话,并使其将跟踪直接写入到文件。 若要停止跟踪,请退出应用程序。
DOTNET_EnableEventPipe
:将此值设置为1
以启动直接写入到文件的 EventPipe 会话。 默认值为0
。DOTNET_EventPipeOutputPath
:输出 EventPipe 跟踪文件(配置为通过DOTNET_EnableEventPipe
运行时)的路径。 默认值为trace.nettrace
,将在运行应用的同一目录中创建该默认值。注意
自 .NET 6 起,
DOTNET_EventPipeOutputPath
中的{pid}
字符串实例将替换为所跟踪的进程的进程 ID。DOTNET_EventPipeCircularMB
:一个十六进制值,它表示 EventPipe 的内部缓冲区大小(以 MB 为单位)。 仅当 EventPipe 配置为通过DOTNET_EnableEventPipe
运行时,才使用此配置值。 默认缓冲区大小为 1024 MB,而由于0x400
==1024
,它转换为设置成400
的环境变量。注意
如果目标进程过于频繁地写入事件,则它可能会溢出此缓冲区,并且某些事件可能会被丢弃。 如果丢弃的事件过多,请增加缓冲区大小,查看丢弃的事件数是否减少。 如果丢弃的事件数未随缓冲区大小的增加而减少,则可能是因为读取器的速度较慢,导致无法刷新目标进程的缓冲区。
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 运行时行为的环境变量标准化前缀 DOTNET_
而不是 COMPlus_
。 但是,COMPlus_
前缀仍将继续正常工作。 如果使用的是早期版本的 .NET 运行时,则环境变量仍应该使用 COMPlus_
前缀。