- 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>
58 lines
3.0 KiB
Markdown
58 lines
3.0 KiB
Markdown
# 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)
|
|
|
|
- [x] 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`.
|
|
- [x] Structured filters on `/api/history/search` and `/api/history/wait`:
|
|
`type=`, `since=`, `until=` (unix nanoseconds), combinable with the
|
|
existing free-text `q=`.
|
|
- [x] `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.
|
|
- [x] 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
|
|
|
|
- [x] 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).
|
|
- [x] `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)
|
|
|
|
- [x] `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}`.
|
|
- [x] 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}`.
|
|
- [x] CORS support on the OTLP HTTP endpoints (`withCORS` in
|
|
`cmd/server/main.go`), verified with a live cross-origin POST.
|
|
- [x] 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.
|
|
- [x] Explicitly out of scope for v1: source map resolution, session
|
|
replay, PII scrubbing (documented in README.md and the script's
|
|
header comment).
|