dotnet-trace 性能分析实用工具
本文适用于:✔️ dotnet-trace
3.0.47001 及更高版本
安装
可采用两种方法来下载和安装 dotnet-trace
:
dotnet 全局工具:
若要安装最新版
dotnet-trace
NuGet 包,请使用 dotnet tool install 命令:dotnet tool install --global dotnet-trace
直接下载:
下载与平台相匹配的工具可执行文件:
(OS) 平台 Windows x86 | x64 | Arm | Arm-x64 Linux x64 | Arm | Arm64 | musl-x64 | musl-Arm64
摘要
dotnet-trace [-h, --help] [--version] <command>
描述
dotnet-trace
工具:
- 是一个跨平台的 .NET Core 工具。
- 在不使用本机探查器的情况下启用正在运行的进程的 .NET Core 跟踪集合。
- 是基于 .NET Core 运行时的
EventPipe
构建的。 - 在 Windows、Linux 或 macOS 上提供相同体验。
选项
-h|--help
显示命令行帮助。
--version
显示 dotnet-dump 实用工具的版本。
--duration
运行跟踪的时间。
--duration 00:00:00:05
将运行它 5 秒。
命令
命令 |
---|
dotnet-trace collect |
dotnet-trace convert |
dotnet-trace ps |
dotnet-trace list-profiles |
dotnet-trace report |
dotnet-trace collect
从正在运行的进程中收集诊断跟踪,或者启动子进程并对其进行跟踪(.NET 5 或更高版本)。 若要让工具运行子进程并自其启动时对其进行跟踪,请将 --
追加到 collect 命令。
摘要
dotnet-trace collect [--buffersize <size>] [--clreventlevel <clreventlevel>] [--clrevents <clrevents>]
[--format <Chromium|NetTrace|Speedscope>] [-h|--help] [--duration dd:hh:mm:ss]
[-n, --name <name>] [--diagnostic-port] [-o|--output <trace-file-path>] [-p|--process-id <pid>]
[--profile <profile-name>] [--providers <list-of-comma-separated-providers>]
[-- <command>] (for target applications running .NET 5 or later)
[--show-child-io] [--resume-runtime]
[--stopping-event-provider-name <stoppingEventProviderName>]
[--stopping-event-event-name <stoppingEventEventName>]
[--stopping-event-payload-filter <stoppingEventPayloadFilter>]
选项
--buffersize <size>
设置内存中缓冲区的大小(以 MB 表示)。 默认值为 256 MB。
注意
如果目标进程发出事件的速度快于事件写入磁盘的速度,则此缓冲区可能会溢出,并且某些事件将被删除。 可以通过增加缓冲区大小或减少正在记录的事件数来缓解此问题。
--clreventlevel <clreventlevel>
要发出的 CLR 事件的详细级别。 下表显示可用的事件级别。
字符串值 数值 logalways
0
critical
1
error
2
warning
3
informational
4
verbose
5
--clrevents <clrevents>
要启用的 CLR 运行时提供程序关键字列表,以
+
符号分隔。 这是一个简单映射,支持通过字符串别名而不是其十六进制值指定事件关键字。 例如,dotnet-trace collect --providers Microsoft-Windows-DotNETRuntime:3:4
请求与dotnet-trace collect --clrevents gc+gchandle --clreventlevel informational
相同的事件集。 下表显示可用关键字的列表:关键字字符串别名 关键字十六进制值 gc
0x1
gchandle
0x2
fusion
0x4
loader
0x8
jit
0x10
ngen
0x20
startenumeration
0x40
endenumeration
0x80
security
0x400
appdomainresourcemanagement
0x800
jittracing
0x1000
interop
0x2000
contention
0x4000
exception
0x8000
threading
0x10000
jittedmethodiltonativemap
0x20000
overrideandsuppressngenevents
0x40000
type
0x80000
gcheapdump
0x100000
gcsampledobjectallocationhigh
0x200000
gcheapsurvivalandmovement
0x400000
gcheapcollect
0x800000
gcheapandtypenames
0x1000000
gcsampledobjectallocationlow
0x2000000
perftrack
0x20000000
stack
0x40000000
threadtransfer
0x80000000
debugger
0x100000000
monitoring
0x200000000
codesymbols
0x400000000
eventsource
0x800000000
compilation
0x1000000000
compilationdiagnostic
0x2000000000
methoddiagnostic
0x4000000000
typediagnostic
0x8000000000
有关 CLR 提供程序的详细信息,请参阅 .NET 运行时提供程序参考文档。
--format {Chromium|NetTrace|Speedscope}
设置跟踪文件转换的输出格式。 默认值为
NetTrace
。-n, --name <name>
从中收集跟踪的进程的名称。
--diagnostic-port <path-to-port>
要创建的诊断端口的名称。 请参阅使用诊断端口从应用启动时开始收集跟踪,以了解如何使用此选项从应用启动时开始收集跟踪。
--duration <time-to-run>
跟踪运行的时间。 使用
dd:hh:mm:ss
格式。 例如00:00:00:05
,将运行它 5 秒。-o|--output <trace-file-path>
收集的跟踪数据的输出路径。 如果未指定,则默认为
<appname>_<yyyyMMdd>_<HHmmss>.nettrace
,例如“myapp_20210315_111514.nettrace”。-p|--process-id <PID>
从中收集跟踪的进程 ID。
--profile <profile-name>
一组命名的预定义提供程序配置,允许简明地指定常见跟踪方案。 可用配置文件如下:
配置文件 | 说明 |
---|---|
cpu-sampling |
可用于跟踪 CPU 使用情况和一般 .NET 运行时信息。 如果未指定配置文件或提供程序,则这是默认选项。 |
gc-verbose |
跟踪 GC 集合并示例对象分配。 |
gc-collect |
仅以极低的开销跟踪 GC 集合。 |
--providers <list-of-comma-separated-providers>
要启用的
EventPipe
提供程序的以逗号分隔的列表。 这些提供程序会补充--profile <profile-name>
隐含的任何提供程序。 如果特定提供程序存在任何不一致的情况,此配置将优先于配置文件中的隐式配置。此提供程序列表的格式为:
Provider[,Provider]
Provider
的格式为:KnownProviderName[:Flags[:Level][:KeyValueArgs]]
。KeyValueArgs
的格式为:[key1=value1][;key2=value2]
。
若要详细了解 .NET 中的一些已知提供程序,请参阅已知事件提供程序。
-- <command>
(适用于运行 .NET 5 或更高版本的目标应用程序)在集合配置参数之后,用户可以追加
--
,后跟一个命令,以启动至少具有 5.0 运行时的 .NET 应用程序。 这在过程早期发生诊断问题(如启动性能问题或程序集加载程序和绑定器错误)时可能会有所帮助。注意
使用此选项监视第一个与该工具通信的 .NET 进程,这意味着,如果命令启动多个 .NET 应用程序,它只会收集第一个应用。 因此,建议在自包含应用程序上使用此选项,或使用
dotnet exec <app.dll>
选项。--show-child-io
显示当前控制台中已启动的子进程的输入和输出流。
--resume-runtime
初始化会话后立即恢复运行时,默认为 true。 使用 --resume-runtime:false 禁止恢复运行时。
--stopping-event-provider-name
按原样分析的字符串,它将在命中具有匹配提供程序名称的事件时停止跟踪。 对于更具体的停止事件,请额外提供
--stopping-event-event-name
和/或--stopping-event-payload-filter
。 例如--stopping-event-provider-name Microsoft-Windows-DotNETRuntime
,用于在命中Microsoft-Windows-DotNETRuntime
事件提供程序发出的第一个事件时停止跟踪。--stopping-event-event-name
按原样分析的字符串,它将在命中具有匹配事件名称的事件时停止跟踪。 需要设置
--stopping-event-provider-name
。 对于更具体的停止事件,请额外提供--stopping-event-payload-filter
。 例如--stopping-event-provider-name Microsoft-Windows-DotNETRuntime --stopping-event-event-name Method/JittingStarted
,用于在命中Microsoft-Windows-DotNETRuntime
事件提供程序发出的第一个Method/JittingStarted
事件时停止跟踪。--stopping-event-payload-filter
分析为 [payload_field_name]:[payload_field_value] 对(用逗号分隔)的字符串,它将在命中包含所有指定有效负载对的事件时停止跟踪。 需要设置
--stopping-event-provider-name
和--stopping-event-event-name
。 例如--stopping-event-provider-name Microsoft-Windows-DotNETRuntime --stopping-event-event-name Method/JittingStarted --stopping-event-payload-filter MethodNameSpace:Program,MethodName:OnButtonClick
,用于在命中Microsoft-Windows-DotNETRuntime
事件提供程序发出的Program
名称空间中方法OnButtonClick
的第一个Method/JittingStarted
事件时停止跟踪。
注意
- 对于大型应用程序,停止跟踪可能需要较长时间(可达数分钟)。 运行时需要为跟踪中捕获的所有托管代码发送类型缓存。
- 在 Linux 和 macOS 上,此命令需要目标应用程序和
dotnet-trace
使用同一TMPDIR
环境变量。 否则,该命令将超时。
- 若要使用
dotnet-trace
收集跟踪,需要以与运行目标进程的用户相同的用户身份或以根身份运行。 否则,该工具将无法与目标进程建立连接。
- 如果在运行
dotnet-trace collect
时遇到未经处理的异常,这会导致跟踪不完整。 如果找到异常的根本原因是优先级,请导航到崩溃时收集转储。 由于未处理的异常,运行时关闭时跟踪会被截断,以防发生其他不希望的行为,例如挂起或数据损坏。 即使跟踪不完整,仍可打开它以查看导致故障的原因。 但是,它将丢失断开信息(这发生在跟踪末尾),因此堆栈可能无法解析(具体取决于打开的提供程序)。 通过在命令行中使用/ContinueOnError
标记执行 PerfView 来打开跟踪。 日志还将包含触发异常的位置。
- 通过
--stopping-event-*
选项指定停止事件时,由于正在异步分析 EventStream,因此在分析与指定停止事件选项匹配的跟踪事件和停止 EventPipeSession 的这段时间会有一些事件通过。
dotnet-trace convert
将 nettrace
跟踪转换为备用格式,以便用于备用跟踪分析工具。
摘要
dotnet-trace convert [<input-filename>] [--format <Chromium|NetTrace|Speedscope>] [-h|--help] [-o|--output <output-filename>]
自变量
<input-filename>
要转换的输入跟踪文件。 默认为 trace.nettrace 。
选项
--format <Chromium|NetTrace|Speedscope>
设置跟踪文件转换的输出格式。
-o|--output <output-filename>
输出文件名。 将添加目标格式的扩展。
注意
将 nettrace
文件转换为 chromium
或 speedscope
文件是不可逆操作。 speedscope
和 chromium
文件不具备重新构造 nettrace
文件所需的全部信息。 但是,convert
命令保留了原始 nettrace
文件,因此,如果打算将来打开该文件,请不要将其删除。
dotnet-trace ps
列出可从中收集跟踪的 dotnet 进程。
dotnet-trace
6.0.320703 及更高版本还显示每个进程的启动命令行参数(如果可用)。
注意
若要获取枚举 64 位进程的完整信息,需要使用 64 位版本的 dotnet-trace
工具。
摘要
dotnet-trace ps [-h|--help]
示例
假设使用命令 dotnet run --configuration Release
启动长时间运行的应用。 在另一个窗口中,运行 dotnet-trace ps
命令。 你将看到如下输出。 命令行参数(如果有)显示在 dotnet-trace
版本 6.0.320703 及更高版本中。
> dotnet-trace ps
21932 dotnet C:\Program Files\dotnet\dotnet.exe run --configuration Release
36656 dotnet C:\Program Files\dotnet\dotnet.exe
dotnet-trace list-profiles
列出预生成的跟踪配置文件,并描述每个配置文件中包含的提供程序和筛选器。
摘要
dotnet-trace list-profiles [-h|--help]
dotnet-trace report
将报表从以前生成的跟踪创建到 stdout 中。
摘要
dotnet-trace report [-h|--help] <tracefile> [command]
自变量
<tracefile>
要分析的跟踪的文件路径。
命令
dotnet-trace report topN
查找在调用堆栈上的时间最长的前 N 个方法。
摘要
dotnet-trace report <tracefile> topN [-n|--number <n>] [--inclusive] [-v|--verbose] [-h|--help]
选项
-n|--number <n>
提供调用堆栈上的前 N 个方法。
--inclusive
基于非独占时间输出前 N 个方法。 如果未指定,则默认情况下使用独占时间。
-v|--verbose
完整输出每个方法的参数。 如果未指定,则将截断参数。
使用 dotnet-trace 收集跟踪
若要使用 dotnet-trace
收集跟踪,请执行以下操作:
需要首先查找要从中收集跟踪的 .NET Core 应用程序的进程标识符 (PID)。
- 例如,在 Windows 上,可以使用任务管理器或
tasklist
命令。 - 在 Linux 上,使用
ps
命令。 - dotnet-trace ps
- 例如,在 Windows 上,可以使用任务管理器或
运行下面的命令:
dotnet-trace collect --process-id <PID>
前面的命令生成类似于以下内容的输出:
Press <Enter> to exit... Connecting to process: <Full-Path-To-Process-Being-Profiled>/dotnet.exe Collecting to file: <Full-Path-To-Trace>/trace.nettrace Session Id: <SessionId> Recording trace 721.025 (KB)
按
<Enter>
键停止收集。dotnet-trace
会将完成将事件记录到 trace.nettrace 文件中 。
启动子应用程序,并使用 dotnet-trace 从启动中收集跟踪
有时,从进程启动中收集进程的跟踪可能很有用。 对于运行 .NET 5 或更高版本的应用,可以使用 dotnet-trace 来做到这一点。
这将启动 hello.exe
并以 arg1
和 arg2
作为其命令行参数,从其运行时启动中收集跟踪:
dotnet-trace collect -- hello.exe arg1 arg2
前面的命令生成类似于以下内容的输出:
No profile or providers specified, defaulting to trace profile 'cpu-sampling'
Provider Name Keywords Level Enabled By
Microsoft-DotNETCore-SampleProfiler 0x0000F00000000000 Informational(4) --profile
Microsoft-Windows-DotNETRuntime 0x00000014C14FCCBD Informational(4) --profile
Process : E:\temp\gcperfsim\bin\Debug\net5.0\gcperfsim.exe
Output File : E:\temp\gcperfsim\trace.nettrace
[00:00:00:05] Recording trace 122.244 (KB)
Press <Enter> or <Ctrl+C> to exit...
可以通过按 <Enter>
或 <Ctrl + C>
键来停止收集跟踪。 此操作还将退出 hello.exe
。
注意
通过 dotnet-trace 启动 hello.exe
会重定向其输入/输出;默认情况下,你将无法在控制台上与其交互。 使用 --show-child-io
开关与其 stdin/stdout 交互。
通过 CTRL+C 或 SIGTERM 退出工具将安全地结束该工具和子进程。
如果子进程在工具之前退出,工具也将退出,应可安全查看跟踪。
使用诊断端口从应用启动时开始收集跟踪
诊断端口是 .NET 5 中新增的运行时功能,你可以通过它从应用启动时开始跟踪。 若要使用 dotnet-trace
执行此操作,可以使用以上示例中所述的 dotnet-trace collect -- <command>
,也可以使用 --diagnostic-port
选项。
使用 dotnet-trace <collect|monitor> -- <command>
以子进程的形式启动应用程序,是从启动时开始对该应用程序进行快速跟踪的最简单方法。
但是,如果想要更好地控制所跟踪应用的生存期(例如,仅在前 10 分钟内监视应用并继续执行),或者如果需要使用 CLI 与应用进行交互,则使用 --diagnostic-port
选项可以同时控制要监视的目标应用和 dotnet-trace
。
以下命令使
dotnet-trace
创建一个名为myport.sock
的诊断套接字并等待连接。dotnet-trace collect --diagnostic-port myport.sock
输出:
Waiting for connection on myport.sock Start an application with the following environment variable: DOTNET_DiagnosticPorts=/home/user/myport.sock
在单独的控制台中,通过将环境变量
DOTNET_DiagnosticPorts
设置为dotnet-trace
输出中的值,启动目标应用程序。export DOTNET_DiagnosticPorts=/home/user/myport.sock ./my-dotnet-app arg1 arg2
这应该会使
dotnet-trace
开始跟踪my-dotnet-app
:Waiting for connection on myport.sock Start an application with the following environment variable: DOTNET_DiagnosticPorts=myport.sock Starting a counter session. Press Q to quit.
重要
通过
dotnet run
启动应用可能会产生问题,因为 dotnet CLI 可能会生成许多子进程,这些子程序不是应用,并且可以在应用之前连接到dotnet-trace
,从而导致应用在运行时挂起。 建议直接使用应用的独立版本或使用dotnet exec
来启动应用程序。
查看由 dotnet-trace 捕获的跟踪
在 Windows 上,可以在 Visual Studio 或 PerfView 中查看 .nettrace 文件以进行分析。
在 Linux 上,可以通过将 dotnet-trace
的输出格式更改为 speedscope
来查看跟踪。 使用 -f|--format
选项更改输出文件格式。 可以在 nettrace
(默认选项)和 speedscope
之间进行选择。 选项 -f speedscope
将使 dotnet-trace
生成一个 speedscope
文件。 可以在 https://www.speedscope.app 打开 Speedscope
文件。
对于在非 Windows 平台上收集的跟踪,还可以将跟踪文件移动到 Windows 计算机并在 Visual Studio 或 PerfView 中查看它。
注意
.NET Core 运行时以 nettrace
格式生成跟踪。 跟踪完成后,跟踪将转换为 speedscope(如果指定)。 由于某些转换可能会导致数据丢失,因此,原始 nettrace
文件将保留在转换后的文件旁边。
使用 .rsp 文件来避免键入长命令
可以使用包含要传递的参数的 .rsp
文件启动 dotnet-trace
。 当启用需要较长参数的提供程序时,或在使用可去除字符的 shell 环境时,这很有用。
例如,以下提供程序在每次要跟踪时都可能要繁琐地键入内容:
dotnet-trace collect --providers Microsoft-Diagnostics-DiagnosticSource:0x3:5:FilterAndPayloadSpecs="SqlClientDiagnosticListener/System.Data.SqlClient.WriteCommandBefore@Activity1Start:-Command;Command.CommandText;ConnectionId;Operation;Command.Connection.ServerVersion;Command.CommandTimeout;Command.CommandType;Command.Connection.ConnectionString;Command.Connection.Database;Command.Connection.DataSource;Command.Connection.PacketSize\r\nSqlClientDiagnosticListener/System.Data.SqlClient.WriteCommandAfter@Activity1Stop:\r\nMicrosoft.EntityFrameworkCore/Microsoft.EntityFrameworkCore.Database.Command.CommandExecuting@Activity2Start:-Command;Command.CommandText;ConnectionId;IsAsync;Command.Connection.ClientConnectionId;Command.Connection.ServerVersion;Command.CommandTimeout;Command.CommandType;Command.Connection.ConnectionString;Command.Connection.Database;Command.Connection.DataSource;Command.Connection.PacketSize\r\nMicrosoft.EntityFrameworkCore/Microsoft.EntityFrameworkCore.Database.Command.CommandExecuted@Activity2Stop:",OtherProvider,AnotherProvider
此外,前一个示例包含 "
作为参数的一部分。 由于每个 shell 对引号的处理不同,因此在使用不同的 shell 时可能会遇到各种问题。 例如,在 zsh
中输入的命令与 cmd
中的命令不同。
可以将以下文本保存到名为 myprofile.rsp
的文件中,而不必每次都键入此内容。
--providers
Microsoft-Diagnostics-DiagnosticSource:0x3:5:FilterAndPayloadSpecs="SqlClientDiagnosticListener/System.Data.SqlClient.WriteCommandBefore@Activity1Start:-Command;Command.CommandText;ConnectionId;Operation;Command.Connection.ServerVersion;Command.CommandTimeout;Command.CommandType;Command.Connection.ConnectionString;Command.Connection.Database;Command.Connection.DataSource;Command.Connection.PacketSize\r\nSqlClientDiagnosticListener/System.Data.SqlClient.WriteCommandAfter@Activity1Stop:\r\nMicrosoft.EntityFrameworkCore/Microsoft.EntityFrameworkCore.Database.Command.CommandExecuting@Activity2Start:-Command;Command.CommandText;ConnectionId;IsAsync;Command.Connection.ClientConnectionId;Command.Connection.ServerVersion;Command.CommandTimeout;Command.CommandType;Command.Connection.ConnectionString;Command.Connection.Database;Command.Connection.DataSource;Command.Connection.PacketSize\r\nMicrosoft.EntityFrameworkCore/Microsoft.EntityFrameworkCore.Database.Command.CommandExecuted@Activity2Stop:",OtherProvider,AnotherProvider
保存 myprofile.rsp
后,可以使用以下命令通过此配置启动 dotnet-trace
:
dotnet-trace @myprofile.rsp