Note
Ang pag-access sa pahinang ito ay nangangailangan ng pahintulot. Maaari mong subukang mag-sign in o magpalit ng mga direktoryo.
Ang pag-access sa pahinang ito ay nangangailangan ng pahintulot. Maaari mong subukang baguhin ang mga direktoryo.
This article applies to: ✔️ dotnet-trace 9.0.661903 and later versions
Install
There are two ways to download and install dotnet-trace:
dotnet global tool:
To install the latest release version of the
dotnet-traceNuGet package, use the dotnet tool install command:dotnet tool install --global dotnet-traceDirect download:
Download the tool executable that matches your platform:
OS Platform Windows x86 | x64 | Arm | Arm-x64 Linux x64 | Arm | Arm64 | musl-x64 | musl-Arm64
Synopsis
dotnet-trace [-h, --help] [--version] <command>
Description
The dotnet-trace tool:
Is a cross-platform .NET Core tool.
Enables the collection of .NET Core traces of a running process without a native profiler.
Is built on
EventPipeof the .NET Core runtime.Supports two different ways of collecting traces:
- The
collectverb offers consistent functionality on any OS. - The
collect-linuxverb uses Linux-specific OS capabilities to provide additional features.
Characteristic collectcollect-linuxSupported OS Any Linux only, kernel version >= 6.4 Requires Admin/Root Privilege No Yes Trace all processes simultaneously No Supported Capture native library and kernel events No Supported Event callstacks include native frames No Yes - The
Options
-h|--helpShows command-line help.
--versionDisplays the version of the dotnet-trace utility.
Commands
| Command |
|---|
| dotnet-trace collect |
| dotnet-trace collect-linux |
| dotnet-trace convert |
| dotnet-trace ps |
| dotnet-trace list-profiles |
| dotnet-trace report |
dotnet-trace collect
Collects a diagnostic trace from a running process or launches a child process and traces it (.NET 5 or later). To have the tool run a child process and trace it from its startup, append -- to the collect command.
Synopsis
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 <list-of-comma-separated-profile-names>]
[--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>]
Options
--buffersize <size>Sets the size of the in-memory buffer, in megabytes. Default 256 MB.
Note
If the target process emits events faster than they can be written to disk, this buffer may overflow and some events will be dropped. You can mitigate this problem by increasing the buffer size or reducing the number of events being recorded.
--clreventlevel <clreventlevel>Verbosity of CLR events to be emitted. This option only applies when
--clreventsis specified and not overridden by--profileor--providers. The following table shows the available event levels.String value Numeric value logalways0critical1error2warning3informational4verbose5--clrevents <clrevents>A list of CLR runtime provider keywords to enable separated by
+signs. This is a simple mapping that lets you specify event keywords via string aliases rather than their hex values. For example,dotnet-trace collect --providers Microsoft-Windows-DotNETRuntime:3:4requests the same set of events asdotnet-trace collect --clrevents gc+gchandle --clreventlevel informational. If the CLR runtime providerMicrosoft-Windows-DotNETRuntimeis also enabled through--providersor--profile, this option is ignored. The following table shows the list of available keywords:Keyword String Alias Keyword Hex Value gc0x1gchandle0x2assemblyloader0x4loader0x8jit0x10ngen0x20startenumeration0x40endenumeration0x80security0x400appdomainresourcemanagement0x800jittracing0x1000interop0x2000contention0x4000exception0x8000threading0x10000jittedmethodiltonativemap0x20000overrideandsuppressngenevents0x40000type0x80000gcheapdump0x100000gcsampledobjectallocationhigh0x200000gcheapsurvivalandmovement0x400000managedheapcollect0x800000gcheapandtypenames0x1000000gcsampledobjectallocationlow0x2000000perftrack0x20000000stack0x40000000threadtransfer0x80000000debugger0x100000000monitoring0x200000000codesymbols0x400000000eventsource0x800000000compilation0x1000000000compilationdiagnostic0x2000000000methoddiagnostic0x4000000000typediagnostic0x8000000000jitinstrumentationdata0x10000000000profiler0x20000000000waithandle0x40000000000allocationsampling0x80000000000You can read about the CLR provider in more detail on the .NET runtime provider reference documentation.
`--dsrouter {ios|ios-sim|android|android-emu}
Starts dotnet-dsrouter and connects to it. Requires dotnet-dsrouter to be installed. Run
dotnet-dsrouter -hfor more information.--format {Chromium|NetTrace|Speedscope}Sets the output format for the trace file conversion. The default is
NetTrace.-n, --name <name>The name of the process to collect the trace from.
Note
On Linux and macOS, using this option requires the target application and
dotnet-traceto share the sameTMPDIRenvironment variable. Otherwise, the command will time out.--diagnostic-port <port-address[,(listen|connect)]>Sets the diagnostic port used to communicate with the process to be traced. dotnet-trace and the .NET runtime inside the target process must agree on the port-address, with one listening and the other connecting. dotnet-trace automatically determines the correct port when attaching using the
--process-idor--nameoptions, or when launching a process using the-- <command>option. It's usually only necessary to specify the port explicitly when waiting for a process that will start in the future or communicating to a process that is running inside a container that isn't part of the current process namespace.The
port-addressdiffers by OS:- Linux and macOS - a path to a Unix domain socket such as
/foo/tool1.socket. - Windows - a path to a named pipe such as
\\.\pipe\my_diag_port1. - Android, iOS, and tvOS - an IP:port such as
127.0.0.1:9000.
By default,
dotnet-tracelistens at the specified address. You can requestdotnet-traceto connect instead by appending,connectafter the address. For example,--diagnostic-port /foo/tool1.socket,connectwill connect to a .NET runtime process that is listening to the/foo/tool1.socketUnix domain socket.To learn how to use this option to collect a trace from app startup, see Use diagnostic port to collect a trace from app startup.
- Linux and macOS - a path to a Unix domain socket such as
--duration <time-to-run>The time for the trace to run. Use the
dd:hh:mm:ssformat. For example00:00:00:05will run it for 5 seconds.-o|--output <trace-file-path>The output path for the collected trace data. If not specified it defaults to
<appname>_<yyyyMMdd>_<HHmmss>.nettrace, for example, `myapp_20210315_111514.nettrace``.-p|--process-id <PID>The process ID to collect the trace from.
Note
On Linux and macOS, using this option requires the target application and
dotnet-traceto share the sameTMPDIRenvironment variable. Otherwise, the command will time out.--profile <list-of-comma-separated-profile-names>A profile is a predefined set of provider configurations for common tracing scenarios. Multiple profiles can be specified at a time, delimited by commas. Providers configured through
--providersoverride the profile's configuration. Similarly, if any profile configures the CLR runtime provider, it will override any configurations prescribed through--clrevents.When
--profile,--providers, and--clreventsare all omitted,dotnet-trace collectenables profilesdotnet-commonanddotnet-sampled-thread-timeby default.Available profiles:
Profile Description dotnet-commonLightweight .NET runtime diagnostics designed to stay low overhead.
Includes GC, AssemblyLoader, Loader, JIT, Exceptions, Threading, JittedMethodILToNativeMap, and Compilation events
Equivalent to--providers "Microsoft-Windows-DotNETRuntime:0x100003801D:4".dotnet-sampled-thread-timeSamples .NET thread stacks (~100 Hz) to identify hotspots over time. Uses the runtime sample profiler with managed stacks. gc-verboseTracks GC collections and samples object allocations. gc-collectTracks GC collections only at very low overhead. databaseCaptures ADO.NET and Entity Framework database commands. Note
In past versions of the dotnet-trace tool, the collect verb supported a profile called
cpu-sampling. This profile was removed because the name was misleading. It sampled all threads regardless of their CPU usage. You can achieve a similar result now using--profile dotnet-sampled-thread-time,dotnet-common. If you need to match the formercpu-samplingbehavior exactly, use--profile dotnet-sampled-thread-time --providers "Microsoft-Windows-DotNETRuntime:0x14C14FCCBD:4".--providers <list-of-comma-separated-providers>A comma-separated list of
EventPipeproviders to be enabled. These providers supplement any providers implied by--profile <list-of-comma-separated-profile-names>. If there's any inconsistency for a particular provider, this configuration takes precedence over the implicit configuration from--profileand--clrevents.This list of providers is in the form
Provider[,Provider]:Provideris in the form:KnownProviderName[:Flags[:Level[:KeyValueArgs]]]KeyValueArgsis in the form:[key1=value1][;key2=value2]
To learn more about some of the well-known providers in .NET, refer to Well-known Event Providers.
-- <command>(for target applications running .NET 5 or later)After the collection configuration parameters, the user can append
--followed by a command to start a .NET application with at least a 5.0 runtime. This may be helpful when diagnosing issues that happen early in the process, such as startup performance issue or assembly loader and binder errors.Note
Using this option monitors the first .NET process that communicates back to the tool, which means if your command launches multiple .NET applications, it will only collect the first app. Therefore, it is recommended you use this option on self-contained applications, or using the
dotnet exec <app.dll>option.--show-child-ioShows the input and output streams of a launched child process in the current console.
--resume-runtimeResume runtime once session has been initialized, defaults to true. Disable resume of runtime using --resume-runtime:false.
--stopping-event-provider-nameA string, parsed as-is, that will stop the trace upon hitting an event with the matching provider name. For a more specific stopping event, additionally provide
--stopping-event-event-nameand/or--stopping-event-payload-filter. for example,--stopping-event-provider-name Microsoft-Windows-DotNETRuntimeto stop the trace upon hitting the first event emitted by theMicrosoft-Windows-DotNETRuntimeevent provider.--stopping-event-event-nameA string, parsed as-is, that will stop the trace upon hitting an event with the matching event name. Requires
--stopping-event-provider-nameto be set. For a more specific stopping event, additionally provide--stopping-event-payload-filter. for example,--stopping-event-provider-name Microsoft-Windows-DotNETRuntime --stopping-event-event-name Method/JittingStartedto stop the trace upon hitting the firstMethod/JittingStartedevent emitted by theMicrosoft-Windows-DotNETRuntimeevent provider.--stopping-event-payload-filterA string, parsed as [payload_field_name]:[payload_field_value] pairs separated by commas, that will stop the trace upon hitting an event containing all specified payload pairs. Requires
--stopping-event-provider-nameand--stopping-event-event-nameto be set. for example,--stopping-event-provider-name Microsoft-Windows-DotNETRuntime --stopping-event-event-name Method/JittingStarted --stopping-event-payload-filter MethodNameSpace:Program,MethodName:OnButtonClickto stop the trace upon the firstMethod/JittingStartedevent for the methodOnButtonClickin theProgramnamespace emitted by theMicrosoft-Windows-DotNETRuntimeevent provider.
Note
- Stopping the trace may take a long time (up to minutes) for large applications. The runtime needs to send over the type cache for all managed code that was captured in the trace.
- To collect a trace using
dotnet-trace, it needs to be run as the same user as the user running the target process or as root. Otherwise, the tool will fail to establish a connection with the target process.
- If you experience an unhandled exception while running
dotnet-trace collect, this results in an incomplete trace. If finding the root cause of the exception is your priority, navigate to Collect dumps on crash. As a result of the unhandled exception, the trace is truncated when the runtime shuts down to prevent other undesired behavior such as a hang or data corruption. Even though the trace is incomplete, you can still open it to see what happened leading up to the failure. However, it will be missing Rundown information (this happens at the end of a trace) so stacks might be unresolved (depending on what providers were turned on). Open the trace by executing PerfView with the/ContinueOnErrorflag at the command line. The logs will also contain the location the exception was fired.
- When specifying a stopping event through the
--stopping-event-*options, as the EventStream is being parsed asynchronously, there will be some events that pass through between the time a trace event matching the specified stopping event options is parsed and the EventPipeSession is stopped.
dotnet-trace collect-linux
Note
The collect-linux verb is a new preview feature and relies on an updated version of the .nettrace file format. The latest PerfView release supports these trace files, but other ways of using the trace file, such as convert and report, might not work yet.
Collects diagnostic traces using perf_events, a Linux OS technology. collect-linux enables the following additional features over collect.
| collect | collect-linux | |
|---|---|---|
| Supported OS | Any | Linux only, kernel version >= 6.4 |
| Requires Admin/Root privilege | No | Yes |
| Trace all processes simultaneously | No | Supported |
| Capture native library and kernel events | No | Supported |
| Event callstacks include native frames | No | Yes |
Prerequisites
- Linux kernel with
CONFIG_USER_EVENTS=ysupport (kernel 6.4+) - Root permissions
- .NET 10+
Note
The collect-linux verb only runs on linux x64 and linux arm64 environments that have glibc version 2.35 or above.
All of the .NET 10 officially supported Linux distros support this requirement except Alpine 3.22, CentOS Stream 9, and any distros based off Red Hat Enterprise Linux 9.
A quick way to check the version of a system's libc is with the command ldd --version or by executing the libc library directly.
Synopsis
dotnet-trace collect-linux
[-h|--help]
# Provider/Event Specification
[--providers <list-of-comma-separated-providers>]
[--clreventlevel <clreventlevel>]
[--clrevents <clrevents>]
[--perf-events <list-of-perf-events>]
[--profile <list-of-comma-separated-profile-names>]
# Trace Collection
[-o|--output <trace-file-path>]
[--duration dd:hh:mm:ss]
# .NET Process Target (Optional)
[-n, --name <name>]
[-p|--process-id <pid>]
# Probe mode
[--probe]
Default collection behavior
When --providers, --profile, --clrevents, and --perf-events aren’t specified, collect-linux enables these profiles by default:
dotnet-common— lightweight .NET runtime diagnostics.cpu-sampling— kernel CPU sampling.
By default, all processes on the machine are traced. To trace only one process, use -n, --name <name> or -p|--process-id <PID>.
Options
Provider/Event Specification Options
--providers <list-of-comma-separated-providers>A comma-separated list of
EventPipeproviders to be enabled. These providers supplement any providers implied by--profile <list-of-comma-separated-profile-names>. If there's any inconsistency for a particular provider, this configuration takes precedence over the implicit configuration from--profileand--clrevents.This list of providers is in the form
Provider[,Provider]:Provideris in the form:KnownProviderName[:Flags[:Level[:KeyValueArgs]]]KeyValueArgsis in the form:[key1=value1][;key2=value2]
To learn more about some of the well-known providers in .NET, see Well-known Event Providers.
--clreventlevel <clreventlevel>Verbosity of CLR events to be emitted. This option only applies when
--clreventsis specified and not overridden by--profileor--providers. The following table shows the available event levels.String value Numeric value logalways0critical1error2warning3informational4verbose5--clrevents <clrevents>A list of CLR runtime provider keywords to enable separated by
+signs. This is a simple mapping that lets you specify event keywords via string aliases rather than their hex values. For example,dotnet-trace collect-linux --providers Microsoft-Windows-DotNETRuntime:3:4requests the same set of events asdotnet-trace collect-linux --clrevents gc+gchandle --clreventlevel informational. If the CLR runtime providerMicrosoft-Windows-DotNETRuntimeis also enabled through--providersor--profile, this option is ignored. The following table shows the list of available keywords:Keyword String Alias Keyword Hex Value gc0x1gchandle0x2assemblyloader0x4loader0x8jit0x10ngen0x20startenumeration0x40endenumeration0x80security0x400appdomainresourcemanagement0x800jittracing0x1000interop0x2000contention0x4000exception0x8000threading0x10000jittedmethodiltonativemap0x20000overrideandsuppressngenevents0x40000type0x80000gcheapdump0x100000gcsampledobjectallocationhigh0x200000gcheapsurvivalandmovement0x400000managedheapcollect0x800000gcheapandtypenames0x1000000gcsampledobjectallocationlow0x2000000perftrack0x20000000stack0x40000000threadtransfer0x80000000debugger0x100000000monitoring0x200000000codesymbols0x400000000eventsource0x800000000compilation0x1000000000compilationdiagnostic0x2000000000methoddiagnostic0x4000000000typediagnostic0x8000000000jitinstrumentationdata0x10000000000profiler0x20000000000waithandle0x40000000000allocationsampling0x80000000000You can read about the CLR provider in more detail on the .NET runtime provider reference documentation.
--perf-events <list-of-perf-events>A comma-separated list of perf events to include in the trace. Available events can be found under tracefs, which is typically mounted at
/sys/kernel/tracing, throughavailable_eventsfor all available events or through theevents/subdirectory for categorized events.Example:
--perf-events syscalls:sys_enter_execve,sched:sched_switch,sched:sched_wakeup--profile <list-of-comma-separated-profile-names>A profile is a predefined set of provider configurations for common tracing scenarios. Multiple profiles can be specified at a time, delimited by commas. Providers configured through
--providersoverride the profile's configuration. Similarly, if any profile configures the CLR runtime provider, it will override any configurations prescribed through--clrevents.When
--profile,--providers,--clrevents, and--perf-eventsare all omitted,dotnet-trace collect-linuxenables profilesdotnet-commonandcpu-samplingby default.Available profiles:
Profile Description dotnet-commonLightweight .NET runtime diagnostics designed to stay low overhead.
Includes GC, AssemblyLoader, Loader, JIT, Exceptions, Threading, JittedMethodILToNativeMap, and Compilation events
Equivalent to--providers "Microsoft-Windows-DotNETRuntime:0x100003801D:4".cpu-samplingKernel CPU sampling (perf-based), emitted as Universal.Events/cpu, for precise on-CPU attribution.thread-timeKernel thread context switches, emitted as Universal.Events/cswitch, for on/off-CPU and scheduler analysis.gc-verboseTracks GC collections and samples object allocations. gc-collectTracks GC collections only at very low overhead. databaseCaptures ADO.NET and Entity Framework database commands.
Trace Collection Options
-o|--output <trace-file-path>The output path for the collected trace data. If not specified, it defaults to
trace_<yyyyMMdd>_<HHmmss>.nettracefor the default machine-wide trace and to<appname>_<yyyyMMdd>_<HHmmss>.nettracefor a process-specific trace (--nameor--process-id)--duration <time-to-run>The time for the trace to run. Use the
dd:hh:mm:ssformat. For example00:00:00:05will run it for 5 seconds.
.NET Process Target Options
See Default collection behavior
-n, --name <name>The name of the process to collect the trace from.
-p|--process-id <PID>The process ID to collect the trace from.
Probe mode options
--probe [-n|--name] [-p|--process-id] [-o|--output <stdout|output-filename>]Probe .NET processes for support of the EventPipe UserEvents IPC command used by collect-linux, without collecting a trace. Results list supported processes first. Use '-o stdout' to print CSV (pid,processName,supportsCollectLinux) to the console, or '-o output-filename' to write the CSV. Probe a single process with -n|--name or -p|--process-id.
As running
collect-linuxin probe mode does not collect a trace, it does not require root permissions to run. It does not provide validation of the prerequisites, and .NET processes running on preview versions of .NET Runtime '10.0.0' are considered unsupported.
Note
To collect a trace using
dotnet-trace collect-linux, it needs to be run with root permissions (CAP_PERFMON/CAP_SYS_ADMIN). Otherwise, the tool will fail to collect events.
dotnet-trace convert
Converts nettrace traces to alternate formats for use with alternate trace analysis tools.
Synopsis
dotnet-trace convert [<input-filename>] [--format <Chromium|NetTrace|Speedscope>] [-h|--help] [-o|--output <output-filename>]
Arguments
<input-filename>Input trace file to be converted. Defaults to trace.nettrace.
Options
--format <Chromium|NetTrace|Speedscope>Sets the output format for the trace file conversion.
-o|--output <output-filename>Output filename. Extension of target format will be added.
Note
Converting nettrace files to chromium or speedscope files is irreversible. speedscope and chromium files don't have all the information necessary to reconstruct nettrace files. However, the convert command preserves the original nettrace file, so don't delete this file if you plan to open it in the future.
dotnet-trace ps
Lists the dotnet processes that traces can be collected from.
dotnet-trace 6.0.320703 and later, also display the command-line arguments that each process was started with, if available.
Note
To get full information for enumerated 64 bit processes, you need to use a 64-bit version of the dotnet-trace tool.
Synopsis
dotnet-trace ps [-h|--help]
Example
Suppose you start a long-running app using the command dotnet run --configuration Release. In another window, you run the dotnet-trace ps command. The output you'll see is as follows. The command-line arguments, if available, are shown in dotnet-trace version 6.0.320703 and later.
> 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
Lists pre-built tracing profiles with a description of what providers and filters are in each profile.
Synopsis
dotnet-trace list-profiles [-h|--help]
dotnet-trace report
Creates a report into stdout from a previously generated trace.
Synopsis
dotnet-trace report [-h|--help] <tracefile> [command]
Arguments
<tracefile>The file path for the trace being analyzed.
Commands
dotnet-trace report topN
Finds the top N methods that have been on the callstack the longest.
Synopsis
dotnet-trace report <tracefile> topN [-n|--number <n>] [--inclusive] [-v|--verbose] [-h|--help]
Options
-n|--number <n>
Gives the top N methods on the callstack.
--inclusive
Output the top N methods based on inclusive time. If not specified, exclusive time is used by default.
-v|--verbose
Output the parameters of each method in full. If not specified, parameters will be truncated.
Collect a trace with dotnet-trace
To collect traces using dotnet-trace collect:
Get the process identifier (PID) of the .NET Core application to collect traces from.
- On Windows, you can use Task Manager or the
tasklistcommand, for example. - On Linux, for example, the
pscommand. - dotnet-trace ps
- On Windows, you can use Task Manager or the
Run the following command:
dotnet-trace collect --process-id <PID>The preceding command generates output similar to the following:
No profile or providers specified, defaulting to trace profiles 'dotnet-common' + 'dotnet-sampled-thread-time'. Provider Name Keywords Level Enabled By Microsoft-Windows-DotNETRuntime 0x000000100003801D Informational(4) --profile Microsoft-DotNETCore-SampleProfiler 0x0000F00000000000 Informational(4) --profile Process : <full-path-to-process-being-trace> Output File : <process>_20251007_154557.nettrace [00:00:00:02] Recording trace 178.172 (KB) Press <Enter> or <Ctrl+C> to exit... Stopping the trace. This may take several minutes depending on the application being traced. Trace completed.Stop collection by pressing the Enter key.
dotnet-tracewill finish logging events to the.nettracefile.
Launch a child application and collect a trace from its startup using dotnet-trace
Sometimes it may be useful to collect a trace of a process from its startup. For apps running .NET 5 or later, it is possible to do this by using dotnet-trace.
This will launch hello.exe with arg1 and arg2 as its command-line arguments and collect a trace from its runtime startup:
dotnet-trace collect -- hello.exe arg1 arg2
The preceding command generates output similar to the following:
No profile or providers specified, defaulting to trace profiles 'dotnet-common' + 'dotnet-sampled-thread-time'.
Provider Name Keywords Level Enabled By
Microsoft-Windows-DotNETRuntime 0x000000100003801D Informational(4) --profile
Microsoft-DotNETCore-SampleProfiler 0x0000F00000000000 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...
You can stop collecting the trace by pressing <Enter> or <Ctrl + C> key. Doing this will also exit hello.exe.
Note
Launching hello.exe via dotnet-trace will redirect its input/output and you won't be able to interact with it on the console by default. Use the --show-child-io switch to interact with its stdin/stdout.
Exiting the tool via CTRL+C or SIGTERM will safely end both the tool and the child process.
If the child process exits before the tool, the tool will exit as well and the trace should be safely viewable.
Use diagnostic port to collect a trace from app startup
Diagnostic port is a runtime feature added in .NET 5 that allows you to start tracing from app startup. To do this using dotnet-trace, you can either use dotnet-trace collect -- <command> as described in the examples above, or use the --diagnostic-port option.
Using dotnet-trace <collect|monitor> -- <command> to launch the application as a child process is the simplest way to quickly trace the application from its startup.
However, when you want to gain a finer control over the lifetime of the app being traced (for example, monitor the app for the first 10 minutes only and continue executing) or if you need to interact with the app using the CLI, using --diagnostic-port option allows you to control both the target app being monitored and dotnet-trace.
The command below makes
dotnet-tracecreate a diagnostics socket namedmyport.sockand wait for a connection.dotnet-trace collect --diagnostic-port myport.sockOutput:
Waiting for connection on myport.sock Start an application with the following environment variable: DOTNET_DiagnosticPorts=/home/user/myport.sockIn a separate console, launch the target application with the environment variable
DOTNET_DiagnosticPortsset to the value in thedotnet-traceoutput.export DOTNET_DiagnosticPorts=/home/user/myport.sock ./my-dotnet-app arg1 arg2This should then enable
dotnet-traceto start tracingmy-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.Important
Launching your app with
dotnet runcan be problematic because the dotnet CLI may spawn many child processes that are not your app and they can connect todotnet-tracebefore your app, leaving your app to be suspended at runtime. It is recommended you directly use a self-contained version of the app or usedotnet execto launch the application.
(Linux-only) Collect a machine-wide trace using dotnet-trace
This example captures CPU samples for all processes on the machine. Any processes running .NET 10+ will also include some additional lightweight events describing GC, JIT, and Assembly loading behavior.
$ sudo dotnet-trace collect-linux
==========================================================================================
The collect-linux verb is a new preview feature and relies on an updated version of the
.nettrace file format. The latest PerfView release supports these trace files but other
ways of using the trace file may not work yet. For more details, see the docs at
https://learn.microsoft.com/dotnet/core/diagnostics/dotnet-trace.
==========================================================================================
No providers, profiles, ClrEvents, or PerfEvents were specified, defaulting to trace profiles 'dotnet-common' + 'cpu-sampling'.
Provider Name Keywords Level Enabled By
Microsoft-Windows-DotNETRuntime 0x000000100003801D Informational(4) --profile
Linux Perf Events Enabled By
cpu-sampling --profile
Output File : <path-to-nettrace>trace_20251008_181939.nettrace
[00:00:00:03] Recording trace.
Press <Enter> or <Ctrl-C> to exit...
Recording stopped.
Resolving symbols.
Finished recording trace.
Trace written to <path-to-nettrace>trace_20251008_181939.nettrace
For environments with multiple .NET versions installed, running collect-linux in probe mode helps discern whether a .NET process is capable of being traced with collect-linux.
$ dotnet-trace collect-linux --probe
==========================================================================================
The collect-linux verb is a new preview feature and relies on an updated version of the
.nettrace file format. The latest PerfView release supports these trace files but other
ways of using the trace file may not work yet. For more details, see the docs at
https://learn.microsoft.com/dotnet/core/diagnostics/dotnet-trace.
==========================================================================================
Probing .NET processes for support of the EventPipe UserEvents IPC command used by collect-linux. Requires runtime '10.0.0' or later.
.NET processes that support the command:
3802935 MyApp
.NET processes that do NOT support the command:
3809123 dotnet - Detected runtime: '10.0.0-rc.1.25451.107'
View the trace captured from dotnet-trace
On Windows, you can view .nettrace files in Visual Studio or PerfView for analysis.
On Linux, you can view the trace by changing the output format of dotnet-trace to speedscope. Change the output file format by using the -f|--format option. You can choose between nettrace (the default option) and speedscope. The option -f speedscope will make dotnet-trace produce a speedscope file. Speedscope files can be opened at https://www.speedscope.app.
For traces collected on non-Windows platforms, you can also move the trace file to a Windows machine and view it in Visual Studio or PerfView.
Note
The .NET Core runtime generates traces in the nettrace format. The traces are converted to speedscope (if specified) after the trace is completed. Since some conversions may result in loss of data, the original nettrace file is preserved next to the converted file.
Use .rsp file to avoid typing long commands
You can launch dotnet-trace with an .rsp file that contains the arguments to pass. This can be useful when enabling providers that expect lengthy arguments or when using a shell environment that strips characters.
For example, the following provider can be cumbersome to type out each time you want to trace:
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
In addition, the previous example contains " as part of the argument. Because quotes are not handled equally by each shell, you may experience various issues when using different shells. For example, the command to enter in zsh is different to the command in cmd.
Instead of typing this each time, you can save the following text into a file called 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
Once you've saved myprofile.rsp, you can launch dotnet-trace with this configuration using the following command:
dotnet-trace @myprofile.rsp