feat: Phase 2 — request tracing & persistence (OpenTelemetry + SQLite)#4
Merged
Conversation
Implements ROADMAP Phase 2 (PRP C7): every request is an OpenTelemetry span — provider, model, status, latency, token usage — persisted to a queryable store and exposed via an admin-gated read API. - OTel SDK: a span per request; a custom SpanExporter persists spans to the trace store; optional OTLP export when OTEL_EXPORTER_OTLP_ENDPOINT is set. Tracer resolved lazily so it binds to the registered provider. - Trace store: TraceStore interface with SQLite (better-sqlite3) and in-memory backends, behind a createTraceStore factory. - GET /traces + /traces/:id, gated by SENTINEL_ADMIN_KEY (distinct from client keys). Filters: model/provider/status/stream/since/until/limit. - Privacy: metadata only — no prompt/response bodies; keys SHA-256 hashed. - 69 tests, 93% branch coverage; pnpm verify + CI green. Live-verified in-process against a real SQLite store + OTel bootstrap.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
ROADMAP Phase 2 — tracing & persistence (PRP C7). Every request becomes an OpenTelemetry span — provider, model, status, latency, token usage — persisted to a queryable store and exposed through an admin-gated read API.
onRequesthook; a customTraceStoreSpanExporterpersists finished spans to the trace store; optional OTLP/HTTP export to Jaeger/a collector whenOTEL_EXPORTER_OTLP_ENDPOINTis set. The tracer is resolved lazily per request so it binds to the registered provider (not a no-op captured at import).TraceStoreinterface with SQLite (better-sqlite3) and in-memory backends behind acreateTraceStorefactory. Streaming and the hijacked SSE path are traced inline (noonResponseafter hijack); the span ends exactly once.GET /traces(+/traces/:id) gated by a dedicatedSENTINEL_ADMIN_KEY, distinct from client keys. Filters:model,provider,status,stream,since,until,limit(≤500),offset.SECURITY_REVIEW_LOGSR-002.)How to verify
Live smoke test
Ran the full path in-process against a real SQLite store + the real OTel bootstrap (
initTelemetry):GET /traceswith the admin key -> 200, returning the persisted trace: model, provider,durationMs, token usage (8/4/12), andapiKeyHash(a sha256, not the raw key)GET /traceswithout the admin key -> 401Notes
better-sqlite3pinned to v11 (v12 had no prebuilt binary for the local Node 20 / Windows setup; v11 ships one and also covers CI's Linux/Node 22). Added topnpm.onlyBuiltDependencies. Falls back to the in-memory store if the native module is ever unavailable.nullunless the client sendsstream_options.include_usage(deferred). Per-key trace scoping deferred — admin-only for now.