From 351131e92b80873dbbe5a2cf1ba6f4743770a4b0 Mon Sep 17 00:00:00 2001 From: giles Date: Wed, 1 Jul 2026 16:12:26 +0000 Subject: [PATCH] =?UTF-8?q?otel:=20tick=20P8,=20log=20progress=20=E2=80=94?= =?UTF-8?q?=20roadmap=20P1-P8=20complete=20(124/124)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plans/otel-loop.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plans/otel-loop.md b/plans/otel-loop.md index b0133a77..057def06 100644 --- a/plans/otel-loop.md +++ b/plans/otel-loop.md @@ -61,11 +61,12 @@ type-block grammar + type-def editor). You are on branch `loops/otel` in attributes). `otel/export-otlp traces` → the JSON; POST to an OTLP HTTP collector via an **injected transport** (so it's testable without a live collector). Tests: OTLP shape matches the spec for a known trace; the transport receives the payload. -- [ ] **P8 — context propagation + errors.** Parse/emit the W3C `traceparent` header so a trace +- [x] **P8 — context propagation + errors.** Parse/emit the W3C `traceparent` header so a trace spans services (fed with the host's inter-service calls); mark error spans (`:status :error` + an event). Tests: traceparent round-trips; an error thunk yields an error span. ## Progress log (newest first) +- 2026-07-01 — P8 done — **ROADMAP COMPLETE (P1–P8, 124/124)**. `otel/format-traceparent`/`otel/current-traceparent` emit W3C `00-<32hex trace>-<16hex span>-01`; `otel/parse-traceparent` → `{:version :trace-id :parent-id :flags :sampled}`, nil on malformed/bad-width — round-trips. `otel/-timed` now GUARDS the thunk: success spans get top-level `:status "ok"` (attrs untouched), a raised error records a span with `:status "error"` + an `{:name "exception" :message}` event, pops the stack, and propagates. 20 new tests (traceparent round-trip + current + malformed; error span status/name/event/message + clean stack; success=ok). GOTCHA (saved to memory): an explicit `(raise e)` inside a guard handler RE-ENTERS the same guard and hangs — propagate instead via a clause whose TEST does the side-effect and returns `false`, letting R7RS guard auto-reraise to the outer handler. - 2026-07-01 — P7 done. `otel/export-otlp spans` folds → the OTLP/JSON envelope `{:resourceSpans [{:resource … :scopeSpans [{:scope … :spans […]}]}]}`; each span has hex `traceId`(32)/`spanId`(16)/`parentSpanId` (from `otel/-pad-hex` of the numeric id suffix via `string->number`+`number->string _ 16`), uint64-as-string `startTimeUnixNano`/`endTimeUnixNano`, typed `attributes` (number→`intValue`, else `stringValue`), and `kind` (2 SERVER if http.method, else 1 INTERNAL); root omits `parentSpanId`. `otel/export-otlp-json` → `dream-json-encode`. `otel/post-otlp endpoint spans transport` POSTs `{:method :url :headers :body}` through an INJECTED transport (tests pass a recorder; real deploy passes http POST). Suite 104/104 (26 new: nesting depth, hex widths+values, string timestamps, kinds, typed attrs, parentSpanId link, json+transport, empty envelope). All needed prims (`string->number`,`number->string`radix,`split`,`keys`,`assoc`,`has-key?`,`dream-json-encode`) are real (not server-env), so conformance-safe. - 2026-07-01 — P6 done. `GET /otel` (`otel/dashboard-route`) SSRs `otel/dashboard`: metrics strip (table) + latest-trace waterfall `` + recent-traces `