Start / Seminare / Observability mit OpenTelemetry, Prometheus und Grafana

Modul

Context Propagation und Baggage

4 Kapitel in diesem Modul-Video · Laufzeit

Vertonung mit synthetischer Stimme · Inhalte redaktionell verantwortet · © 2026 HECKER CONSULTING, alle Rechte vorbehalten

Transkript

Der gesprochene Text dieses Moduls zum Mitlesen, Überfliegen und Durchsuchen. Ein Klick auf einen Zeitstempel springt an die Stelle im Video.

Context Propagation und Baggage

0:00 In Modul fünf ist Ihnen vermutlich aufgefallen, dass der Trace zwischen zwei Diensten abreißt. Das ist kein Zufall und kein Einzelfall — es ist das häufigste Problem beim Einstieg ins verteilte Tracing. Ein Trace, der an der Dienstgrenze abreißt, ist kein Trace mehr; er ist ein Log mit Zeitangabe. In diesem Modul klären wir, wie der Zusammenhang über Dienstgrenzen transportiert wird, wo er typischerweise verloren geht — und wir schauen uns Baggage an, einen Mechanismus, der außerordentlich praktisch und außerordentlich heikel ist.

Context Propagation und Baggage

0:31 Drei Kapitel und ein Abschluss. Zuerst der Trace Context selbst: ein Header, ein Standard, wenig Magie. Dann die Bruchstellen — Thread-Wechsel, Warteschlangen, asynchrone Verarbeitung —, an denen der Zusammenhang verloren geht, ohne dass jemand einen Fehler bekommt. Und schließlich Baggage, wo wir über Datenschutz und Vertrauensgrenzen reden müssen. Am Ende reparieren Sie den zerrissenen Trace von Pfandwerk. Damit schließt Tag eins.

Trace Context über Servicegrenzen

0:58 Fangen wir mit dem Mechanismus an. Die gute Nachricht vorweg: Es ist einfacher, als man vermutet. Es gibt keinen verteilten Zustand, keine zentrale Registratur, keinen Abgleich zwischen Diensten. Es gibt einen Header. Genau deshalb ist die Fehlersuche auch überschaubar — man muss nur wissen, wo man hinschaut. Der Context enthält die Angaben, mit denen Dienste ihre Signale verbinden — im Kern Trace-ID und Span-ID.

1:24 Propagation bedeutet: Beim Verlassen eines Dienstes wird dieser Context serialisiert, beim Empfänger wieder eingelesen. Zuständig sind Propagatoren, und der Standard folgt der W3C-Spezifikation Trace Context. Stellen Sie sich einen Laufzettel vor, der mit einem Vorgang durchs Haus wandert: Jede Abteilung trägt ihren Teil ein, aber der Zettel selbst kommt von der vorherigen Station.

1:46 Geht er unterwegs verloren, fängt die nächste Abteilung einen neuen an — und niemandem fällt es auf. Das ist der ganze Zauber: eine Zeichenkette in einem HTTP-Header. Vier Teile, durch Bindestriche getrennt — Version, Trace-ID, Span-ID des Absenders und ein paar Flags. Worauf es ankommt: Sie können das im Browser-Werkzeug, im Proxy-Log oder mit einem einfachen Mitschnitt selbst nachsehen. Genau das ist die Fehlersuchtechnik dieses Moduls.

2:14 Ist der Header im ausgehenden Aufruf da, hat der Sender seine Arbeit getan. Ist er nicht da, brauchen Sie im Empfänger gar nicht weiterzusuchen. Daneben gibt es noch tracestate für herstellerspezifische Zusatzangaben — das brauchen Sie selten. Diese Kette zeigt, was passieren soll: Der Annahmedienst erzeugt den Context, gibt ihn per traceparent an den Bon-Dienst weiter, der reicht ihn an die Auszahlung durch.

2:40 Jeder Dienst erzeugt eigene Spans, aber alle tragen dieselbe Trace-ID. Entscheidend ist, dass jede Weitergabe aktiv passieren muss. Es gibt keinen automatischen Mechanismus im Netz, der das für Sie erledigt. In der Praxis erledigt es die Instrumentierung Ihrer HTTP-Bibliothek — solange Sie eine verwenden, die der Agent kennt.

3:00 Vier Konsequenzen, und sie hängen zusammen. Jeder Dienst erzeugt einen eigenen Trace, und keiner zeigt den Vorgang. Die Latenz lässt sich nicht mehr aufsummieren — Sie wissen, dass jeder Dienst schnell war, aber nicht, warum das Ganze langsam ist. Der Fehler wird dem letzten Dienst zugeschrieben statt dem verursachenden; das führt zu erstaunlich zähen Diskussionen zwischen Teams.

3:22 Und Logs lassen sich nicht mehr über die Trace-ID zusammenführen, womit der Nutzen aus Modul vier verloren geht. Alles wegen eines fehlenden Headers. Der erste Punkt ist die häufigste Ursache: ein selbst gebauter HTTP-Client, den die Instrumentierung nicht kennt und der die Header nicht mitkopiert. Der zweite ist besonders ärgerlich, weil er außerhalb Ihres Codes liegt — ein Reverse Proxy entfernt unbekannte Header.

3:47 Das ist manchmal sogar so konfiguriert, aus guten Gründen; man muss es nur wissen. Der dritte ist historisch gewachsen: ein eigener Korrelationsheader, der parallel existiert und zu nichts passt. Und der vierte ist Konfigurationsdrift — die Propagatoren sind je Dienst verschieden eingestellt.

Unterbrochene Zusammenhänge

4:05 Jetzt zu den Stellen, an denen der Context auch dann verloren geht, wenn Sie alles richtig gemacht haben. Der Grund ist technisch: Der Context hängt am Ausführungspfad. Überall dort, wo dieser Pfad verlassen wird, muss man nachhelfen — und diese Stellen sind erstaunlich zahlreich. Das ist die unangenehme Sorte Problem: Alles ist richtig konfiguriert, und trotzdem zerfällt der Zusammenhang.

4:27 Wer die betroffenen Stellen einmal kennt, erkennt sie in jedem Projekt wieder — es sind immer dieselben. Der Context ist an den aktuellen Ausführungspfad gebunden. Thread-Wechsel, Nebenläufigkeit, Warteschlangen, zeitversetzte Verarbeitung — überall dort muss er ausdrücklich mitgeführt werden. Und für Vorgänge, zwischen denen keine Eltern-Kind-Beziehung besteht, gibt es Span Links.

4:51 Das ist ein wichtiges Detail: Wenn ein Stapellauf zehn Anfragen gemeinsam verarbeitet, ist keine davon der Elternteil. Ein Link sagt „das hängt zusammen", ohne eine Hierarchie zu behaupten, die es nicht gibt. Die Logik dieser Tabelle ist einheitlich: Immer dort, wo der synchrone Faden endet, muss der Context von Hand mitreisen. Beim Thread-Wechsel übergeben Sie ihn ausdrücklich.

5:14 Bei der Warteschlange legen Sie ihn in die Nachricht — dort, wo auch die Nutzdaten stehen. Bei der Stapelverarbeitung setzen Sie einen Link je Ursache. Und bei einem Wiederholungsversuch einen Link auf den ersten Versuch. Die Fußzeile enthält die begriffliche Feinheit, die man sich merken sollte: Links verbinden, ohne eine Eltern-Kind-Beziehung zu behaupten.

5:35 Wer stattdessen eine Elternbeziehung setzt, verfälscht die Dauer des übergeordneten Spans. Und hier liegt das eigentliche Problem dieses Moduls. Es entsteht kein Fehler, sondern nur ein zweiter, unauffälliger Trace. Die Latenzsumme sieht plausibel aus, weil der fehlende Teil einfach fehlt — man vermisst nichts, was man nie gesehen hat.

5:55 Erst die Suche nach einem konkreten Vorgang bringt die Lücke ans Licht, und das passiert typischerweise im schlechtesten Moment, nämlich während einer Störung. Deshalb der Rat: Die Prüfung gehört in die Abnahme eines neuen Dienstes, nicht in die Störungssuche. Der erste Punkt beschreibt genau das gerade Gesagte: Der asynchrone Teil erzeugt eigene Traces, und niemand bemerkt es monatelang.

6:18 Der zweite ist eine halbe Lösung — der Context wird in die Nachricht gelegt, aber beim Lesen nicht wiederhergestellt. Der dritte ist der Link, der fälschlich als Elternbeziehung gesetzt wird und die Dauer verfälscht. Und der vierte ist unauffällig: Die Warteschlange trägt den Context, aber der Consumer-Span fehlt ganz. Dann sehen Sie, dass etwas abgeschickt wurde, aber nicht, was damit geschehen ist.

Baggage und seine Risiken

6:42 Kommen wir zum dritten Kapitel, und das ist eines, bei dem ich Sie ausdrücklich zur Vorsicht raten möchte. Baggage ist ein sehr nützlicher Mechanismus — und einer, mit dem man ohne böse Absicht erheblichen Schaden anrichten kann. Das liegt nicht an der Technik, sondern an der Reichweite: Baggage verlässt Ihr System und wandert in Systeme, über die Sie nichts wissen.

7:02 Deshalb gehört zu diesem Kapitel eine Datenschutzbetrachtung und nicht nur eine Konfigurationsanleitung. Baggage überträgt beliebige Schlüssel-Wert-Paare über Dienstgrenzen hinweg und erlaubt es, Kontext für Metriken und andere Zwecke mitzuführen. Der entscheidende Unterschied zu Span-Attributen steht im letzten Satz: Baggage wandert automatisch weiter — auch dorthin, wo man es nicht erwartet.

7:25 Ein Span-Attribut bleibt an seinem Span. Baggage steigt in jeden ausgehenden Aufruf mit ein, ohne dass Sie an der jeweiligen Stelle noch einmal darüber nachdenken. Das ist der Komfort, und das ist das Risiko. Lesen Sie die vier Punkte als Eskalation. Baggage geht an jeden nachgelagerten Dienst, auch an fremde. Es kann unterwegs protokolliert werden, ohne dass jemand es vorgesehen hat — fremde Systeme loggen gern ihre eingehenden Header.

7:50 Die Dokumentation warnt deshalb ausdrücklich vor Zugangsdaten, Schlüsseln und personenbezogenen Daten in Baggage-Feldern. Und der vierte Punkt ist der, der die Sache ernst macht: Was die Vertrauensgrenze verlassen hat, ist praktisch nicht mehr zurückzuholen. Bei Pfandwerk heißt diese Grenze Girokette. Diese Gegenüberstellung ist die Entscheidungshilfe für den Alltag. Ein Span-Attribut bleibt lokal und ist für die Auswertung gedacht — bei Fachdaten unkritisch.

8:18 Baggage wandert mit jeder Anfrage, ist auch bei Fremden sichtbar und für die Weitergabe gedacht — bei allem Sensiblen kritisch. Die praktische Regel daraus: Nehmen Sie Baggage nur für Dinge, die ein nachgelagerter Dienst wirklich braucht und die niemandem schaden, wenn sie irgendwo im Log auftauchen. Eine Filialkennung erfüllt das. Eine Kundennummer nicht.

8:38 Sie üben hier etwas, das in der Praxis fast immer vergessen wird: den Geltungsbereich begrenzen. Konkret wandert die Filiale als Baggage bis zur Auszahlung — dort wird sie gebraucht — und wird vor dem Aufruf der Girokette entfernt. Der Hinweis ist wichtig: Prüfen Sie den ausgehenden Aufruf, nicht die Absicht. Entscheidend ist, was tatsächlich über die Leitung geht, und das sehen Sie nur, wenn Sie hinschauen.

9:01 Die schriftliche Begründung gehört dazu, denn diese Entscheidung muss auch in einem Jahr noch nachvollziehbar sein. Der erste Punkt ist die Zweckentfremdung: Baggage als bequemer Transportweg für Anwendungsdaten. Es funktioniert, es ist verlockend, und es ist die falsche Schicht. Der zweite ist der Ernstfall — personenbezogene Daten landen im Log eines Fremdsystems. Das ist dann kein Observability-Problem mehr, sondern ein meldepflichtiger Vorgang.

9:29 Der dritte ist harmlos, aber häufig: Baggage wird gesetzt und nie als Attribut übernommen, bleibt also wirkungslos. Und der vierte ist ein Governance-Problem — jeder Dienst ergänzt Felder, und niemand kennt den Gesamtinhalt. Schreiben Sie auf, was drinsteht.

Übung

9:46 Zum Abschluss von Tag eins reparieren wir den Trace, der in Modul fünf abgerissen ist. Rechnen Sie mit etwas Suchen — der erste durchgehende Trace über alle Dienste ist in fast jedem Projekt ein kleiner Meilenstein. Dafür nehmen Sie eine Technik mit, die Sie in jeder Umgebung wieder brauchen werden und die dieselbe Frage künftig in wenigen Minuten klärt.

10:06 Drei Ergebnisse: Eine Rücknahme erscheint als ein Trace über alle drei Dienste, die Filiale liegt als Baggage vor, und vor dem Aufruf der Girokette ist sie entfernt. Der Hinweis nennt die Abkürzung zur Lösung — sehen Sie sich zuerst die Header des ausgehenden Aufrufs an. Fehlt der traceparent dort, liegt das Problem im Sender, und Sie können sich den Empfänger sparen. Diese Reihenfolge spart bei echten Störungen erfahrungsgemäß die Hälfte der Zeit.

10:32 Der rote Faden führt von der Diagnose über die Reparatur zur Absicherung. Zuerst bestimmen Sie anhand der Trace-IDs, wo es abreißt. Dann prüfen Sie die ausgehenden Header. Im dritten Schritt stellen Sie die Propagation her — und zwar an der Bruchstelle, nicht daneben. Danach kommt die Baggage-Übung: setzen, übernehmen, und vor der Vertrauensgrenze wieder entfernen.

10:54 Die Fußzeile enthält den bleibenden Rat: Diese Prüfung gehört in die Abnahme jedes neuen Dienstes. Einmal eingeführt, kostet sie fast nichts — nachträglich suchen kostet Tage. Der erste Punkt ist eine Scheinlösung: Die Reparatur erfolgt im Empfänger, indem man dort einen Trace-Zusammenhang erfindet. Das sieht im Backend richtig aus und ist es nicht.

11:15 Der zweite ist eine halbe Sache — der Trace ist durchgehend, aber die Spans tragen kein Kind, und das Backend erkennt keine Dienstgrenzen. Der dritte ist menschlich: Die Baggage-Entfernung wird vergessen, weil die Übung mit dem durchgehenden Trace gefühlt gelöst war. Und der vierte ist der Reflex, einen eigenen Header einzuführen, statt den vorhandenen zu nutzen. Damit sind Sie wieder bei Punkt drei aus dem ersten Kapitel.

Lieber mit Trainer? Dieses Modul ist Teil unserer Team-Schulungen — mit Übungen, Ihrem eigenen Code und Fragen, die ein Video nicht beantwortet. Mehr erfahren →