Auf dieser Seite
Architektureigenschaft
COADF P-4 ist vollständig veröffentlicht. Eine Kennung entsteht, wenn ein Dokument aufgenommen wird, und begleitet jeden Verarbeitungsschritt, jede Konfidenzbewertung, jede menschliche Entscheidung und die veröffentlichte Ausgabe. Die Spur wächst nur an, eine einzige Abfrage rekonstruiert die Kette, und die Kette lässt sich als JSON exportieren, für jemanden, der das System nicht gebaut hat. Das veröffentlichte Schema der Prüfspur benennt die Felder: trace_id, timestamp, event_type, actor, input, output, decision, source_hash und immutable.
Zwei Eigenschaften tragen das. Kontinuität: Jeder Schritt trägt dieselbe Identität, über jede Grenze hinweg, die er überschreitet. Beständigkeit: Der Eintrag zu jedem Schritt bleibt erhalten, und niemand kann ihn nachträglich bearbeiten, damit die Antwort besser aussieht.
Warum sie wichtig ist
Die Frage, die P-4 beantwortet, kommt spät und von außen. Monate nach der Veröffentlichung fragt jemand, woher ein Wert stammt, was ihn gelesen hat und wer ihn sich angesehen hat. Die Antwort muss sich von jemandem rekonstruieren lassen, der das System nicht gebaut hat, aus Einträgen, die in der Zwischenzeit niemand umschreiben konnte.
Ein verteilter Trace ist keine fachliche Prüfspur
Diese Unterscheidung verwischen die meisten Implementierungen, weil die Werkzeuge einander ähneln: Beide haben eine Kennung, beide überschreiten Dienstgrenzen, beide zeigen Schritte der Reihe nach. Sie beantworten verschiedene Fragen und geben verschiedene Zusagen.
| Aspekt | Verteilter Trace | Prüfspur |
|---|---|---|
| Zweck | Eine Ausführung erklären: Latenz, Fehler, Aufrufstruktur | Feststellen, was mit einem Vorgang geschah und wer gehandelt hat |
| Identität | Ein Trace pro Anfrage oder Job, im W3C-Header traceparent mitgeführt | Eine trace_id pro fachlichem Vorgang, bei der Aufnahme erzeugt |
| Lebensdauer | Die Dauer der Anfrage; Aufbewahrung in Tagen gemessen | So lange wie die Datensätze, die sie begründet |
| Sampling | Sampling ist üblich und zulässig | Kein Sampling: Ein fehlender Eintrag ist ein Defekt |
| Veränderbarkeit | Pipelines filtern, verwerfen und schreiben per Konfiguration um | Append-only: Eine Berichtigung ist ein neuer Eintrag |
| Inhalt | Spans, Zeitmessungen, Attribute, gewählt für die Diagnose | Fachliche Ereignisse: Eingabe, Ausgabe, Entscheidung, Akteur |
Die W3C-Spezifikation Trace Context definiert den Header traceparent, und OpenTelemetry-SDKs geben standardmäßig tracecontext und baggage weiter. Diese Identität gilt pro Ausführung. In OpenTelemetry wird ein Trace, der nicht gesampelt wird, nicht exportiert, und der Filter-Prozessor des Collectors verwirft Telemetrie, die eine Bedingung erfüllt. Beides ist für die Diagnose korrektes Verhalten und schließt eine Verwendung als Nachweis aus.
Die beiden lassen sich korrelieren: die trace_id der Prüfspur als Attribut auf jedem Span festhalten und die Kennung des verteilten Trace in den Logs. Keines von beiden darf zum anderen gemacht werden. Ein einzelner fachlicher Vorgang erstreckt sich regelmäßig über mehrere verteilte Traces: eine Aufnahmeanfrage, einen asynchronen Verarbeitungsjob, eine Tage später getroffene Entscheidung, die Ausgabe.
Korrelation kopiert die Kennung der Prüfspur in die Telemetrie, und Telemetrie überschreitet weitere Grenzen: Exporter, Anbieter, Zugriffsregeln und Aufbewahrungsfristen, die meist lockerer sind als die des Speichers der Prüfspur. Die Kennung wird klassifiziert, bevor sie hinausgeht: eine opake Referenz, nie personenbezogene Daten und nie ein Geheimnis. Wo die Kennung der Prüfspur selbst eine Bedeutung trägt, wird über eine getrennte, nicht sensible Referenz korreliert.
Beispielarchitektur · Nicht normativ
Verteilte Traces und eine Prüfspur
- Korrelation über die trace_id der Prüfspur
Textbeschreibung. Obere Bahn, verteilte Traces: vier getrennte Traces, je einer für eine Aufnahme-Anfrage, einen Verarbeitungsjob, eine Tage später getroffene Entscheidung und eine Ausgabe. Sie sind nicht miteinander verbunden. Untere Bahn, die Prüfspur: vier illustrative Einträge, Aufnahme, Verarbeitung, Entscheidung und Ausgabe, alle mit derselben trace_id, getrennt von der Telemetrie persistiert und nicht gesampelt. Eine Notiz in der Bahn besagt, dass die Ereignisse illustrativ sind und kein von COADF vorausgesetzter Workflow. Eine gestrichelte Linie verbindet jeden Trace mit dem Eintrag, dem er entspricht, beschriftet als Span-Attribut, das die trace_id der Prüfspur trägt.
Zulässige Umsetzungsstrategien
Einmal erzeugen, bei der Aufnahme
Die Kennung entsteht dort, wo der Vorgang eintritt, und nirgends sonst. Jede spätere Komponente verlangt sie, und keine erzeugt eine. Eine fehlende Kennung ist ein Fehler, nie ein Grund, eine neue zu erzeugen, und ein Standardwert in einem Nachrichtenmodell ist der häufigste Weg, diese Regel zu brechen, ohne dass es jemand bemerkt.
Explizit über jede Grenze mitführen
- Im Prozess: ein Funktionsargument oder der Anfragekontext.
- Zwischen Diensten: ein Feld im Anfrage- oder Nachrichtenvertrag, wo ein Schema es verlangen kann.
- In geplanten Aufgaben: ein Job-Argument.
- Im Speicher: eine Spalte in jeder gespeicherten Zeile.
Propagation-Bibliotheken führen den Ausführungskontext für einen mit. Die Identität der Prüfspur ist Teil des eigenen Vertrags und gehört in die Nutzlast.
Dauerhaft speichern, nur anhängend
Mehrere Umsetzungen sind zulässig, und sie lassen sich kombinieren:
- Persistenz nur durch Einfügen. Das Repository bietet Anhängen und Lesen an und sonst nichts.
- Datenbankrechte. Die Rolle der Anwendung hat
INSERTundSELECTauf der Prüfspur und keinUPDATE,DELETEoderTRUNCATE. - Trigger, die Umschreibungen verweigern, als zusätzliche Verteidigungslinie für Sitzungen, die doch weitergehende Rechte haben, mit einem Trigger auf Anweisungsebene für
TRUNCATE, denn in PostgreSQL löstTRUNCATEkeineON DELETE-Trigger aus. - Ein unveränderliches Ereignismodell, in dem eine Berichtigung ein neues Ereignis ist, das ein früheres ablöst.
- Eine Ablösungskonvention. Der aktuelle Wert eines Attributs ist der neueste Eintrag dazu; die Historie sind alle Einträge.
Event Sourcing ist ein Weg zu einer Append-only-Historie, und nicht der einzige; siehe die Technologie-Notiz.
Den Eintrag mit der Änderung schreiben
Den Eintrag der Prüfspur in derselben Datenbanktransaktion festhalten wie die Zustandsänderung, die er beschreibt, oder über eine transaktionale Outbox, sodass keines ohne das andere existieren kann.
Wiederholungen idempotent machen
Den Zeitpunkt des Schritts festhalten, wenn der Schritt läuft, und bei einer Wiederholung denselben Eintrag erneut senden. Einträge erhalten einen natürlichen eindeutigen Schlüssel, damit ein wiederholter Schreibvorgang aufgefangen statt verdoppelt wird. In PostgreSQL überspringt ON CONFLICT DO NOTHING eine Zeile, die mit einem Unique-Constraint oder -Index kollidiert, statt einen Fehler auszulösen, und genau deshalb kann es nicht die ganze Antwort sein: Ein Konflikt ist nicht immer eine Wiederholung. Derselbe Schlüssel mit anderem Inhalt ist ein zweiter Schreiber oder ein Bug. Den gespeicherten Eintrag vergleichen, bevor der Schreibvorgang als Wiederholung gilt, und deutlich fehlschlagen, wenn er abweicht.
Mit einer Abfrage rekonstruieren, als JSON exportieren
Braucht die Rekonstruktion jemanden, der das System kennt, gilt P-4 nicht. Nach Zeitstempel ordnen und angeben, was diese Reihenfolge nicht klärt: Einträge mit demselben Zeitstempel sind durch keines der veröffentlichten Felder geordnet.
Was ein Trigger nicht leistet
Rechte und Trigger sind Kontrollen innerhalb der eigenen Vertrauensgrenze der Datenbank. In PostgreSQL umgeht ein Superuser alle Rechteprüfungen, und der Eigentümer der Tabelle kann ihre Trigger deaktivieren. Eine Append-only-Tabelle ist daher eine starke Kontrolle gegenüber der Anwendung und eine schwache gegenüber ihren Administratoren. Manipulationsnachweis gegenüber privilegierten Innentätern braucht eine Kontrolle außerhalb der Datenbank, und er ist eine eigene Eigenschaft, getrennt von Append-only-Persistenz. Keines von beiden ist für sich eine rechtliche Aussage über Beweise.
Fehlermuster
Die Kennung auf halbem Weg neu erzeugt
Ein Konsument oder Worker erzeugt eine neue Kennung, wenn das Feld fehlt, oft über einen Standardwert in einem Nachrichtenmodell. Das Ergebnis sind zwei Hälften eines Vorgangs und keine Abfrage, die sie verbindet.
Die Spur existiert nur in Logs
Logs rotieren, werden gesampelt, sind unstrukturiert und werden von Code geschrieben, der sie als Diagnose behandelt. Eine Kette, die sich nur aus Logs wieder aufbauen lässt, lässt sich nicht verlässlich wieder aufbauen.
Eine asynchrone Grenze verliert den Kontext
Thread-Pools, Executors und Broker führen nichts mit, solange nichts es kopiert. In Python ist für
asyncio.to_threaddokumentiert, dass es den aktuellen Kontext weitergibt; fürrun_in_executorist nichts dergleichen dokumentiert, und dasto_threadvon CPython selbst kopiert den Kontext ausdrücklich, bevor es die Funktion aufruft. In Spring braucht ein Executor einen Task-Decorator, der den Kontext weitergibt.Gespeicherte Zeilen lassen sich nicht mit ihren Nachweisen verbinden
Kein
source_hash, oder ein Hash über etwas anderes als die tatsächlich gelesenen Bytes, sodass dieselbe Eingabe nie wiedererkannt werden kann.Wiederholungen erzeugen mehrdeutige Einträge
Ein Zeitstempel, der beim Einfügen genommen wird, macht aus jeder Wiederholung einen neuen, anderen Eintrag, und die Spur sagt dann, ein Schritt sei zweimal geschehen.
Ein Konflikt als Wiederholung verworfen
Ein eindeutiger Schlüssel und
ON CONFLICT DO NOTHING, sonst nichts: Ein zweiter Eintrag mit demselben Schlüssel und einer anderen Entscheidung verschwindet ohne Fehler, und die Spur behält den, der zuerst ankam.Eine Berichtigung überschreibt
Ein
UPDATEzerstört, was zuvor angenommen wurde, und die Spur kann nicht mehr erklären, warum eine frühere Ausgabe sagte, was sie sagte.Eine Dienstgrenze beginnt einen neuen Trace
Ein Gateway entfernt einen Header, den es nicht kennt, eine Client-Bibliothek gibt nichts weiter, ein Batch-Job beginnt bei null. Jedes davon bleibt unsichtbar, bis jemand zu rekonstruieren versucht.
Das Tracing-Backend als Prüfspur verwendet
Sein Sampling, seine Aufbewahrung und seine veränderbare Pipeline sind für die Diagnose richtig und für Nachweise falsch.
Systemuhren zum Ordnen von Schritten über mehrere Hosts verwendet
Zeitstempel verschiedener Maschinen ordnen Einträge nur so gut, wie ihre Uhren übereinstimmen. Innerhalb eines Vorgangs ist ein einzelner Schreiber, oder eine von einem einzigen Schreiber vergebene Reihenfolge, verlässlicher als die Uhrzeit mehrerer Hosts.
Verifikation
Integrationstest
Bestanden, wenn: Von einer veröffentlichten Ausgabe zurück zu ihren Quellen: Eine Abfrage liefert jeden Eintrag, alle mit derselben
trace_id, mit demsource_hashjedes gelesenen Dokuments.Zahnbeweis: In einem Arbeitszweig die Kennung an einem asynchronen Übergang weglassen. Der Rekonstruktionstest muss fehlschlagen, statt eine kürzere Kette zu liefern, die vollständig aussieht.
Integrationstest
Bestanden, wenn: Eine Berichtigung hängt an: Danach existieren beide Einträge, und der spätere löst den früheren ab.
Zahnbeweis: Das Anhängen durch ein Update ersetzen: Der Test schlägt fehl.
Integrationstest
Bestanden, wenn: Eine exakte Wiederholung wird aufgefangen, und derselbe Schlüssel mit anderem Inhalt wird abgewiesen, nicht aufgefangen.
Zahnbeweis: Jeden Konflikt ohne Vergleich als Wiederholung behandeln: Der Test, der unter demselben Schlüssel anderen Inhalt schreibt, schlägt fehl.
Integrationstest
Bestanden, wenn: Gegen die echte Datenbank kann die Rolle der Anwendung die Prüfspur weder aktualisieren noch löschen noch leeren.
Zahnbeweis: In einer Wegwerf-Datenbank der Rolle
UPDATEgewähren: Der Test schlägt fehl.Vertragstest
Bestanden, wenn: Jedes Nachrichtenschema, das eine asynchrone Grenze überschreitet, verlangt die Kennung der Prüfspur.
Zahnbeweis: Das Feld optional machen: Der Vertragstest schlägt fehl.
End-to-End-Test
Bestanden, wenn: Eine Anfrage, die sich auf einen Job und eine Nachricht verzweigt, behält eine einzige Identität für die Prüfspur, geprüft in der gespeicherten Spur und nicht in den Logs.
Manueller Nachweis
Bestanden, wenn: Eine Kette als JSON exportieren und von einer Person, die das System nicht gebaut hat, allein daraus die Geschichte der Ausgabe rekonstruieren lassen.
Alternative Umsetzungen
- Event Sourcing. Der Event Store ist die Historie, und der Zustand wird daraus abgeleitet. Starke Eigenschaften für die Prüfspur und eine große architektonische Festlegung.
- Change Data Capture. Zeilenänderungen, aus dem Log der Datenbank gelesen. Nützlich für Replikation; es hält fest, was sich geändert hat, nicht wer entschieden hat oder warum, und ersetzt daher keine fachlichen Einträge der Prüfspur.
- Write-once-Objektspeicher für exportierte Ketten, wo die Aufbewahrung die Datenbank überdauern muss.
- Ledger- oder manipulationsnachweisende Speicher, wo Manipulation durch Innentäter zum Bedrohungsmodell gehört.
Grenzen
- Das Muster entscheidet nicht, welche Schritte für eine bestimmte Regulierung oder ein bestimmtes Produkt relevant sind.
- Append-only-Persistenz ist kein Manipulationsnachweis, und keines von beiden ist eine rechtliche Schlussfolgerung über Beweise.
- Es legt keine Aufbewahrungsfristen fest.
- Es setzt voraus, dass jede Komponente den Vertrag einhält. Eine Komponente, die das nicht tut, wird vom Rekonstruktionstest gefunden, nicht durch ihn verhindert.
Quellen
- W3C: Trace Context, the traceparent header · Spezifikation · W3C Recommendation, Level 1 · Geprüft am 2026-09-11
- OpenTelemetry: SDK environment variables: OTEL_PROPAGATORS · Spezifikation · Specification 1.60.0 · Geprüft am 2026-09-11
- OpenTelemetry: Sampling · offizielle Dokumentation · Geprüft am 2026-09-11
- OpenTelemetry: Transforming telemetry · offizielle Dokumentation · Geprüft am 2026-09-11
- PostgreSQL Global Development Group: TRUNCATE · offizielle Dokumentation · PostgreSQL 18 · Geprüft am 2026-09-11
- PostgreSQL Global Development Group: INSERT: ON CONFLICT · offizielle Dokumentation · PostgreSQL 18 · Geprüft am 2026-09-11
- PostgreSQL Global Development Group: Role attributes · offizielle Dokumentation · PostgreSQL 18 · Geprüft am 2026-09-11
- PostgreSQL Global Development Group: ALTER TABLE: DISABLE TRIGGER · offizielle Dokumentation · PostgreSQL 18 · Geprüft am 2026-09-11
- Python Software Foundation: asyncio: Task and to_thread · Sprachdokumentation · Python 3.14 · Geprüft am 2026-09-11
- CPython: Lib/asyncio/threads.py · Projekt-Repository · CPython 3.14.7 · Geprüft am 2026-09-11
- Spring Framework: Observability support: context propagation · offizielle Dokumentation · Spring Framework 7.0 · Geprüft am 2026-09-11
