otel P6: live dashboard — GET /otel SSR + /otel/stream SSE
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.
This commit is contained in:
@@ -202,6 +202,63 @@
|
||||
(host-ot-test "empty metrics total 0" (get host-ot-me :total-requests) 0)
|
||||
(host-ot-test "empty metrics no routes" (len (get host-ot-me :routes)) 0)
|
||||
|
||||
;; ── P6: live dashboard (SSR + SSE) ─────────────────────────────────
|
||||
;; Drive two traces through instrumented routes, then check: recent-traces lists
|
||||
;; them (newest first); the dashboard SSRs to HTML with the metrics strip + the
|
||||
;; latest-trace <svg>; the /otel/stream SSE endpoint emits an SXTP span event.
|
||||
(otel/reset!)
|
||||
(define host-ot-dapp
|
||||
(dream-router (otel/instrument-routes
|
||||
(list
|
||||
(dream-get "/feed" (fn (req) (dream-response 200 {} "ok")))
|
||||
(dream-get "/health" (fn (req) (dream-response 200 {} "ok")))))))
|
||||
(host-ot-dapp (dream-request "GET" "/feed" {} ""))
|
||||
(host-ot-dapp (dream-request "GET" "/health" {} ""))
|
||||
|
||||
(host-ot-test "recent-traces lists both" (len (otel/recent-traces)) 2)
|
||||
(host-ot-test "recent-traces newest first"
|
||||
(get (first (otel/recent-traces)) :name) "GET /health")
|
||||
(host-ot-test "latest-trace is the /health trace"
|
||||
(otel/-trace-root-name (otel/latest-trace)) "GET /health")
|
||||
|
||||
;; dashboard SSRs to an HTML string carrying the strip + waterfall + trace list
|
||||
(define host-ot-dash (render-to-html (otel/dashboard) {}))
|
||||
(host-ot-test "dashboard is a string" (= (type-of host-ot-dash) "string") true)
|
||||
(host-ot-test "dashboard has the root id" (contains? host-ot-dash "otel-dashboard") true)
|
||||
(host-ot-test "dashboard SSRs the waterfall svg" (contains? host-ot-dash "<svg") true)
|
||||
(host-ot-test "dashboard shows a route in the strip" (contains? host-ot-dash "/feed") true)
|
||||
(host-ot-test "dashboard declares the SSE subscription" (contains? host-ot-dash "/otel/stream") true)
|
||||
|
||||
;; the SSE endpoint emits a span event, SSE-framed
|
||||
(define host-ot-sse
|
||||
((dream-route-handler otel/stream-route) (dream-request "GET" "/otel/stream" {} "")))
|
||||
(host-ot-test "sse content type is event-stream"
|
||||
(contains? (str (dream-headers host-ot-sse)) "event-stream") true)
|
||||
(host-ot-test "sse body is SSE-framed" (contains? (dream-resp-body host-ot-sse) "data:") true)
|
||||
(host-ot-test "sse emits an otel.span event"
|
||||
(contains? (dream-resp-body host-ot-sse) "otel.span") true)
|
||||
(host-ot-test "sse event carries the span name"
|
||||
(contains? (dream-resp-body host-ot-sse) "GET /health") true)
|
||||
|
||||
;; span-event helper carries the type + span
|
||||
(define host-ot-ev (otel/latest-span-event))
|
||||
(host-ot-test "latest span event type" (str (get host-ot-ev :type)) "otel.span")
|
||||
|
||||
;; mounted through make-app: GET /otel serves the dashboard page
|
||||
(otel/reset!)
|
||||
(feed/reset!)
|
||||
(define host-ot-mapp (host/make-app (list host/feed-routes otel/routes)))
|
||||
(define host-ot-otelresp (host-ot-mapp (dream-request "GET" "/otel" {} "")))
|
||||
(host-ot-test "GET /otel status 200" (dream-status host-ot-otelresp) 200)
|
||||
(host-ot-test "GET /otel serves the dashboard"
|
||||
(contains? (dream-resp-body host-ot-otelresp) "otel-dashboard") true)
|
||||
|
||||
;; empty ring → dashboard still SSRs (a placeholder, no svg)
|
||||
(otel/reset!)
|
||||
(define host-ot-empty-dash (render-to-html (otel/dashboard) {}))
|
||||
(host-ot-test "empty dashboard still renders" (contains? host-ot-empty-dash "otel-dashboard") true)
|
||||
(host-ot-test "empty stream body is blank" (otel/-stream-body) "")
|
||||
|
||||
(define
|
||||
host-ot-tests-run!
|
||||
(fn
|
||||
|
||||
Reference in New Issue
Block a user