EventPipe

EventPipe è un componente di runtime che può essere usato per raccogliere dati sulla traccia, simili a ETW o LTTng. L'obiettivo di EventPipe è consentire agli sviluppatori di .NET di tenere traccia facilmente delle proprie applicazioni .NET senza doversi basare su componenti nativi del sistema operativo specifici della piattaforma, ad esempio ETW o LTTng.

EventPipe è il meccanismo dietro molti degli strumenti di diagnostica e può essere usato per l'utilizzo di eventi generati dal runtime, nonché eventi personalizzati scritti con EventSource.

Questo articolo è una panoramica generale di EventPipe. Descrive quando e come usare EventPipe e come configurarlo in base alle proprie esigenze.

Nozioni di base su EventPipe

EventPipe aggrega gli eventi generati dai componenti di runtime, ad esempio il compilatore Just-In-Time o il Garbage Collector, e gli eventi scritti dalle istanze di EventSource nelle librerie e nel codice utente.

Gli eventi vengono quindi serializzati nel formato di file .nettrace e possono essere scritti direttamente in un file o trasmessi tramite una porta di diagnostica per l'utilizzo out-of-process.

Per altre informazioni sul formato di serializzazione EventPipe, vedere la documentazione sul formato EventPipe.

Confronto tra EventPipe e ETW/LTTng

EventPipe fa parte del runtime .NET (CoreCLR) ed è progettato per funzionare allo stesso modo in tutte le piattaforme supportate da .NET Core. Ciò consente agli strumenti di traccia basati su EventPipe, ad esempio dotnet-counters, dotnet-gcdump e dotnet-trace, di funzionare senza problemi tra le piattaforme.

Tuttavia, poiché EventPipe è un componente predefinito del runtime, il suo ambito è limitato al codice gestito e al runtime stesso. EventPipe non può essere usato per tenere traccia di alcuni eventi di livello inferiore, ad esempio la risoluzione dello stack di codice nativo o il recupero di vari eventi del kernel. Se si usa l'interoperabilità C/C++ nella propria app o si vuole tenere traccia del runtime stesso (scritto in C++) o si vuole una diagnostica più approfondita nel comportamento dell'app che richiede eventi kernel (ovvero eventi di cambio di contesto del thread nativo) occorre usare ETW o perf/LTTng.

Un'altra differenza principale tra EventPipe e ETW/LTTng è il requisito dei privilegi di amministratore/radice. Per tracciare un'applicazione usando ETW o LTTng, è necessario essere un amministratore/radice. Se si usa EventPipe, è possibile tracciare le applicazioni purché l'analisi (ad esempio, dotnet-trace) venga eseguita come lo stesso utente che ha avviato l'applicazione.

La tabella seguente contiene un riepilogo delle differenze tra EventPipe e ETW/LTTng.

Funzionalità EventPipe ETW LTTng
Multipiattaforma No (solo in Windows) No (solo nelle distribuzioni Linux supportate)
Richiede privilegio amministratore/radice No
Può ottenere eventi del sistema operativo/kernel No
Può risolvere gli stack di chiamate nativi No

Usare EventPipe per tenere traccia dell'applicazione .NET

È possibile usare EventPipe per tenere traccia dell'applicazione .NET in molti modi:

Dopo aver prodotto un file nettrace contenente gli eventi EventPipe, è possibile visualizzare il file in PerfView o Visual Studio. Nelle piattaforme diverse da Windows è possibile convertire il file nettrace in un formato di traccia speedscope o Chromium usando il comando dotnet-trace convert e visualizzarlo con Speedscope o Chrome DevTools.

È anche possibile analizzare le tracce EventPipe a livello di programmatico con TraceEvent.

Strumenti che usano EventPipe

Questo è il modo più semplice per usare EventPipe per tracciare l'applicazione. Per altre informazioni su come usare ognuno di questi strumenti, vedere la documentazione di ogni strumento.

  • dotnet-counters consente di monitorare e raccogliere varie metriche generate dal runtime e dalle librerie principali di .NET, nonché metriche personalizzate che è possibile scrivere.

  • dotnet-gcdump consente di raccogliere dump di arresto anomalo dell'heap GC dei processi in tempo reale per l'analisi dell'heap gestito di un'applicazione.

  • dotnet-trace consente di raccogliere tracce di applicazioni da analizzare per ottenere prestazioni.

Traccia delle variabili di ambiente

Il meccanismo preferito per l'uso di EventPipe consiste nell'usare dotnet-trace o la libreria Microsoft.Diagnostics.NETCore.Client.

È tuttavia possibile usare le variabili di ambiente seguenti per configurare una sessione di EventPipe in un'app e scrivere la traccia direttamente in un file. Per arrestare la traccia, uscire dall'applicazione.

  • DOTNET_EnableEventPipe: impostare su 1 per avviare una sessione EventPipe che scrive direttamente in un file. Il valore predefinito è 0.

  • DOTNET_EventPipeOutputPath: il percorso del file di traccia EventPipe di output quando è configurato per l'esecuzione tramite DOTNET_EnableEventPipe. Il valore predefinito è trace.nettrace, che verrà creato nella stessa directory da cui è in esecuzione l'app.

    Nota

    A partire da .NET 6, le istanze della stringa {pid} in DOTNET_EventPipeOutputPath vengono sostituite con l'ID processo del processo di cui tenere traccia.

  • DOTNET_EventPipeCircularMB: il valore esadecimale che rappresenta le dimensioni del buffer interno di EventPipe in megabyte. Questo valore di configurazione viene usato solo quando EventPipe è configurato per l'esecuzione tramite DOTNET_EnableEventPipe. La dimensione predefinita del buffer è 1024 MB, che si traduce in questa variabile di ambiente impostata su 400, poiché 0x400 == 1024.

    Nota

    Se il processo di destinazione scrive gli eventi troppo frequentemente, può eseguire l'overflow di questo buffer e alcuni eventi potrebbero essere eliminati. Se vengono eliminati troppi eventi, è possibile aumentare le dimensioni del buffer per verificare se il numero di eventi eliminati si riduce. Se il numero di eventi eliminati non diminuisce con una dimensione del buffer maggiore, può essere dovuto a un lettore lento che impedisce lo scaricamento dei buffer del processo di destinazione.

  • DOTNET_EventPipeProcNumbers: impostare questa opzione su 1 per abilitare l'acquisizione dei numeri del processore nelle intestazioni di evento EventPipe. Il valore predefinito è 0.

  • DOTNET_EventPipeConfig: configurare la configurazione della sessione EventPipe all'avvio di una sessione EventPipe con DOTNET_EnableEventPipe. La sintassi è la seguente:

    <provider>:<keyword>:<level>

    È anche possibile specificare più provider concatenandoli con una virgola:

    <provider1>:<keyword1>:<level1>,<provider2>:<keyword2>:<level2>

    Se questa variabile di ambiente non è impostata ma EventPipe è abilitata da DOTNET_EnableEventPipe, inizierà la traccia abilitando i provider seguenti con le parole chiave e i livelli seguenti:

    • Microsoft-Windows-DotNETRuntime:4c14fccbd:5
    • Microsoft-Windows-DotNETRuntimePrivate:4002000b:5
    • Microsoft-DotNETCore-SampleProfiler:0:5

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

Nota

.NET 6 standardizza il prefisso DOTNET_ anziché quello di COMPlus_ per le variabili di ambiente che configurano il comportamento in fase di esecuzione di .NET. Tuttavia, il prefisso diCOMPlus_ continuerà a funzionare. Se si usa una versione precedente del runtime .NET, è comunque consigliabile usare il prefisso COMPlus_ per le variabili di ambiente.