Eine Trace-ID ist eine global eindeutige Kennung, die alle Spans eines verteilten Traces gemeinsam haben. In W3C Trace Context und OpenTelemetry umfasst sie 16 Byte, dargestellt als 32 hexadezimale Kleinbuchstaben, und wird im traceparent-Header zwischen Services weitergegeben, damit Backends Spans, Logs und Exemplare derselben Anfrage verknüpfen können.
Was ist eine Trace-ID?
Eine Trace-ID verbindet alle Arbeitsschritte, die für eine einzelne Anfrage in einem verteilten System anfallen. Der erste Service, der eine Anfrage ohne eingehenden Kontext erhält, erzeugt eine neue Trace-ID. Jeder nachgelagerte Span, ob im API-Gateway, im Payment-Service oder im Datenbank-Client, speichert dieselbe Trace-ID und zusätzlich eine eigene Span-ID. Ein Tracing-Backend setzt anschließend alle Spans mit dieser Trace-ID zu einem Trace-Baum zusammen.
Jeder Span hält außerdem die Span-ID seines Eltern-Spans fest, woraus die Baumstruktur entsteht. Die Trace-ID beantwortet die Frage „Zu welcher Anfrage gehört das?“, die Span-ID „Welche Operation ist das?“.
Das Format der Trace-ID nach W3C
Die W3C-Empfehlung Trace Context, die OpenTelemetry standardmäßig verwendet, legt das Format genau fest:
| Feld | Größe | Kodierung |
|---|---|---|
| trace-id | 16 Byte (128 Bit) | 32 hexadezimale Kleinbuchstaben |
| parent-id (Span-ID) | 8 Byte (64 Bit) | 16 hexadezimale Kleinbuchstaben |
| trace-flags | 1 Byte | 2 Hex-Zeichen, Bit 0 = sampled |
Eine ID, die nur aus Nullen besteht, ist sowohl als Trace-ID als auch als Span-ID ungültig. Übertragen werden die Werte im HTTP-Header traceparent mit dem Aufbau version-traceid-parentid-flags:
traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
00 ist die Version, 4bf9…4736 die Trace-ID, 00f0…02b7 die Span-ID des aufrufenden Spans, und 01 bedeutet, dass der Trace gesampelt wurde. Herstellerspezifische Daten gehören in den separaten Header tracestate. Die Spezifikation empfiehlt zufällig erzeugte Trace-IDs, damit sie ohne Abstimmung eindeutig sind. Der Entwurf von Trace Context Level 2 ergänzt ein „random“-Flag, das nachgelagerten Samplern diese Eigenschaft signalisiert.
Wie die Trace-ID weitergegeben wird
Trace-IDs wandern per Context Propagation durch das System. Die Instrumentierung liest traceparent aus eingehenden Anfragen, legt den Kontext im Prozess ab und injiziert ihn in ausgehende HTTP-Aufrufe, gRPC-Metadaten oder Nachrichten-Header in Kafka und anderen Queues. Verliert ein Hop den Header, etwa ein Proxy, der unbekannte Header entfernt, oder ein eigener HTTP-Client ohne Instrumentierung, startet der nachgelagerte Service eine neue Trace-ID, und der Trace zerfällt in zwei unverbundene Teile. Ältere Formate wie die B3-Header von Zipkin, die auch 64-Bit-Trace-IDs erlauben, oder der eigene Header von AWS X-Ray lassen sich mit OpenTelemetry-Propagatoren überbrücken.
Die Trace-ID in Logs schreiben
Die Trace-ID ist der einfachste Weg, Signale zu korrelieren. Enthält jede Logzeile innerhalb eines Spans trace_id und span_id, springen Sie von einem langsamen Trace direkt zu den zugehörigen Logs und von einem Fehlerlog zum vollständigen Anfragepfad. Mit strukturiertem Logging ist das ein einzelnes Feld:
{"level":"error","msg":"card declined","service":"payments",
"trace_id":"4bf92f3577b34da6a3ce929d0e0e4736","span_id":"00f067aa0ba902b7"}
Die OpenTelemetry-Log-Bridges für Java, Python, Go und weitere Sprachen ergänzen diese Felder automatisch. Auch Metriken lassen sich mit Traces verknüpfen: Ein Exemplar hängt eine beispielhafte Trace-ID an einen Histogramm-Bucket, sodass ein Latenzanstieg im Diagramm direkt zu einem repräsentativen Trace führt.
Best Practices
- W3C Trace Context durchgängig verwenden und jeden Proxy, jedes Gateway und jeden Load Balancer so konfigurieren, dass
traceparentundtracestateweitergereicht werden. - Die Trace-ID in Fehlerantworten oder einem Response-Header zurückgeben, damit der Support fehlgeschlagene Anfragen findet.
- Trace-IDs nie aus Nutzerdaten oder fortlaufenden Zählern ableiten, sondern den Zufallsgenerator des SDK nutzen.
- Trace-IDs nicht als Metrik-Label verwenden: Jeder Wert ist einzigartig und führt zu einer Kardinalitätsexplosion.
- Beachten, dass Sampling einen Trace verwerfen kann, obwohl seine ID in Logs auftaucht.
Typische Fehler
- Hex-Großbuchstaben oder IDs falscher Länge, die konforme Parser ablehnen.
- In jedem Service einen neuen Trace starten, weil ein Queue-Consumer den weitergegebenen Kontext ignoriert.
- Eine Trace-ID loggen, die aus einem anderen Kontext stammt als der aktive Span, etwa in asynchronen Callbacks.
Trace-IDs bei asynchroner Verarbeitung
Nicht jede Beziehung passt in einen einzigen Trace. Ein Batch-Job, der 500 Nachrichten aus einer Queue verarbeitet, die jeweils aus einer anderen Anfrage stammen, kann keinen einzelnen Eltern-Span haben. OpenTelemetry löst das mit Span Links: Der Consumer-Span beginnt einen eigenen Trace oder setzt einen fort und verweist auf die Span-Kontexte der Producer, die jeweils durch Trace-ID und Span-ID identifiziert sind. Lang laufende Workflows über Stunden oder Tage werden oft bewusst in mehrere Traces aufgeteilt und über Links oder eine gemeinsame fachliche Kennung verbunden, etwa eine Bestellnummer als Span-Attribut. So bleiben einzelne Traces überschaubar, und Sie können dennoch von einer Verarbeitungsstufe zur nächsten navigieren. Für die Fehlersuche ist das oft hilfreicher als ein riesiger Trace mit Tausenden Spans.
Wie Obseria unterstützt
Obseria nimmt OpenTelemetry-Traces nativ per OTLP an und speichert Spans, Logs und Metriken in Obseria Lake. Eine Abfrage nach einer Trace-ID liefert daher den vollständigen Trace samt zugehörigen Logs. In den Ansichten für Distributed Tracing wechseln Sie von jedem Span zu korrelierten Logs und Fehlern. Mit vorhandenen OpenTelemetry-SDKs kommt der erste Trace in der Regel innerhalb von 15 Minuten an.