Files
developerandClaude Sonnet 5 c20a0b77f3
Build and Publish / Metadata (push) Successful in 2s
Build and Publish / BuildAndDeployAmd64 (push) Failing after 5s
Add frontend error collector, CORS/ingest guards, and static doc routes (Phase 3)
- Add static/otel-rum.js: a framework-free browser script that captures
  uncaught errors, unhandled promise rejections and failed resource loads,
  translating them into OTLP log records POSTed to the existing /v1/logs
  endpoint (source: frontend attribute) so they flow through the same
  history/search/issue pipeline as backend telemetry.
- Add correlation-id support: traceHeaders() (manual) and same-origin
  fetch auto-instrumentation inject a W3C traceparent header, so a
  frontend error and the backend spans it triggered share a trace id and
  can be found together via GET /api/traces/{traceId}.
- Add CORS handling (withCORS in cmd/server/main.go) on the OTLP HTTP
  endpoints, required for any browser-origin POST.
- Add an optional shared ingest key (OTEL_INGEST_KEY, via '?key=' or
  X-Otel-Ingest-Key) and a per-IP rate limit (20 rps/burst 50) on OTLP
  HTTP ingestion, to scope/protect a public endpoint fed by a browser
  script. Verified end-to-end (CORS preflight, cross-origin POST, ingest
  key enforcement, rate limiting) against a running server.
- Serve static/otel-rum.js and agents_example.md as static HTTP routes so
  both the script and the agent instructions doc are fetchable directly
  from the base URL.
- Ignore the separately-cloned otel-ui/ frontend repo (has its own .git;
  not meant to be nested into this repo's history).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-17 10:20:42 +00:00

3.0 KiB

Improvement plan

Priority order: (1) agent endpoints, (2) recent issues for the web UI, (3) a Sentry-like frontend error collector.

Phase 1 — Agent endpoints (highest priority)

  • Fix HandleHistoryByType: it only filtered the in-memory ring buffer (capped at historySize, default 100) instead of the persistent store, so /api/history/traces|metrics|logs silently returned far less than /api/history/search could see. Now routed through SearchHistory.
  • Structured filters on /api/history/search and /api/history/wait: type=, since=, until= (unix nanoseconds), combinable with the existing free-text q=.
  • GET /api/traces/{traceId} — assemble all entries referencing one trace id in a single call, instead of relying on substring search matching the id inside raw JSON.
  • Basic per-IP rate limiting on /api/history/wait (a blocking long-poll, cheap to abuse).
  • Cursor-based pagination for /api/history/search (deferred).
  • Machine-readable tool manifest (/.well-known/agent-tools.json or an MCP server) replacing agents_example.md (deferred).

Phase 2 — Recent issues for the web UI

  • Fingerprint spans with status=ERROR/exception events and logs with severity >= ERROR into deduped Issues (count, firstSeen, lastSeen, sample entries, affected services), updated incrementally on ingest. internal/issues (fingerprinting/dedup) + internal/collector/issue_extract.go (OTLP field extraction).
  • GET /api/issues, GET /api/issues/{id}.
  • UI "Issues" tab (lives in the separate frontend/dist project — this repo's API is ready for it).

Phase 3 — Frontend error collector (Sentry-style)

  • static/otel-rum.js: captures uncaught errors, unhandledrejection, resource load failures; translates them to OTLP log records client-side and POSTs to the existing /v1/logs endpoint (so Phase 2's issue derivation picks them up for free via a source: frontend attribute). Verified end-to-end against a running server: an ingested frontend error shows up in GET /api/issues and GET /api/traces/{traceId}.
  • Correlation-id injection: traceHeaders() (manual) and auto-injection into same-origin fetch calls, using a W3C traceparent header so a backend span sharing that trace id and the frontend error that triggered it show up together via /api/traces/{traceId}.
  • CORS support on the OTLP HTTP endpoints (withCORS in cmd/server/main.go), verified with a live cross-origin POST.
  • Lightweight ingest key (OTEL_INGEST_KEY, checked via Collector.checkIngest) for scoping noisy pages, plus a per-IP rate limit (20 rps/burst 50) on the OTLP HTTP ingestion endpoints so a runaway error loop can't hammer the collector. Not real auth.
  • Explicitly out of scope for v1: source map resolution, session replay, PII scrubbing (documented in README.md and the script's header comment).