Tracciamento distribuito nelle librerie di System.Net
Tracciamento distribuito è una tecnica diagnostica che consente agli ingegneri di localizzare guasti e problemi di prestazioni all'interno delle applicazioni, in particolare quelli distribuiti tra più computer o processi. Questa tecnica tiene traccia delle richieste tramite un'applicazione correlando il lavoro svolto da componenti diversi e separandolo da altre operazioni che l'applicazione potrebbe eseguire per le richieste simultanee. Ad esempio, una richiesta a un servizio Web tipico potrebbe essere ricevuta prima da un servizio di bilanciamento del carico e quindi inoltrata a un processo del server Web, che esegue quindi diverse query a un database. La traccia distribuita consente ai tecnici di distinguere se uno di questi passaggi non è riuscito e il tempo necessario per ogni passaggio. Può anche registrare i messaggi generati da ogni passaggio durante l'esecuzione.
Il sistema di traccia in .NET è progettato per funzionare con OpenTelemetry (OTel) e usa OTel per esportare i dati nei sistemi di monitoraggio. Il tracciamento in .NET viene implementato usando le API di System.Diagnostics, in cui un'unità di lavoro è rappresentata dalla classe System.Diagnostics.Activity, che corrisponde a una traccia dell'intervallo OTel. OpenTelemetry definisce uno schema di denominazione standard a livello di settore per intervalli (attività) insieme ai relativi attributi (tag), noti come convenzioni semantiche . I dati di telemetria .NET usano convenzioni semantiche esistenti laddove possibile.
Nota
I termini e attività sono sinonimi in questo articolo. Nel contesto del codice .NET, fanno riferimento a un'istanza di System.Diagnostics.Activity. Non confondere l'intervallo OTel con System.Span<T>.
Mancia
Per un elenco completo di tutte le attività predefinite insieme ai relativi tag/attributi, vedere attività predefinite in .NET.
Strumentazione
Per generare tracce, le librerie di System.Net vengono instrumentate con origini ActivitySource predefinite, che creano oggetti Activity per tenere traccia del lavoro eseguito. Le attività vengono create solo se sono presenti ascoltatori iscritti al ActivitySource.
La strumentazione predefinita si è evoluta con le versioni di .NET.
- In .NET 8 e versioni precedenti, la strumentazione è limitata alla creazione di un'attività di richiesta client HTTP vuota . Ciò significa che gli utenti devono basarsi sulla libreria
OpenTelemetry.Instrumentation.Http
per popolare l'attività con le informazioni (ad esempio, tag) necessarie per generare tracce utili. - .NET 9 ha esteso la strumentazione emettendo il nome, lo stato, le informazioni sulle eccezioni e i tag più importanti secondo le convenzioni semantiche OTel per il client HTTP nell'attività di richiesta del client HTTP. Ciò significa che in .NET 9+, la dipendenza
OpenTelemetry.Instrumentation.Http
può essere omessa, a meno che non siano necessarie funzionalità più avanzate come arricchimento. - .NET 9 ha anche introdotto tracce di connessione sperimentali, aggiungendo nuove attività nelle librerie
System.Net
per supportare la diagnosi dei problemi di connessione.
Raccogliere tracce di System.Net
Al livello più basso, la raccolta di tracce è supportata tramite il metodo AddActivityListener, che registra ActivityListener oggetti contenenti la logica definita dall'utente.
Tuttavia, in qualità di sviluppatore di applicazioni, è probabile che si preferisca basarsi sull'ecosistema avanzato basato sulle funzionalità fornite dal OpenTelemetry .NET SDK per raccogliere, esportare e monitorare le tracce.
- Per ottenere informazioni fondamentali sulla raccolta di tracce con OTel, vedere la guida su raccolta di tracce tramite OpenTelemetry.
- Per tempo di produzione raccolta e monitoraggio delle tracce, è possibile usare OpenTelemetry con Prometheus, Grafana e Jaeger o con Monitoraggio di Azure e Application Insights. Tuttavia, questi strumenti sono piuttosto complessi e potrebbero risultare scomodi da usare in fase di sviluppo.
- Per tempo di sviluppo raccolta e monitoraggio delle tracce, è consigliabile usare .NET Aspire che offre un modo semplice ma estendibile per avviare la traccia distribuita nell'applicazione e diagnosticare i problemi in locale.
- È anche possibile riutilizzare il progetto delle impostazioni predefinite del servizio Aspire senza l'orchestrazione Aspire. Questo è un modo pratico per introdurre e configurare la traccia e le metriche OpenTelemetry nei progetti ASP.NET.
Raccogliere tracce con .NET Aspirare
Un modo semplice per raccogliere tracce e metriche nelle applicazioni ASP.NET consiste nell'usare .NET Aspire. .NET Aspire è un set di estensioni per .NET per semplificare la creazione e l'uso di applicazioni distribuite. Uno dei vantaggi dell'uso di .NET Aspire è che i dati di telemetria sono incorporati, usando le librerie OpenTelemetry per .NET.
I modelli di progetto predefiniti per .NET Aspire contengono un progetto ServiceDefaults
. Ogni servizio nella soluzione .NET Aspire ha un riferimento al progetto Service Defaults. I servizi lo usano per impostare e configurare OTel.
Il modello di progetto Service Defaults include i pacchetti OTel SDK, ASP.NET, HttpClient e strumentazione del runtime. Questi componenti di strumentazione vengono configurati nel file Extensions.cs. Per supportare la visualizzazione dei dati di telemetria in Aspira dashboard, il progetto Service Defaults include anche l'utilità di esportazione OTLP per impostazione predefinita.
Aspira dashboard è progettato per portare l'osservazione dei dati di telemetria al ciclo di debug locale, che consente agli sviluppatori di garantire che le applicazioni producano dati di telemetria. La visualizzazione dei dati di telemetria consente anche di diagnosticare tali applicazioni in locale. La possibilità di osservare le chiamate tra i servizi è utile in fase di debug, come nell'ambiente di produzione. Il dashboard .NET Aspire viene avviato automaticamente quando si F5 il progetto AppHost
da Visual Studio o dotnet run
il progetto AppHost
dalla riga di comando.
Per altre informazioni su .NET Aspire, vedere:
- Panoramica Aspire
- Telemetria in Aspire
- aspirare dashboard
Riutilizzare il progetto Service Defaults senza .NET Aspire Orchestration
Il progetto Aspire Service Defaults offre un modo semplice per configurare OTel per i progetti ASP.NET, anche senza usare il restante di .NET Aspire come AppHost per l'orchestrazione. Il progetto Service Defaults è disponibile come modello di progetto tramite Visual Studio o dotnet new
. Imposta OTel e configura l'esportatore OTLP. È quindi possibile usare le variabili di ambiente OTel per configurare l'endpoint OTLP per inviare dati di telemetria e fornire le proprietà delle risorse per l'applicazione.
I passaggi per usare ServiceDefaults all'esterno di .NET Aspire sono:
Aggiungere il progetto ServiceDefaults alla soluzione usando Aggiungi nuovo progetto in Visual Studio oppure usare
dotnet new
:dotnet new aspire-servicedefaults --output ServiceDefaults
Fare riferimento al progetto ServiceDefaults dalla tua applicazione ASP.NET. In Visual Studio selezionare Aggiungi>Riferimento al Progetto e selezionare il progetto ServiceDefaults
Chiamare la funzione di installazione di OpenTelemetry
ConfigureOpenTelemetry()
come parte dell'inizializzazione del generatore di applicazioni.var builder = WebApplication.CreateBuilder(args) builder.ConfigureOpenTelemetry(); // Extension method from ServiceDefaults. var app = builder.Build(); app.MapGet("/", () => "Hello World!"); app.Run();
Per una procedura dettagliata completa, vedere Esempio: Usare OpenTelemetry con OTLP e l'Aspire Dashboard autonomo.
Tracciamento sperimentale della connessione
Durante la risoluzione dei problemi HttpClient
o dei colli di bottiglia, potrebbe essere fondamentale capire dove viene impiegato il tempo nell'invio di richieste HTTP. Spesso, il problema si verifica durante la definizione della connessione HTTP, che in genere si suddivide in ricerca DNS, connessione TCP e handshake TLS.
.NET 9 ha introdotto il tracciamento sperimentale delle connessioni aggiungendo uno span HTTP connection setup
con tre span figlio che rappresentano le fasi DNS, TCP e TLS della connessione. La parte HTTP della traccia di connessione viene implementata all'interno di SocketsHttpHandler, ovvero il modello di attività deve rispettare il comportamento del pool di connessioni sottostante.
Nota
In SocketsHttpHandlerle connessioni e le richieste hanno cicli di vita indipendenti. Una connessione in pool può essere attiva per molto tempo e gestire molte richieste. Quando si effettua una richiesta, se non è disponibile alcuna connessione immediatamente nel pool di connessioni, la richiesta viene aggiunta a una coda di richieste per attendere una connessione disponibile. Non esiste alcuna relazione diretta tra le richieste in attesa e le connessioni. Il processo di connessione potrebbe essere stato avviato quando un'altra connessione è diventata disponibile per l'uso, nel qual caso viene usata la connessione liberata. Di conseguenza, l'intervallo di HTTP connection setup
non viene modellato come figlio dell'intervallo di HTTP client request
; Vengono invece usati i collegamenti span.
.NET 9 ha introdotto gli intervalli seguenti per consentire la raccolta di informazioni dettagliate sulla connessione:
Nome | ActivitySource | Descrizione |
---|---|---|
HTTP wait_for_connection |
Experimental.System.Net.Http.Connections |
Intervallo figlio dell'intervallo di HTTP client request che rappresenta l'intervallo di tempo in cui la richiesta è in attesa di una connessione disponibile nella coda delle richieste. |
HTTP connection_setup |
Experimental.System.Net.Http.Connections |
Rappresenta l'istituzione della connessione HTTP. Intervallo radice di traccia separato con il proprio TraceId . Gli HTTP client request segmenti possono contenere collegamenti a HTTP connection_setup . |
DNS lookup |
Experimental.System.Net.NameResolution |
Ricerca DNS eseguita dalla classe Dns. |
socket connect |
Experimental.System.Net.Sockets |
Creazione di una connessione Socket. |
TLS handshake |
Experimental.System.Net.Security |
L'handshake del client o del server TLS eseguito da SslStream. |
Nota
I nomi di ActivitySource
corrispondenti iniziano con il prefisso Experimental
, poiché questi intervalli potrebbero essere modificati nelle versioni future, man mano che si apprenderà come funzionano correttamente nell'ambiente di produzione.
Questi intervalli sono troppo verbosi per un uso continuo negli scenari di produzione con carichi di lavoro elevati, essendo difficili da gestire, e questo livello di strumentazione non è normalmente necessario. Tuttavia, se si sta tentando di diagnosticare i problemi di connessione o ottenere una comprensione più approfondita del modo in cui la latenza di rete e connessione influisce sui servizi, forniscono informazioni dettagliate difficili da raccogliere con altri mezzi.
Quando la Experimental.System.Net.Http.Connections
ActivitySource è abilitata, l'intervallo di HTTP client request
contiene un collegamento all'intervallo di HTTP connection_setup
corrispondente alla connessione che gestisce la richiesta. Poiché una connessione HTTP può essere di lunga durata, ciò potrebbe comportare molti collegamenti all'intervallo di connessione da ognuna delle attività della richiesta. Alcuni strumenti di monitoraggio APM navigano in modo aggressivo i collegamenti tra gli intervalli per creare le loro visualizzazioni e, di conseguenza, includere questo span può causare problemi se gli strumenti non sono stati progettati per gestire un numero elevato di collegamenti.
Il diagramma seguente illustra il comportamento degli intervalli e la relativa relazione:
Procedura dettagliata: Uso della traccia di connessione sperimentale in .NET 9
Questa procedura dettagliata usa un .NET 9 Aspire Starter App per illustrare la traccia delle connessioni, ma dovrebbe essere facile configurarla con anche altri strumenti di monitoraggio. Il passaggio chiave consiste nell'abilitare ActivitySources.
Creare un'app .NET Aspire 9 Starter usando
dotnet new
:dotnet new aspire-starter-9 --output ConnectionTracingDemo
In alternativa, in Visual Studio:
Aprire
Extensions.cs
nel progetto diServiceDefaults
e modificare il metodoConfigureOpenTelemetry
aggiungendo ActivitySources per la connessione nel callback di configurazione della traccia:.WithTracing(tracing => { tracing.AddAspNetCoreInstrumentation() // Instead of using .AddHttpClientInstrumentation() // .NET 9 allows to add the ActivitySources directly. .AddSource("System.Net.Http") // Add the experimental connection tracking ActivitySources using a wildcard. .AddSource("Experimental.System.Net.*"); });
Avviare la soluzione. Dovrebbe aprire il .NET Aspire Dashboard.
Vai alla pagina Meteo dell'app
webfrontend
per generare una richiestaHttpClient
versoapiservice
.Tornare al Dashboard e navigare alla pagina Traces. Aprire la traccia
webfrontend: GET /weather
.
Quando le richieste HTTP vengono effettuate con la strumentazione della connessione abilitata, verranno visualizzate le modifiche seguenti all'intervallo di richieste client:
- Se deve essere stabilita una connessione o se l'app è in attesa di una connessione dal pool di connessioni, viene visualizzato un intervallo di
HTTP wait_for_connection
aggiuntivo che rappresenta il ritardo di attesa di una connessione. Ciò consente di comprendere i ritardi tra la richiestaHttpClient
effettuata nel codice e l'avvio effettivo dell'elaborazione della richiesta. Nell'immagine precedente:- L'intervallo selezionato è la richiesta HttpClient.
- L'intervallo seguente rappresenta il tempo che la richiesta trascorre in attesa che una connessione venga stabilita.
- L'ultimo intervallo in giallo proviene dalla destinazione che elabora la richiesta.
- L'intervallo HttpClient avrà un collegamento all'intervallo di
HTTP connection_setup
, che rappresenta l'attività per creare la connessione HTTP usata dalla richiesta.
Come accennato in precedenza, l'intervallo di HTTP connection_setup
è un intervallo separato con il proprio TraceId
, poiché la durata è indipendente da ogni singola richiesta client. Questo intervallo ha solitamente intervalli figlio DNS lookup
, (TCP) socket connect
, e TLS client handshake
.
Arricchimento
In alcuni casi, è necessario aumentare la funzionalità di traccia System.Net
esistente. In genere questo significa inserire tag/attributi aggiuntivi per le attività predefinite. Questo metodo viene chiamato arricchimento .
API di arricchimento nella libreria di strumentazione OpenTelemetry
Per aggiungere altri tag/attributi all'attività di richiesta client HTTP, l'approccio più semplice consiste nell'usare le API di arricchimento HttpClient
della libreria di strumentazione HttpClient e HttpWebRequest di OpenTelemetry. Ciò richiede di avere una dipendenza dal pacchetto OpenTelemetry.Instrumentation.Http
.
Arricchimento manuale
L'arricchimento dell'attività HTTP client request
può essere implementato manualmente. Per questo è necessario accedere Activity.Current nel codice in esecuzione nell'ambito dell'attività della richiesta, prima che l'attività venga completata. A tale scopo, è possibile implementare un IObserver<DiagnosticListener>
e sottoscriverlo a AllListeners per ottenere i callback per quando si verifica un'attività di rete. Infatti, questo è il modo in cui viene implementata la libreria di strumentazione OpenTelemetry HttpClient e HttpWebRequest. Per un esempio di codice, vedere il codice di sottoscrizione in DiagnosticSourceSubscriber.cs
e l'implementazione sottostante in HttpHandlerDiagnosticListener.cs a cui vengono delegate le notifiche.
Sono necessarie altre tracce?
Se hai suggerimenti per altre informazioni utili che potrebbero essere esposte tramite tracciamento, segnala un problema dotnet/runtime.