本文适用于: ✔️ dotnet-trace 9.0.625801 及更高版本
安装
可采用两种方法来下载和安装 dotnet-trace:
dotnet 全局工具:
若要安装最新版
dotnet-traceNuGet 包,请使用 dotnet tool install 命令:dotnet tool install --global dotnet-trace直接下载:
下载与平台相匹配的工具可执行文件:
(OS) 平台 Windows操作系统 x86 | x64 | 手臂 | Arm-x64 Linux的 x64 | 手臂 | 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 报表 |
dotnet-trace collect
从正在运行的进程中收集诊断跟踪,或者启动子进程并对其进行跟踪(.NET 5 或更高版本)。 若要让工具运行子进程并自其启动时对其进行跟踪,请将 -- 追加到 collect 命令。
摘要
dotnet-trace collect [--buffersize <size>] [--clreventlevel <clreventlevel>] [--clrevents <clrevents>]
[--dsrouter <ios|ios-sim|android|android-emu>]
[--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 事件的详细级别。 下表显示可用的事件级别。
字符串值 数值 logalways0critical1error2warning3informational4verbose5--clrevents <clrevents>要启用的 CLR 运行时提供程序关键字列表,以
+符号分隔。 这是一个简单映射,支持通过字符串别名而不是其十六进制值指定事件关键字。 例如,dotnet-trace collect --providers Microsoft-Windows-DotNETRuntime:3:4请求与dotnet-trace collect --clrevents gc+gchandle --clreventlevel informational相同的事件集。 下表显示可用关键字的列表:关键字字符串别名 关键字十六进制值 gc0x1gchandle0x2fusion0x4loader0x8jit0x10ngen0x20startenumeration0x40endenumeration0x80security0x400appdomainresourcemanagement0x800jittracing0x1000interop0x2000contention0x4000exception0x8000threading0x10000jittedmethodiltonativemap0x20000overrideandsuppressngenevents0x40000type0x80000gcheapdump0x100000gcsampledobjectallocationhigh0x200000gcheapsurvivalandmovement0x400000gcheapcollect0x800000gcheapandtypenames0x1000000gcsampledobjectallocationlow0x2000000perftrack0x20000000stack0x40000000threadtransfer0x80000000debugger0x100000000monitoring0x200000000codesymbols0x400000000eventsource0x800000000compilation0x1000000000compilationdiagnostic0x2000000000methoddiagnostic0x4000000000typediagnostic0x8000000000waithandle0x40000000000有关 CLR 提供程序的详细信息,请参阅 .NET 运行时提供程序参考文档。
'--dsrouter {ios|ios-sim|android|android-emu}
启动 dotnet-dsrouter 并连接到它。 需要安装 dotnet-dsrouter 。 有关详细信息,请运行 dotnet-dsrouter -h 。
--format {Chromium|NetTrace|Speedscope}设置跟踪文件转换的输出格式。 默认值为
NetTrace。-n, --name <name>从中收集跟踪的进程的名称。
注意
在 Linux 和 macOS 上,使用此选项需要目标应用程序并
dotnet-trace共享相同的TMPDIR环境变量。 否则,该命令将超时。--diagnostic-port <port-address[,(listen|connect)]>设置用于与要跟踪的进程通信的 诊断端口 。 目标进程内的 dotnet-trace 和 .NET 运行时必须在端口地址上达成一致,其中一个侦听和另一个连接。 dotnet-trace 在使用或
--process-id选项附加--name时或使用选项启动进程-- <command>时自动确定正确的端口。 通常需要在等待将来启动的进程或与不在当前进程命名空间的容器中运行的进程通信时显式指定端口。OS
port-address的不同之处在于:- Linux 和 macOS - Unix 域套接字的路径,例如
/foo/tool1.socket。 - Windows - 命名管道的路径,例如
\\.\pipe\my_diag_port1。 - Android、iOS 和 tvOS - IP:port,例如
127.0.0.1:9000。
默认情况下,
dotnet-trace侦听指定地址。 可以通过在地址后面追加dotnet-trace来请求,connect连接。 例如,--diagnostic-port /foo/tool1.socket,connect将连接到侦听 Unix 域套接字的/foo/tool1.socket.NET 运行时进程。若要了解如何使用此选项从应用启动收集跟踪,请参阅 使用诊断端口从应用启动收集跟踪。
- Linux 和 macOS - Unix 域套接字的路径,例如
--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。
注意
在 Linux 和 macOS 上,使用此选项需要目标应用程序并
dotnet-trace共享相同的TMPDIR环境变量。 否则,该命令将超时。--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若要在命中事件提供程序发出的Method/JittingStarted第一个Microsoft-Windows-DotNETRuntime事件时停止跟踪。--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若要在事件提供程序发出的Method/JittingStarted命名空间中OnButtonClick方法Program的第一个Microsoft-Windows-DotNETRuntime事件时停止跟踪。
注意
- 对于大型应用程序,停止跟踪可能需要较长时间(可达数分钟)。 运行时需要为跟踪中捕获的所有托管代码发送类型缓存。
- 若要使用
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 报表
将报表从以前生成的跟踪创建到 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 文件。 可以在 Speedscope 打开 https://www.speedscope.app 文件。
对于在非 Windows 平台上收集的跟踪,还可以将跟踪文件移动到 Windows 计算机并在 Visual Studio 或 PerfView 中查看它。
注意
.NET Core 运行时以 nettrace 格式生成跟踪。 跟踪完成后,跟踪将转换为 speedscope(如果指定)。 由于某些转换可能会导致数据丢失,因此,原始 nettrace 文件将保留在转换后的文件旁边。
使用 .rsp 文件来避免键入长命令
可以使用包含要传递的参数的 dotnet-trace 文件启动 .rsp。 当启用需要较长参数的提供程序时,或在使用可去除字符的 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