Freigeben über


Beispiel: Verwenden von OpenTelemetry mit OTLP und dem eigenständigen Aspire-Dashboard

Dies ist eins von mehreren Beispielen zur Veranschaulichung des .NET-Einblicks mit OpenTelemetry.

Das Aspire-Dashboard ist als Standardkomponente von .NET Aspire sowie als eigenständiger Docker-Container verfügbar, der OTLP-Endpunkttelemetrie bereitstellt, an die Daten gesendet werden können, und Protokolle, Metriken und Ablaufverfolgungen visualisiert. Bei einer derartigen Verwendung des Dashboards besteht keine Abhängigkeit von .NET Aspire. Es visualisiert Telemetriedaten von jeder Anwendung, die über OTLP gesendet werden. Es eignet sich gleichermaßen gut für Anwendungen, die in Java, GoLang, Python usw. geschrieben wurden, vorausgesetzt, sie können ihre Telemetriedaten an einen OTLP-Endpunkt senden.

Bei der Verwendung des Aspire-Dashboards müssen weniger Konfigurations- und Einrichtungsschritte als bei der Verwendung von Open Source-Lösungen wie Prometheus, Grafana und Jaeger ausgeführt werden. Im Gegensatz zu diesen Tools ist das Aspire-Dashboard jedoch als Visualisierungstool für Entwickler und nicht für die Produktionsüberwachung vorgesehen.

1. Erstellen des Projekts

Erstellen Sie ein einfaches Web-API-Projekt, indem Sie die Vorlage ASP.NET Core Empty in Visual Studio oder den folgenden .NET CLI-Befehl verwenden:

dotnet new web

2. Hinzufügen von Metriken und Aktivitätsdefinitionen

Der folgende Code definiert eine neue Metrik (greetings.count) für die Anzahl der Aufrufe der API und eine neue Aktivitätsquelle (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. Erstellen eines API-Endpunkts

Fügen Sie Folgendes zwischen builder.Build(); und app.Run() ein:

app.MapGet("/", SendGreeting);

Fügen Sie am Ende der Datei die folgende Funktion hinzu:

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!";
}

Hinweis

Die Endpunktdefinition verwendet keine OpenTelemetry-spezifischen Elemente. Für Einblick werden die .NET-APIs verwendet.

4. Verweisen auf die OpenTelemetry-Pakete

Verwenden Sie den NuGet-Paket-Manager oder die Befehlszeile, um die folgenden NuGet-Pakete hinzuzufügen:

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

Hinweis

Verwenden Sie die neuesten Versionen, da die OTel-APIs ständig weiterentwickelt werden.

5. Konfigurieren von OpenTelemetry mit den richtigen Anbietern

Fügen Sie den folgende Code vor builder.Build(); ein:

// 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();
}

Dieser Code richtet OpenTelemetry mit den verschiedenen Telemetriequellen ein:

  • Er fügt ILogger einen OTel-Anbieter hinzu, um Protokolldatensätze zu sammeln.
  • Er richtet Metriken ein und registriert Instrumentierungsanbieter und Verbrauchseinheiten für ASP.NET und unsere benutzerdefinierte Verbrauchseinheit.
  • Er richtet die Ablaufverfolgung ein und registriert Instrumentierungsanbieter und unser benutzerdefiniertes ActivitySource-Element.

Anschließend wird der OTLP-Exporter mithilfe von Umgebungsvariablen für seine Konfiguration registriert.

6. Konfigurieren von OTLP-Umgebungsvariablen

Der OTLP-Exporter kann über APIs im Code konfiguriert werden, es ist jedoch üblicher, ihn über Umgebungsvariablen zu konfigurieren. Fügen Sie AppSettings.Development.json Folgendes hinzu:

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

Sie können zusätzliche Umgebungsvariablen für den .NET OTLP-Exporter oder allgemeine OTel-Variablen wie OTEL_RESOURCE_ATTRIBUTES zum Definieren von Ressourcenattributen hinzufügen.

Hinweis

Ein häufiger Fehler besteht in der Verwechslung von AppSettings.json und AppSettings.Development.json. Wenn letztere vorhanden ist, wird sie verwendet, wenn Sie in F5 in Visual Studio drücken, und alle Einstellungen in AppSettings.json werden ignoriert.

7. Starten des Aspire-Dashboardcontainers

Verwenden Sie Docker, um den Dashboardcontainer herunterzuladen und auszuführen.

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

Auf dem Dashboard angezeigte Daten können vertraulich sein. Standardmäßig wird das Dashboard mit Authentifizierung geschützt, die ein Token für die Anmeldung erfordert. Das Token wird beim Ausführen des Containers in der resultierenden Ausgabe angezeigt.

[Aspire-Dashboard]

Kopieren Sie die angezeigte URL, ersetzen Sie 0.0.0.0 durch localhost (z. B. http://localhost:18888/login?t=123456780abcdef123456780), und öffnen Sie die URL in Ihrem Browser. Sie können den Schlüssel auch nach /login?t= einfügen, wenn das Anmeldedialogfeld angezeigt wird. Das Token ändert sich jedes Mal, wenn Sie den Container starten.

8. Ausführen des Projekts

Führen Sie das Projekt aus, und greifen Sie dann mit dem Browser oder curl auf die API zu.

curl -k http://localhost:7275

Jedes Mal, wenn Sie die Seite anfordern, wird die Anzahl der gesendeten Begrüßungen erhöht.

8.1 Protokollausgabe

Die Protokollierungsanweisungen aus dem Code werden mit ILogger ausgegeben. Standardmäßig ist der Konsolenanbieter aktiviert, sodass die Ausgabe an die Konsole weitergeleitet wird.

Es gibt eine Reihe von Optionen, wie Protokolle von .NET ausgehen können:

  • Die Ausgaben stdout und stderr werden von Containersystemen wie Kubernetes an Protokolldateien umgeleitet.
  • Unter Verwendung von Protokollierungsbibliotheken, die in ILogger integriert werden, unter anderem Serilog oder NLog.
  • Verwenden von Protokollierungsanbietern für OTel wie OTLP. Der Protokollierungsabschnitt im Code aus Schritt 5 fügt den OTel-Anbieter hinzu.

Die Protokolle werden auf dem Dashboard als strukturierte Protokolle angezeigt: Alle Eigenschaften, die Sie in der Protokollnachricht festlegen, werden als Felder im Protokolldatensatz extrahiert.

Protokolle auf dem eigenständigen Dashboard

8.2 Anzeigen der Metriken

Das Aspire-Dashboard zeigt Metriken pro Ressource an (eine Ressource ist dabei die OTel-Methode, um über Telemetriequellen wie einen Prozess zu sprechen). Wenn eine Ressource ausgewählt ist, zählt das Dashboard jede Metrik auf, die von der Ressource an den OTLP-Endpunkt gesendet wurde. Die Liste der Metriken ist dynamisch und wird aktualisiert, wenn neue Metriken empfangen werden.

Metriken auf dem eigenständigen Dashboard

Die Ansicht für die Metriken hängt vom Typ der verwendeten Metrik ab:

  • Zähler werden direkt angezeigt.
  • Histogramme, die einen Wert pro Anforderung nachverfolgen, z. B. einen Zeitbereich oder pro Anforderung gesendete Bytes, werden in einer Reihe von Buckets erfasst. Auf dem Dashboard werden die Perzentile P50, P90 und P99 dargestellt. Histogrammergebnisse können Exemplare enthalten. Dabei handelt es sich um einzelne Datenpunkte zusammen mit der Ablaufverfolgs- oder span-ID für diese Anforderung. Diese werden als Punkte im Diagramm angezeigt. Wenn Sie einen Punkt auswählen, navigieren Sie zur jeweiligen Ablaufverfolgung und können sehen, was passiert ist, dass dieser Wert verursacht wurde. Dies ist nützlich für die Diagnose von Ausreißern.
  • Metriken können Dimensionen enthalten, bei denen es sich um Schlüssel-Wert-Paare handelt, die einzelnen Werten zugeordnet sind. Die Werte werden pro Dimension aggregiert. Mithilfe der Dropdownmenüs in der Ansicht können Sie die Ergebnisse filtern, um bestimmte Dimensionen anzuzeigen, z. B. nur GET-Anforderungen oder Anforderungen für eine bestimmte URL-Route in ASP.NET.

8.3 Anzeigen der Ablaufverfolgung

Die Ablaufverfolgungsansicht zeigt eine Liste der Ablaufverfolgungen an – jede Ablaufverfolgung ist eine Gruppe von Aktivitäten, die dieselbe TraceId gemeinsam nutzen. Die Arbeit wird mit span-Elementen nachverfolgt, die eine Arbeitseinheit darstellen. Die Verarbeitung einer ASP.NET-Anforderung erstellt ein span-Element. Die Erstellung einer HttpClient-Anforderung ist ein span-Element. Durch das Nachverfolgen des übergeordneten Bereichs kann eine Hierarchie von Spans dargestellt werden. Durch das Sammeln von span-Elementen der einzelnen Ressourcen (Prozess) verfolgen wir die Arbeit nach, die in einer Reihe von Diensten ausgeführt wird. HTTP-Anforderungen verfügen über einen Header, der zum Übergeben der Ablaufverfolgungs-ID (traceId) und der übergeordneten span-ID (SpanId) an den nächsten Dienst verwendet wird. Jede Ressource muss Telemetriedaten sammeln und an denselben Collector senden. Anschließend wird eine Hierarchie der span-Elemente aggregiert und dargestellt.

Ablaufverfolgungen auf dem eigenständigen Dashboard

Das Dashboard zeigt eine Liste der Ablaufverfolgungen mit Zusammenfassungsinformationen an. Immer wenn span-Elemente mit neuer Ablaufverfolgungs-ID (traceId) erkannt werden, erhalten sie eine Zeile in der Tabelle. Wenn Sie auf die Ansicht klicken, werden alle span-Elemente in der Ablaufverfolgung angezeigt.

span-Elemente auf dem eigenständigen Dashboard

Wenn Sie ein span-Element auswählen, werden die Details einschließlich aller Eigenschaften des span-Elements angezeigt, z. B. das Tag greeting, das wir in Schritt 3 festgelegt haben.