dotnet-trace diagnostic tool - .NET CLI - .NET (original) (raw)

This article applies to: ✔️ dotnet-trace 9.0.625801 and later versions

Install

There are two ways to download and install dotnet-trace:

dotnet tool install --global dotnet-trace  

Synopsis

dotnet-trace [-h, --help] [--version] <command>

Description

The dotnet-trace tool:

Options

Commands

Command
dotnet-trace collect
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 <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>]

Options

Starts and connects to it. Requires to be installed. Run dotnet-dsrouter -h for more information.

Profile Description
cpu-sampling Useful for tracking CPU usage and general .NET runtime information. This is the default option if no profile or providers are specified.
gc-verbose Tracks GC collections and samples object allocations.
gc-collect Tracks GC collections only at very low overhead.

Note

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

Options

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.

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

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

Gives the top N methods on the callstack.

Output the top N methods based on inclusive time. If not specified, exclusive time is used by default.

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:

dotnet-trace collect --process-id <PID>  

The preceding command generates output similar to the following:

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)  

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 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...

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.

  1. The command below makes dotnet-trace create a diagnostics socket named myport.sock and wait for a connection.
    dotnet-trace collect --diagnostic-port myport.sock  
     

    Output:

    Waiting for connection on myport.sock  
    Start an application with the following environment variable: DOTNET_DiagnosticPorts=/home/user/myport.sock  
     
  2. In a separate console, launch the target application with the environment variable DOTNET_DiagnosticPorts set to the value in the dotnet-trace output.
    export DOTNET_DiagnosticPorts=/home/user/myport.sock  
    ./my-dotnet-app arg1 arg2  
     

    This should then enable dotnet-trace to start tracing 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.  
     

    Important
    Launching your app with dotnet run can be problematic because the dotnet CLI may spawn many child processes that are not your app and they can connect to dotnet-trace before your app, leaving your app to be suspended at run time. It is recommended you directly use a self-contained version of the app or use dotnet exec to launch the application.

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

See also