Instrument applications with the OpenTelemetry SDK and prove the telemetry is good by validating it against a local Kopai backend. Use when setting up observability, adding tracing/logging/metrics, deciding what to instrument or which attributes to add, retrofitting OTel into an existing codebase, threading context through call chains, configuring sampling, or when traces/logs/metrics aren't appearing after setup. Also use when users say things like "my traces aren't showing up", "I don't see any data", or "how do I add observability to my app". Do NOT use to investigate existing telemetry for a root cause (use root-cause-analysis), to build dashboards (use create-dashboard), or to instrument LLM and agent calls (use otel-genai-instrumentation).
—
—
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Low
Low-risk findings worth noting
| title | impact | tags |
|---|---|---|
| No Data Received | HIGH | troubleshoot, no-data |
Nothing arrived at all. Work down this list in order — each step rules out one layer, so skipping ahead wastes time on the wrong layer.
The most common cause of "no data" is no traffic. Confirm you drove the app in this run —
drive-traffic.md — before debugging the pipeline.
curl -s -o /dev/null -w '%{http_code}\n' -X POST http://localhost:4318/v1/traces \
-H 'Content-Type: application/json' -d '{"resourceSpans":[]}'Not 2xx → Kopai isn't running. npx @kopai/app start (setup-backend.md).
echo "$OTEL_EXPORTER_OTLP_ENDPOINT" # must be http://localhost:4318, not 8000Port 8000 is the query API and does not accept OTLP — troubleshoot-wrong-port.md.
Check this in the shell that launched the app, not the one you're typing in. Exports made after the process started never reach it.
Go and Java SDKs default to gRPC on 4317. Kopai is HTTP-only:
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobufSymptom: connection refused or a hanging exporter, logged by the app at startup.
Short-lived processes routinely exit with a full buffer. Indistinguishable from a broken pipeline until you check.
export OTEL_BSP_SCHEDULE_DELAY=500Stop servers with SIGTERM (kill $PID), never SIGKILL, and sleep 2 before asserting.
Full detail in validate-shutdown.md.
Read the app's own startup output. SDK init failures are usually logged and then swallowed, so the app runs perfectly while emitting nothing.
export OTEL_LOG_LEVEL=debug # most SDKs; Node.js also honours OTEL_LOG_LEVEL=allLook for exporter errors, a missing endpoint, or an SDK that never started. In Node.js
specifically, confirm the instrumentation file is loaded before the app —
node --import ./instrumentation.mjs server.mjs, not require from inside server.mjs.
echo "$OTEL_TRACES_SAMPLER" # always_off or a tiny ratio explains total silence
export OTEL_TRACES_SAMPLER=always_onRule out a filter typo before concluding nothing arrived:
npx @kopai/cli traces search --limit 50 --json | jq 'length'Rows here but none for your --resource-attr "validation.run_id=$RUN_ID" means the run
tag never reached the process — re-export OTEL_RESOURCE_ATTRIBUTES and restart the app.
Data exists but not the spans you expected → troubleshoot-missing-spans.md.
Spans exist but are bare → troubleshoot-missing-attrs.md.
references