Condividi tramite


Esempio: usare OpenTelemetry con OTLP e Aspire Dashboard standalone

Si tratta di una serie di esempi volti a illustrare l'osservabilità di .NET con OpenTelemetry.

Oltre a essere una parte standard di .NET Aspire, Aspire Dashboard è disponibile come contenitore docker standalone, che fornisce i dati di telemetria degli endpoint OTLP e visualizzerà i log, le metriche e le tracce. In questo modo, l'uso della dashboard non ha alcuna dipendenza da .NET Aspire, visualizzerà i dati di telemetria da qualsiasi applicazione che lo invia i dati di telemetria tramite OTLP. Funziona ugualmente bene per le applicazioni scritte in Java, GoLang, Python e così via. purché possano inviare i dati di telemetria a un endpoint OTLP.

L'uso di Aspire Dashboard ha meno passaggi di configurazione e impostazione rispetto all'uso di soluzioni open source come Prometheus, Grafana e Jaeger, ma a differenza di questi strumenti, Aspire Dashboard è destinato a uno strumento di visualizzazione per sviluppatori e non per il monitoraggio della produzione.

1. Creare il progetto

Creare un semplice progetto API Web usando il modello ASP.NET Core Empty in Visual Studio o il comando dell'interfaccia della riga di comando .NET CLI seguente:

dotnet new web

2. Aggiungere metriche e definizioni di attività

Il codice seguente definisce una nuova metrica (greetings.count) per il numero di chiamate ricevute dall'API e una nuova origine attività (Otel.Example).

// Custom metrics for the application
var greeterMeter = new Meter("OTel.Example", "1.0.0");
var countGreetings = greeterMeter.CreateCounter<int>("greetings.count", description: "Counts the number of greetings");

// Custom ActivitySource for the application
var greeterActivitySource = new ActivitySource("OTel.Example");

3. Creare un endpoint API

Inserire il codice seguente tra builder.Build(); e app.Run()

app.MapGet("/", SendGreeting);

Inserire la seguente funzione in fondo al file:

async Task<String> SendGreeting(ILogger<Program> logger)
{
    // Create a new Activity scoped to the method
    using var activity = greeterActivitySource.StartActivity("GreeterActivity");

    // Log a message
    logger.LogInformation("Sending greeting");

    // Increment the custom counter
    countGreetings.Add(1);

    // Add a tag to the Activity
    activity?.SetTag("greeting", "Hello World!");

    return "Hello World!";
}

Nota

La definizione dell'endpoint non utilizza alcun elemento specifico per OpenTelemetry. Usa le API .NET per l'osservabilità.

4. Fare riferimento ai pacchetti OpenTelemetry

Usare Gestione pacchetti NuGet o la riga di comando per aggiungere i pacchetti NuGet seguenti:

  <ItemGroup>
    <PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.9.0" />
    <PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.9.0" />
    <PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.9.0" />
    <PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.9.0" />
  </ItemGroup>

Nota

Usare le versioni più recenti, perché le API OTel sono in continua evoluzione.

5. Configurare OpenTelemetry con i provider corretti

Inserire il codice seguente prima di builder.Build();:

// Setup logging to be exported via OpenTelemetry
builder.Logging.AddOpenTelemetry(logging =>
{
    logging.IncludeFormattedMessage = true;
    logging.IncludeScopes = true;
});

var otel = builder.Services.AddOpenTelemetry();

// Add Metrics for ASP.NET Core and our custom metrics and export via OTLP
otel.WithMetrics(metrics =>
{
    // Metrics provider from OpenTelemetry
    metrics.AddAspNetCoreInstrumentation();
    //Our custom metrics
    metrics.AddMeter(greeterMeter.Name);
    // Metrics provides by ASP.NET Core in .NET 8
    metrics.AddMeter("Microsoft.AspNetCore.Hosting");
    metrics.AddMeter("Microsoft.AspNetCore.Server.Kestrel");
});

// Add Tracing for ASP.NET Core and our custom ActivitySource and export via OTLP
otel.WithTracing(tracing =>
{
    tracing.AddAspNetCoreInstrumentation();
    tracing.AddHttpClientInstrumentation();
    tracing.AddSource(greeterActivitySource.Name);
});

// Export OpenTelemetry data via OTLP, using env vars for the configuration
var OtlpEndpoint = builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"];
if (OtlpEndpoint != null)
{
    otel.UseOtlpExporter();
}

Questo codice configura OpenTelemetry con le diverse origini di telemetria:

  • Aggiunge un provider OTel a ILogger per raccogliere i record di log.
  • Configura le metriche, registrando i provider di strumentazione e i contatori per ASP.NET e il contatore personalizzato.
  • Configura la traccia, registrando i provider di strumentazione e l'ActivitySource personalizzato.

Registra quindi l'utilità di esportazione OTLP usando env vars per la configurazione.

6. Configurare le variabili dell'ambiente OTLP

L'utilità di esportazione OTLP può essere configurata tramite API nel codice, ma è più comune configurarla tramite variabili di ambiente. Aggiungere quanto segue a AppSettings.Development.json

"OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4317",
"OTEL_SERVICE_NAME": "OTLP-Example"

È possibile aggiungere altre variabili di ambiente per l'utilità di esportazione .NET OTLP o variabili OTel comuni, ad esempio OTEL_RESOURCE_ATTRIBUTES per definire gli attributi delle risorse.

Nota

Un gotcha comune consiste nel combinare AppSettings.json e AppSettings.Development.json, se quest'ultimo è presente, verrà usato quando si fa F5 da Visual Studio, e tutte le impostazioni in AppSettings.json verranno ignorate.

7. Avviare il contenitore di Aspire Dashboard

Usare docker per scaricare ed eseguire il contenitore di dashboard.

docker run --rm -it `
-p 18888:18888 `
-p 4317:18889 `
--name aspire-dashboard `
mcr.microsoft.com/dotnet/aspire-dashboard:latest

I dati visualizzati nella dashboard possono essere sensibili. Per impostazione predefinita, la dashboard è protetta con l'autenticazione che richiede un token per l'accesso. Il token viene visualizzato nell'output risultante durante l'esecuzione del contenitore.

[Aspire Dashboard]

Copiare l'URL visualizzato e sostituire 0.0.0.0 con localhost, ad esempio http://localhost:18888/login?t=123456780abcdef123456780 e aprirlo nel browser oppure è anche possibile incollare la chiave dopo /login?t= quando viene visualizzata la finestra di dialogo di accesso. Il token verrà modificato ogni volta che si avvia il contenitore.

8. Eseguire il progetto

Eseguire il progetto e quindi accedere all'API con il browser o il curl.

curl -k http://localhost:7275

Ogni volta che si richiede la pagina, il conteggio verrà incrementato per il numero di messaggi di saluto che sono stati effettuati.

8.1 Log di output

Le istruzioni di registrazione del codice vengono restituite usando ILogger. Per impostazione predefinita, il Provider console è abilitato in modo che l'output venga indirizzato alla console.

Sono disponibili due opzioni per la modalità di uscita dei log da .NET:

  • L’output stdout e stderr viene reindirizzato ai file di log dai sistemi contenitore, ad esempio Kubernetes.
  • Usando le librerie di registrazione che si integreranno con ILogger, queste includono Serilog o NLog.
  • Uso di provider di registrazione per OTel, ad esempio OTLP. La sezione di registrazione nel codice del passaggio 5 aggiunge il provider OTel.

I log vengono visualizzati nella dashboard come log strutturati. Tutte le proprietà impostate nel messaggio di log vengono estratte come campi nel record di log.

Log nella dashboard standalone

8.2 Visualizzazione delle metriche

Aspire Dashboard mostra le metriche per ogni risorsa (una risorsa è il modo OTel di parlare di origini di telemetria, ad esempio un processo). Quando viene selezionata una risorsa, la dashboard enumera ogni metrica inviata all'endpoint OTLP dalla risorsa. L'elenco delle metriche è dinamico e verrà aggiornato man mano che vengono ricevute nuove metriche.

Metriche nella dashboard autonoma

La visualizzazione per le metriche dipende dal tipo di metrica in uso:

  • I contatori verranno visualizzati direttamente.
  • Gli istogrammi che tengono traccia di un valore per richiesta, ad esempio un intervallo di tempo o byte inviati per ogni richiesta, vengono raccolti in una serie di bucket. La dashboard produrrà un grafico dei percentili P50, P90 e P99. I risultati dell'istogramma possono includere esemplari, che sono singoli punti dati insieme all'elemento trace/spanId per tale richiesta. Questi valori verranno visualizzati come puntini nel grafico. Se se ne seleziona uno, si passerà alla rispettiva traccia in modo da visualizzare l'evento che ha causato tale valore. Questo è utile per la diagnosi degli outlier.
  • Le metriche possono includere dimensioni, ovvero coppie chiave/valore associate ai singoli valori. I valori vengono aggregati per dimensione. Usando gli elenchi a discesa nella visualizzazione, è possibile filtrare i risultati per esaminare dimensioni specifiche, ad esempio solo GET le richieste o quelle per una route URL specifica in ASP.NET.

8.3 Visualizzazione della traccia

La visualizzazione di traccia mostrerà un elenco di tracce: ogni traccia è un set di attività che condividono lo stesso traceId. Il lavoro viene monitorato con intervalli che rappresentano un'unità di lavoro. L'elaborazione di una richiesta di ASP.NET creerà un intervallo. L'esecuzione di una richiesta HttpClient sarà un intervallo. Tenendo traccia dell'elemento padre dell'intervallo, è possibile visualizzare una gerarchia di intervalli. La raccolta di intervalli da una risorsa (processo) tiene traccia del lavoro che avviene in una serie di servizi. Le richieste HTTP hanno un'intestazione usata per passare traceId e spanId padre al servizio successivo. Ogni risorsa deve raccogliere i dati di telemetria e inviarla allo stesso agente di raccolta. Aggrega e presenta una gerarchia degli intervalli.

Tracce nella dashboard autonoma

La dashboard mostrerà un elenco di tracce con informazioni di riepilogo. Ogni volta che vengono visualizzati intervalli con un nuovo traceId, otterranno una riga nella tabella. Facendo clic sulla visualizzazione, verranno visualizzati tutti gli intervalli nella traccia.

Intervalli nella dashboard autonoma

Se si seleziona un intervallo, verranno visualizzati i dettagli, incluse eventuali proprietà nell'intervallo, ad esempio il greeting tag impostato nel passaggio 3.