Utilità di analisi delle prestazioni dotnet-trace

Questo articolo si applica a: ✔️ dotnet-trace 3.0.47001 e versioni successive

Installare

Esistono due modi per scaricare e installare dotnet-trace:

Riepilogo

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

Descrizione

Lo strumento dotnet-trace:

  • è uno strumento .NET Core multipiattaforma.
  • Abilita la raccolta di analisi .NET Core di un processo in esecuzione senza un profiler nativo.
  • Si basa sul EventPipe del runtime di .NET Core.
  • Offre la stessa esperienza in Windows, Linux o macOS.

Opzioni

  • -h|--help

    Mostra la Guida della riga di comando.

  • --version

    Visualizza la versione dell'utilità dotnet-trace.

  • --duration

    Durata dell'esecuzione dell’analisi. --duration 00:00:00:05 verrà eseguito per 5 secondi.

Comandi

Comando
dotnet-trace collect
dotnet-trace convert
dotnet-trace ps
dotnet-trace list-profiles
dotnet-trace report

dotnet-trace collect

Raccoglie un’analisi di diagnostica da un processo in esecuzione o avvia un processo figlio e l’analisi (.NET 5 o versione successiva). Per fare in modo che lo strumento esegua un processo figlio e lo tracci dall'avvio, aggiungi -- al comando collect.

Riepilogo

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

Opzioni

  • --buffersize <size>

    Imposta le dimensioni del buffer in memoria, in megabyte. Valore predefinito 256 MB.

    Nota

    Se il processo di destinazione genera eventi più velocemente di quanto possano essere scritti su disco, questo buffer potrebbe essere sovraccaricato e alcuni eventi potrebbero venire eliminati. È possibile risolvere questo problema aumentando le dimensioni del buffer o riducendo il numero di eventi da registrare.

  • --clreventlevel <clreventlevel>

    Dettaglio degli eventi CLR da generare. Nella tabella seguente vengono illustrati i livelli di evento disponibili.

    Valore stringa Valore numerico
    logalways 0
    critical 1
    error 2
    warning 3
    informational 4
    verbose 5
  • --clrevents <clrevents>

    Elenco delle parole chiave del provider di runtime CLR da abilitare separate da segni +. Si tratta di un mapping semplice che ti consente di specificare parole chiave evento tramite alias stringa anziché tramite i relativi valori hex. Ad esempio, dotnet-trace collect --providers Microsoft-Windows-DotNETRuntime:3:4 richiede lo stesso set di eventi di dotnet-trace collect --clrevents gc+gchandle --clreventlevel informational. La tabella seguente mostra l'elenco delle parole chiave disponibili:

    Alias stringa parola chiave Valore hex parola chiave
    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

    Per altre informazioni sul provider CLR, vedi la documentazione di riferimento del provider di runtime .NET.

  • --format {Chromium|NetTrace|Speedscope}

    Imposta il formato di output per la conversione del file di traccia. Il valore predefinito è NetTrace.

  • -n, --name <name>

    Nome del processo da cui raccogliere la traccia.

  • --diagnostic-port <path-to-port>

    Nome della porta di diagnostica da creare. Per sapere come usare questa opzione per raccogliere una traccia dall'avvio dell'app, vedi Usare la porta di diagnostica per raccogliere una traccia dall'avvio dell'app.

  • --duration <time-to-run>

    Ora di esecuzione della traccia. Usa il formato dd:hh:mm:ss. Ad esempio 00:00:00:05 la eseguirà per 5 secondi.

  • -o|--output <trace-file-path>

    Percorso di output per i dati di traccia raccolti. Se non è specificato, per impostazione predefinita è <appname>_<yyyyMMdd>_<HHmmss>.nettrace, ad esempio “myapp_20210315_111514.nettrace”.

  • -p|--process-id <PID>

    ID processo da cui raccogliere la traccia.

  • --profile <profile-name>

    Set predefinito denominato di configurazioni del provider che consente di specificare in modo conciso gli scenari di traccia comuni. Sono disponibili i profili seguenti:

Profilo Descrizione
cpu-sampling Utile per tenere traccia dell'utilizzo della CPU e delle informazioni generali sul runtime .NET. Questa è l'opzione predefinita se non viene specificato alcun profilo o provider.
gc-verbose Tiene traccia delle raccolte GC e delle allocazioni di oggetti di esempio.
gc-collect Tiene traccia delle raccolte GC solo a un sovraccarico molto basso.
  • --providers <list-of-comma-separated-providers>

    Elenco delimitato da virgole di provider EventPipe da abilitare. Questi provider integrano tutti i provider impliciti in --profile <profile-name>. Se si verifica un'incoerenza per un provider specifico, questa configurazione ha la precedenza sulla configurazione implicita del profilo.

    Questo elenco di provider è nel formato:

    • Provider[,Provider]
    • Provider è nel formato: KnownProviderName[:Flags[:Level][:KeyValueArgs]].
    • KeyValueArgs è nel formato: [key1=value1][;key2=value2].

    Per altre informazioni su alcuni dei provider noti in .NET, vedere Provider di eventi noti.

  • -- <command> (per le applicazioni di destinazione che eseguono .NET 5 o versioni successive)

    Dopo i parametri di configurazione della raccolta, l'utente può accodare -- seguito da un comando per avviare un'applicazione .NET con almeno un runtime 5.0. Ciò può risultare utile durante la diagnosi dei problemi che si verificano all'inizio del processo, ad esempio problemi di prestazioni all’avvio o relativi al caricatore di assembly ed errori binder.

    Nota

    L'uso di questa opzione monitora il primo processo .NET che comunica di nuovo allo strumento, ovvero se il comando avvia più applicazioni .NET, raccoglierà solo la prima app. Pertanto, è consigliabile usare questa opzione nelle applicazioni autonome o usando l'opzione dotnet exec <app.dll>.

  • --show-child-io

    Mostra i flussi di input e output di un processo figlio avviato nella console corrente.

  • --resume-runtime

    Riprendere il runtime dopo l'inizializzazione della sessione, il valore predefinito è true. Disabilitare la ripresa del runtime usando --resume-runtime:false.

  • --stopping-event-provider-name

    Stringa, analizzata così come è, che interromperà l’analisi al raggiungimento di un evento con il nome del provider corrispondente. Per un evento di arresto più specifico, specificare anche --stopping-event-event-name e/o --stopping-event-payload-filter. Ad esempio, --stopping-event-provider-name Microsoft-Windows-DotNETRuntime per arrestare l’analisi al raggiungimento del primo evento generato dal provider di eventi Microsoft-Windows-DotNETRuntime.

  • --stopping-event-event-name

    Stringa, analizzata così come è, che interromperà l’analisi al raggiungimento di un evento con il nome dell’evento corrispondente. --stopping-event-provider-name deve essere impostato. Per un evento di arresto più specifico, specificare anche --stopping-event-payload-filter. Ad esempio, --stopping-event-provider-name Microsoft-Windows-DotNETRuntime --stopping-event-event-name Method/JittingStarted per arrestare l’analisi al raggiungimento del primo evento Method/JittingStarted generato dal provider di eventi Microsoft-Windows-DotNETRuntime.

  • --stopping-event-payload-filter

    Stringa, analizzata come coppie [payload_field_name]:[payload_field_value] separate da virgole, che interromperà l’analisi al raggiungimento di un evento contenente tutte le coppie di payload specificate. --stopping-event-provider-name e --stopping-event-event-name devono essere impostati. Ad esempio, --stopping-event-provider-name Microsoft-Windows-DotNETRuntime --stopping-event-event-name Method/JittingStarted --stopping-event-payload-filter MethodNameSpace:Program,MethodName:OnButtonClick per arrestare l’analisi al primo evento Method/JittingStarted per il metodo OnButtonClick nello spazio dei nomi Program generato dal provider di eventi Microsoft-Windows-DotNETRuntime.

Nota

  • L'arresto dell’analisi può richiedere molto tempo (fino ad alcuni minuti) per le applicazioni di grandi dimensioni. Il runtime deve inviare la cache dei tipi per tutto il codice gestito acquisito nell’analisi.
  • In Linux e macOS questo comando prevede che l'applicazione di destinazione e dotnet-trace condividano la stessa variabile di ambiente TMPDIR. In caso contrario, il comando raggiungerà il timeout.
  • Per raccogliere un’analisi utilizzando dotnet-trace, è necessario che venga eseguito come stesso utente che esegue il processo target o come radice. In caso contrario, lo strumento non riuscirà a stabilire una connessione con il processo di destinazione.
  • Se si verifica un'eccezione non gestita durante l'esecuzione di dotnet-trace collect, viene generata un’analisi incompleta. Se la tua priorità è trovare la causa radice dell'eccezione, accedi a Raccogli dump in caso di arresto anomalo. In seguito all'eccezione non gestita, l’analisi viene troncata quando il runtime viene arrestato per evitare altri comportamenti indesiderati, come un blocco o un danneggiamento dei dati. Anche se l’analisi è incompleta, puoi comunque aprirla per vedere cos’ha causato l’errore. Tuttavia, mancheranno le informazioni di rundown (questo avviene alla fine di un’analisi) e gli stack potrebbero non essere risolti (a seconda dei provider attivati). Apri l’analisi eseguendo PerfView con il flag /ContinueOnError nella riga di comando. I log conterranno anche il percorso in cui è stata generata l'eccezione.
  • Quando si specifica un evento di arresto tramite le opzioni --stopping-event-*, poiché EventStream viene analizzato in modo asincrono, ci saranno alcuni eventi che passano tra il momento in cui viene analizzato un evento di traccia corrispondente alle opzioni di evento di arresto specificate e l’arresto di EventPipeSession.

dotnet-trace convert

Converte le analisi nettrace in formati alternativi, da utilizzare con strumenti di analisi di traccia alternativi.

Riepilogo

dotnet-trace convert [<input-filename>] [--format <Chromium|NetTrace|Speedscope>] [-h|--help] [-o|--output <output-filename>]

Argomenti

  • <input-filename>

    File di traccia di input da convertire. L'impostazione predefinita è trace.nettrace.

Opzioni

  • --format <Chromium|NetTrace|Speedscope>

    Imposta il formato di output per la conversione del file di traccia.

  • -o|--output <output-filename>

    Nome file di output. Verrà aggiunta l'estensione del formato di destinazione.

Nota

La conversione di file nettrace in file chromium o speedscope è irreversibile. I file speedscope e chromium non hanno tutte le informazioni necessarie per ricostruire i file nettrace. Tuttavia, il comando convert mantiene il file nettrace originale, quindi non eliminare questo file se prevedi di aprirlo in futuro.

dotnet-trace ps

Elenca i processi dotnet da cui è possibile raccogliere le tracce. dotnet-trace 6.0.320703 e versioni successive mostrano anche gli argomenti della riga di comando con cui è stato avviato ogni processo, se disponibile.

Nota

Per ottenere informazioni complete per i processi a 64 bit enumerati, è necessario usare una versione a 64 bit dello dotnet-trace strumento.

Riepilogo

dotnet-trace ps [-h|--help]

Esempio

Si supponga di avviare un'app a esecuzione prolungata usando il comando dotnet run --configuration Release. In un'altra finestra si esegue il comando dotnet-trace ps. L'output visualizzato è il seguente. Gli argomenti della riga di comando, se disponibili, vengono visualizzati nella versione dotnet-trace 6.0.320703 e successive.

> 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

Elenca i profili di analisi predefiniti con una descrizione dei provider e dei filtri presenti in ogni profilo.

Riepilogo

dotnet-trace list-profiles [-h|--help]

dotnet-trace report

Crea un report in stdout da una traccia generata in precedenza.

Riepilogo

dotnet-trace report [-h|--help] <tracefile> [command]

Argomenti

  • <tracefile>

    Percorso del file della traccia analizzata.

Comandi

dotnet-trace report topN

Trova i primi N metodi che sono stati nello stack di chiamate più lungo.

Riepilogo
dotnet-trace report <tracefile> topN [-n|--number <n>] [--inclusive] [-v|--verbose] [-h|--help]
Opzioni
  • -n|--number <n>

Fornisce i primi N metodi nello stack di chiamate.

  • --inclusive

Restituisce i primi N metodi in base al tempo inclusivo. Se non specificato, il tempo esclusivo viene utilizzato per impostazione predefinita.

  • -v|--verbose

Restituisci i parametri di ogni metodo in modo completo. Se non specificato, i parametri verranno troncati.

Raccogli una traccia con dotnet-trace

Per raccogliere tracce usando dotnet-trace:

  • Ottieni l'identificatore del processo (PID) dell'applicazione .NET Core da cui raccogliere le tracce.

    • Ad esempio, in Windows è possibile usare Gestione attività o il comando tasklist.
    • In Linux, ad esempio, il comando ps.
    • dotnet-trace ps
  • Esegui questo comando:

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

    Il comando precedente genera un output simile al seguente:

    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)
    
  • Interrompi la raccolta premendo il tasto <Enter>. dotnet-trace terminerà la registrazione degli eventi nel file trace.nettrace.

Avvia un'applicazione figlio e raccogli una traccia dall'avvio usando dotnet-trace

A volte può essere utile raccogliere una traccia di un processo dall'avvio. Per le app che eseguono .NET 5 o versioni successive, è possibile eseguire questa operazione usando dotnet-trace.

Verrà avviato hello.exe con arg1 e arg2 come argomenti della riga di comando e verrà raccolta una traccia dall'avvio del runtime:

dotnet-trace collect -- hello.exe arg1 arg2

Il comando precedente genera un output simile al seguente:

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

Puoi interrompere la raccolta della traccia premendo i tasto <Enter> o <Ctrl + C>. In questo modo si uscirà anche da hello.exe.

Nota

L'avvio di hello.exe tramite dotnet-trace reindirizzerà l'input/output e per impostazione predefinita non sarà possibile interagire con esso nella console. Usa l'opzione --show-child-io per interagire con stdin/stdout. L'uscita dallo strumento tramite CTRL+C o SIGTERM terminerà in modo sicuro sia lo strumento che il processo figlio. Se il processo figlio viene chiuso prima dello strumento, lo strumento verrà chiuso e la traccia dovrebbe essere visualizzabile in modo sicuro.

Usa la porta di diagnostica per raccogliere una traccia dall'avvio dell'app

La porta di diagnostica è una funzionalità di runtime aggiunta in .NET 5 che ti consente di avviare il tracciamento dall'avvio dell'app. A tale scopo, usando dotnet-trace, è possibile usare dotnet-trace collect -- <command> come descritto negli esempi precedenti oppure usare l'opzione --diagnostic-port.

L'uso di dotnet-trace <collect|monitor> -- <command> per avviare l'applicazione come processo figlio è il modo più semplice per tracciare rapidamente l'applicazione dall'avvio.

Tuttavia, quando si vuole ottenere un controllo più preciso sulla durata dell'app tracciata (ad esempio, monitorare l'app solo per i primi 10 minuti e continuare l'esecuzione) o se è necessario interagire con l'app usando l'interfaccia della riga di comando, l'opzione --diagnostic-port ti consente di controllare sia l'app di destinazione monitorata che dotnet-trace.

  1. Il comando seguente fa sì che dotnet-trace crei un socket di diagnostica denominato myport.sock e attenda una connessione.

    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 una console separata, avvia l'applicazione di destinazione con la variabile di ambiente DOTNET_DiagnosticPorts impostata sul valore nell'output dotnet-trace.

    export DOTNET_DiagnosticPorts=/home/user/myport.sock
    ./my-dotnet-app arg1 arg2
    

    Verrà quindi abilitato dotnet-trace per avviare il tracciamento 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.
    

    Importante

    L'avvio dell'app con dotnet run può essere problematico perché l'interfaccia della riga di comando dotnet può generare molti processi figlio che non sono l'app e questi possono connettersi a dotnet-trace prima dell'app, lasciandola sospesa in fase di esecuzione. È consigliabile usare direttamente una versione autonoma dell'app o usare dotnet exec per avviare l'applicazione.

Visualizzare la traccia acquisita da dotnet-trace

In Windows puoi visualizzare i file .nettrace in Visual Studio o PerfView per l'analisi.

In Linux puoi visualizzare la traccia modificando il formato di output di dotnet-trace in speedscope. Modifica il formato del file di output tramite l'opzione -f|--format. Puoi scegliere tra nettrace (opzione predefinita) e speedscope. L'opzione -f speedscope farà sì che dotnet-trace produca un file speedscope. I file Speedscope possono essere aperti in https://www.speedscope.app.

Per le tracce raccolte su piattaforme non Windows, puoi anche spostare il file di traccia in un computer Windows e visualizzarlo in Visual Studio o PerfView.

Nota

Il runtime .NET Core genera tracce nel formato nettrace. Le tracce vengono convertite in ambito rapido (se specificato) dopo il completamento della traccia. Poiché alcune conversioni possono comportare la perdita di dati, il file originale nettrace viene conservato accanto al file convertito.

Usa il file .rsp per evitare di digitare comandi lunghi

È possibile avviare dotnet-trace con un file .rsp che contiene gli argomenti da passare. Ciò può essere utile quando si abilitano provider che prevedono argomenti lunghi o quando si usa un ambiente della shell che rimuove i caratteri.

Ad esempio, il provider seguente può essere complesso da digitare ogni volta che intendi tracciare:

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

Inoltre, l'esempio precedente contiene " come parte dell'argomento. Poiché le virgolette non vengono gestite allo stesso modo da ogni shell, è possibile che si verifichino vari problemi quando si usano shell diverse. Ad esempio, il comando da immettere in zsh è diverso dal comando in cmd.

Anziché digitarlo ogni volta, puoi salvare il testo seguente in un file denominato 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

Dopo aver salvato myprofile.rsp, puoi avviare dotnet-trace con questa configurazione usando il comando seguente:

dotnet-trace @myprofile.rsp

Vedi anche