How to use
oteldebug catches OpenTelemetry data on its way out of your application. You get a short-lived token, stamp your telemetry with it, and every span, log record and metric carrying that stamp shows up on the console in near real time. Nothing else is stored, and everything is wiped when the token expires.
01 generate a debug token
- Open the console and hit generate token.
- The token is a 32-character hex string, valid for 5 minutes. The countdown is on the console.
- The page URL now carries
?token=…: bookmark or share it to look at the same session.
Retry-After the
API hands back.
02 stamp your telemetry
Add an attribute named oteldebug whose value is the token. Where it goes depends on the signal:
- traces: a
spanattribute (the collector filters spans without it). - logs: a
log recordattribute. - metrics: a
resourceattribute.
03 send it to the collector
| protocol | endpoint |
|---|---|
| otlp/grpc | localhost:4317 |
| otlp/http | http://localhost:4318/v1/traces · /v1/logs · /v1/metrics |
With telemetrygen (from the collector-contrib repo) a full run looks like this:
telemetrygen traces \
--otlp-endpoint localhost:4317 \
--otlp-insecure \
--traces 10 --rate 1 --duration 10s \
--status-code Ok --span-duration 100ms \
--telemetry-attributes 'oteldebug="YOUR_TOKEN_HERE"'
Or with plain curl against the OTLP/HTTP endpoint:
curl -sS http://localhost:4318/v1/traces \
-H 'Content-Type: application/json' \
-d '{"resourceSpans":[{"resource":{"attributes":[{"key":"service.name","value":{"stringValue":"checkout"}}]},
"scopeSpans":[{"spans":[{"traceId":"5b8efff798038103d269b633813fc60c","spanId":"eee19b7ec3c1b174",
"name":"GET /cart","kind":2,"startTimeUnixNano":"1700000000000000000","endTimeUnixNano":"1700000000100000000",
"attributes":[{"key":"oteldebug","value":{"stringValue":"YOUR_TOKEN_HERE"}}]}]}]}]}'
04 watch it land
The console polls the API every 5 seconds and shows the newest 100 items of each signal. Expand a row to see
the raw OTLP JSON, json copies it, link copies a URL that opens straight on that item. The
filter box greps the current tab; press / to focus it.
how it works
- Your app exports OTLP to the OpenTelemetry Collector (gRPC 4317 / HTTP 4318).
- A
filterprocessor drops anything without theoteldebugattribute. - What survives is published as OTLP JSON to Kafka (
otel-traces,otel-logs,otel-metrics). - The Go API consumes the topics, checks the token is known and unexpired, and stores the payload in PostgreSQL.
- This page reads it back through the REST API. A cleanup job purges expired tokens and their data every minute.
api
| method | path | notes |
|---|---|---|
| POST | /api/tokens | new token; rate-limited (5/min per client) |
| GET | /api/tokens/{token}/status | valid, expires_at |
| GET | /api/tokens/{token}/traces | newest 100; 401 once expired |
| GET | /api/tokens/{token}/logs | same |
| GET | /api/tokens/{token}/metrics | same |
| GET | /healthz · /readyz | liveness · readiness (db ping) |
local stack
| service | address |
|---|---|
| web | http://localhost:3000 (or WEB_PORT) |
| api | proxied at /api by the web container |
| otlp/grpc | localhost:4317 |
| otlp/http | localhost:4318 |
| kafka ui | http://localhost:8900 |