Dashboard gains a per-route latency bar chart (nested p50/p95/p99 bars, tail
visible) + status-colored waterfall with ms duration labels + a real 3s
auto-refresh (replacing the non-functional data-on-load SSE attr). serve.sh
self-warms the serving JIT over /dev/tcp so the first visitor after a restart
gets ~78ms not the one-time ~2.5s compile. otel suite 125/125.
otel/format-traceparent + otel/current-traceparent emit '00-<32hex>-<16hex>-01';
otel/parse-traceparent round-trips it (nil on malformed/bad-width). otel/-timed
now guards the thunk: success spans get :status ok, a raised error records a
span with :status error + an exception event then propagates. Error propagation
uses a false-returning guard clause test (an explicit (raise e) in a guard
handler re-enters the guard and hangs).
otel/export-otlp folds spans → OTLP/JSON envelope (resourceSpans → scopeSpans →
spans) with hex traceId(32)/spanId(16)/parentSpanId, uint64-as-string nano
timestamps, typed attributes (stringValue/intValue), and span kind
(SERVER/INTERNAL). otel/export-otlp-json encodes via dream-json-encode;
otel/post-otlp POSTs through an injected transport (testable without a live
collector).
otel/dashboard SSRs the metrics strip + latest-trace waterfall + recent-traces
list as HTML carrying Datastar-style data-on-load subscribing to /otel/stream,
the SSE feed of SXTP otel.span events. Routes otel/dashboard-route +
otel/stream-route (otel/routes) mount via make-app. recent-traces/latest-trace
+ otel/span-event helpers.
otel/metrics folds spans → {:total-requests :routes}; each route carries a
request count and nearest-rank latency percentiles over its durations. Route
key is the http.route attr (falls back to span name). Includes a small
insertion sort (no sort primitive) and order-preserving distinct.
otel/waterfall-rects folds a trace's spans into rect geometry (x by start
offset, width by duration, y by depth via parent-link ancestor count);
otel/waterfall folds those into an inline <svg> (one <rect>+<text> per span).
Renders to real SVG markup via the html tag registry.
otel/instrument-routes wraps each flattened Dream route's handler in a timed
span named METHOD /route with {:http.method :http.route :http.status} attrs;
host/make-app applies it so every matched request becomes a trace. Refactored
with-span onto a shared otel/-timed core that takes a finalize fn for
result-derived attrs (the http.status only known post-handler).
Clamp against a high-water mark so the clock never steps backwards; span
durations stay non-negative. Real ns-scale timestamps replace the P1
placeholder counter.