CodeGym /Kurse /C# SELF /Verteiltes Tracing und Telemetrie

Verteiltes Tracing und Telemetrie

C# SELF
Level 64 , Lektion 4
Verfügbar

1. Einführung

In der heutigen Welt der serviceorientierten Architektur (SOA), Microservices und Cloud-Lösungen kann eine einzelne Benutzeranfrage durch Dutzende verschiedener Services "fliegen", bevor sie ein Ergebnis zurückliefert. Jeder Knoten dieser "Route" schreibt seine eigenen Logs — aber wie erkennt man, dass ein Fehler oder eine Verzögerung an einer Stelle wirklich mit genau dieser Anfrage zusammenhängt?

Verteiltes Tracing ist wie ein Tracking-System für ein Paket in der Logistik: du siehst, durch welche Stationen dein Paket gelaufen ist, wo es aufgehalten wurde und wo ein Zwischenfall passiert ist. In der Programmierwelt ist es die Möglichkeit, die "Reise" einer einzelnen Anfrage durch alle Services zu verfolgen, zu verstehen, wie lange sie an jedem Ort verbracht hat und wo ein Fehler oder eine Verzögerung aufgetreten ist.

Wozu braucht man Tracing?

  • Fehlerlokalisierung: Wenn etwas schiefgeht, siehst du sofort, wo genau: in welchem Service, in welchem Schritt und sogar welche konkrete Methode aufgerufen wurde.
  • Suche nach Flaschenhälsen: Tracing zeigt, wo deine Services "bremsen" und in welchem Schritt die meiste Zeit verloren geht.
  • Analyse von Nutzerabläufen: Du kannst verstehen, wie die Clients deine Services tatsächlich nutzen und wo es sich lohnt, zuerst in Optimierung zu investieren.

Wie funktioniert das?

Jede Anfrage erhält eine eindeutige Trace-Identifikation (TraceId), die zusammen mit ihr durch den gesamten Service-Stack reist: vom Frontend bis zum Backend, von der API bis zur Datenbank und zurück. Auf jedem Schritt werden "Spans" erstellt, die die Ausführungszeit einer Operation und zusätzliche Ereignisse aufzeichnen. Am Ende erhältst du einen Baum (Graph) von Operationen mit deren Dauer und Verbindungen untereinander.

Wichtige Entitäten und Begriffe des verteilten Tracings

Begriff Beschreibung
Trace Der logische Pfad einer einzelnen Anfrage durch mehrere Services. Eindeutig durch TraceId.
Span Eine Operation oder Unteroperation innerhalb eines Traces. Jeder Span hat eine eigene eindeutige Kennung.
TraceId Die eindeutige Kennung des gesamten Traces (der gesamten Anfrage).
SpanId Die eindeutige Kennung des aktuellen Spans (der Operation).
Parent SpanId Die Id des übergeordneten Spans (falls dieser Span Teil einer anderen Operation ist).
Attributes Ein Satz benutzerdefinierter Metadaten für den Span: Methodenname, Parameter, Status usw.
Events/Logs Wichtige Ereignisse, die mit dem Span verbunden sind (z. B. Fehler, Abschluss).
Context Propagation Die Weitergabe von Trace-Informationen zwischen Services und Threads.

2. OpenTelemetry: offener Standard für Observability

Kurz zu OpenTelemetry

OpenTelemetry ist ein offener Standard und ein Satz von Tools zum Sammeln von Telemetrie (Tracing, Metriken, Logs) aus unterschiedlichen Anwendungen. Es wird von der Cloud Native Computing Foundation (CNCF) unterstützt und ist de-facto-Standard in der Welt von Cloud- und verteilten Anwendungen geworden.

OpenTelemetry (kurz OTel) kann:

  • Tracing, Metriken und Logs automatisch sammeln und senden;
  • mit den wichtigsten Programmiersprachen arbeiten, einschließlich C#, Java, Python und anderen;
  • Daten an Observability-Systeme zurückgeben — Jaeger, Zipkin, Azure Monitor, Grafana usw.;
  • sich über Plugins erweitern und an jeden Stack anpassen lassen.

Warum ausgerechnet OpenTelemetry?

  • Vendor-Unabhängigkeit: OTel ist ein Standard, kein Produkt einer bestimmten Firma.
  • Kompatibilität: Unterstützt gängige Tracing-Formate und lässt sich leicht in APM-Systeme integrieren.
  • Automatisierung: Einen Großteil der Arbeit (z. B. HTTP-Request-Tracing) kann es selbst übernehmen, mit minimaler Konfiguration.
  • Skalierbarkeit: OTel funktioniert gut in kleinen wie in sehr großen Systemen.

Architektur von OpenTelemetry: einfach erklärt

Damit man sich in den "Schichten" nicht verheddert, visualisieren wir den typischen Datenfluss von Traces in OTel.

flowchart LR
    subgraph Anwendung
        A[OpenTelemetry SDK]
    end
    A -->|Traces, Metriken, Logs| B[OpenTelemetry Collector]
    B -->|Export zu| C[Jaeger/Zipkin/Grafana/Azure/Application Insights usw.]
  1. OpenTelemetry SDK: Wird direkt in deine Anwendung eingebettet (z. B. über NuGet-Pakete für .NET).
  2. OTel Collector: Ein separater Service-Hub (oft als Docker-Container deployed), der Trace-Daten von all deinen Anwendungen annimmt und dorthin exportiert, wohin du sie schickst.
  3. Observability-Frontend: Das System, in dem du hübsche Diagramme, Bäume siehst, filterst und Traces analysierst.

3. Schneller Einstieg ins Tracing mit C#/.NET

Fügen wir unserem Lernbeispiel grundlegendes verteiltes Tracing hinzu. Die Hauptschritte sind ziemlich einfach.

NuGet-Pakete installieren

dotnet add package OpenTelemetry
dotnet add package OpenTelemetry.Exporter.Console

OpenTelemetry — die grundlegende SDK-Implementierung;
OpenTelemetry.Exporter.Console — Export der Traces in die Konsole (kann durch Jaeger, Zipkin etc. ersetzt werden).

Minimale Tracing-Konfiguration

In der Datei Program.cs (für eine Konsolenanwendung):

using OpenTelemetry;
using OpenTelemetry.Trace;

class Program
{
    static void Main(string[] args)
    {
        // Wir konfigurieren Tracing
        using var tracerProvider = Sdk.CreateTracerProviderBuilder()
            .AddSource("DemoApp") // Geben wir den Source-Namen an
            .AddConsoleExporter() // Exportiert Traces in die Konsole
            .Build();

        var source = new System.Diagnostics.ActivitySource("DemoApp");

        // Starten einer neuen Trace (Root-Span)
        using (var activity = source.StartActivity("Hauptoperation"))
        {
            DoWork();
        }
    }

    static void DoWork()
    {
        // Ein bisschen Anwendungslogik...
        System.Threading.Thread.Sleep(300);
    }
}

Was passiert hier?

  • Wir erstellen einen TracerProvider, registrieren die Quelle ("DemoApp") und fügen den Konsolenexporter AddConsoleExporter() hinzu.
  • Wir starten eine neue "Activity" (Span) über ActivitySource im Programmroot.
  • Innerhalb führen wir die Arbeit aus, die wir "tracen" möchten.

Ergebnis:

Activity.Id:          0b69e3e97ca5f14d
Activity.Operation:   Hauptoperation
Duration: 00:00:00.3001082
...

Automatisches Tracing für HTTP und Datenbanken

OpenTelemetry unterstützt Instrumentation — automatisches Tracing für gängige Bibliotheken. Beispielsweise können Aufrufe über HttpClient und DB-Abfragen (ADO.NET) gesammelt werden, ohne dass du extra Code schreiben musst.

using var tracerProvider = Sdk.CreateTracerProviderBuilder()
    .AddHttpClientInstrumentation() // HTTP-Requests
    .AddSqlClientInstrumentation()  // SQL-Requests (falls du sie verwendest)
    .AddConsoleExporter()
    .Build();

Jetzt tauchen alle deine Aufrufe über HttpClient und SQL-Arbeiten automatisch in den Traces auf.

4. Visualisierung von Traces

Die Ausgabe in die Konsole ist nur der erste Schritt. Für echten Nutzen solltest du ein Frontend mit Visualisierung nutzen.

Jaeger

Jaeger ist eines der beliebtesten Open-Source-Tools zur Visualisierung von Traces.

  1. Deploye Jaeger (z. B. via Docker).
  2. Anstelle von AddConsoleExporter() verwendest du:
    .AddJaegerExporter(options =>
    {
        options.AgentHost = "localhost";
        options.AgentPort = 6831;
    })
    
  3. Nun werden alle Traces im Jaeger UI angezeigt — du kannst nach TraceId filtern und detaillierte Zeitdiagramme anschauen.

Vollständige Anleitung: OpenTelemetry Jaeger Exporter für .NET

5. Nützliche Nuancen

Vergleich der Ansätze

Ohne OTel kopierst du das TraceId manuell in Logs, hoffst, es nicht zu vergessen weiterzureichen und leidest bei der Analyse von Incidents. Mit OTel wird die ganze Kette automatisch aufgebaut und per Klick visualisiert.

Ansatz Aufwand Zuverlässigkeit Skalierbarkeit Kompatibilität
Manuelles Loggen von TraceId Hoch Niedrig Benötigt ständige Wartung Nur deine Anwendungen
OpenTelemetry Minimal (nach der Integration) Garantiert Weitreichend (jede Sprache, jeder Stack) Kompatibel mit den meisten APM- und Log-Systemen

Beispielarchitektur

[Web-Client] --> [API-Service] --> [Auth-Service] --> [Database-Service]

Wenn der Benutzer einen Button klickt, läuft die Anfrage durch all diese Services. Mit OTel kannst du den "Faden" (TraceId) durch jeden von ihnen ziehen und die Logik automatisch zu einem einzigen Trace zusammenführen.

  • In jedem Service erkennt das OTel SDK automatisch die TraceId aus den HTTP-Headern und setzt die Kette fort.
  • Als Ergebnis kannst du einen Trace öffnen — und sehen, wo Millisekunden verbraucht wurden, was passiert ist und wo ein Fehler aufgetreten ist.

Anwendung in echten Projekten und im Vorstellungsgespräch

  • Microservice-Systeme und verteilte Anwendungen (FinTech, Marktplätze, SaaS usw.).
  • DevOps/SRE: schnelle Lokalisierung von Problemen.
  • Verbesserung von SLA und Reaktionszeiten der Services.
  • Profiling und Optimierung.
  • Beim Vorstellungsgespräch — Demonstration einer reifen Engineering-Praxis.

6. Typische Fehler und Implementierungsbesonderheiten

TraceContext nicht weitergegeben. Wenn zwischen Services die TraceId nicht mitgeschickt wird (zum Beispiel weil die nötigen HTTP-Header nicht weitergereicht wurden), werden Traces zerschnitten — sie erscheinen als isolierte "Punkte" und die ganze Schönheit der Observability geht verloren.

Nicht instrumentierter Code. Wenn eine Bibliothek oder ein Framework keine Instrumentation unterstützt, fallen einige Operationen aus dem Trace heraus (du kannst aber jederzeit Spans manuell über ActivitySource und StartActivity() anlegen).

Datenüberfluss. Traces für jede Anfrage zu sammeln ist teuer, besonders in großem Production-Traffic. Üblich ist, Tracing nur für einen Teil der Anfragen zu aktivieren (sample rate) oder durch Trigger (Fehler, langsame Requests).

Performance. Die Einführung von OTel beeinflusst die Performance minimal bei Nutzung asynchroner Exporte, aber bei extrem hohem Traffic sollte man auf Overhead achten und die Sampling-Rate anpassen.

1
Umfrage/Quiz
Logging, Level 64, Lektion 4
Nicht verfügbar
Logging
Logging, Monitoring und Tracing
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION