CtrlK
BlogDocsLog inGet started
Tessl Logo

kopai/otel-instrumentation

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).

Quality

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Low

Low-risk findings worth noting

Overview
Quality
Evals
Security
Files

validate-shutdown.mdreferences/

titleimpacttags
Validate ShutdownHIGHvalidate, shutdown, flush

Validate Shutdown

The batch processor buffers. A process that exits without flushing drops everything it was holding — typically the last few seconds, which is exactly the window containing the crash you wanted to debug.

This failure is invisible during normal development: long-running servers flush on their interval and look fine, while short-lived jobs and crashed processes silently lose their tail. Assert on it once, explicitly.

S1 — The final batch lands

RUN_ID=$(uuidgen); export OTEL_RESOURCE_ATTRIBUTES="validation.run_id=$RUN_ID"
# start the app, drive one request, then:
kill "$APP_PID"        # SIGTERM — never kill -9
sleep 5

npx @kopai/cli traces search --resource-attr "validation.run_id=$RUN_ID" --json | jq 'length'

Pass: the spans from just before the signal are present. Fail: shutdown isn't flushing. Three usual causes:

  • No signal handler is registered, so the process exits immediately
  • The handler calls exit() before shutdown() resolves — it must be awaited
  • The shutdown timeout is shorter than the export takes; give it 10–30s

Each language's setup in references/lang-<language>.md shows the shutdown hook. Verify it exists in your code rather than assuming the SDK installed one — most SDKs do not.

S2 — Short-lived processes flush too

For CLI tools, jobs, serverless handlers, and test runs, the process may finish before the first scheduled export ever fires.

Pass: a one-shot invocation produces spans in Kopai. Fail: the run ended before the batch interval. Two fixes, in order of preference:

  1. Call forceFlush() (or the language equivalent) before exiting — correct and explicit
  2. Set OTEL_BSP_SCHEDULE_DELAY=500 — a blunt instrument that shortens the window but never closes it

For serverless, flushing before returning is mandatory, not an optimisation: the runtime freezes the process the moment your handler returns, and the buffer freezes with it.

S3 — Telemetry failure never breaks the app

Stop Kopai, then start the app:

# with the Kopai backend stopped
<start your app>
curl -s -o /dev/null -w "%{http_code}\n" "$BASE/"

Pass: the app starts and serves traffic normally. Export errors may be logged; that is fine. Fail: the app refuses to start, hangs, or 500s because it can't reach the collector. Instrumentation must never be load-bearing. Wrap SDK init so a failure logs and continues — an observability outage that takes production down with it is worse than no observability.

Done when

S1–S3 pass. That closes the loop: the telemetry is correct, complete, survives shutdown, and cannot take the service down. Report what you instrumented, which assertions you ran, and the $RUN_ID they were green against.

references

_sections.md

architectural-patterns.md

attributes.md

cli-reference.md

context-propagation.md

custom-instrumentation.md

drive-traffic.md

instrument-attributes.md

instrument-errors.md

instrument-spans.md

lang-cpp.md

lang-dotnet.md

lang-erlang.md

lang-fastify.md

lang-go.md

lang-java.md

lang-nextjs.md

lang-nodejs.md

lang-php.md

lang-python.md

lang-ruby.md

lang-rust.md

layered-telemetry.md

nextjs-examples.md

otel-docs.md

sampling.md

setup-backend.md

setup-environment.md

troubleshoot-missing-attrs.md

troubleshoot-missing-spans.md

troubleshoot-no-data.md

troubleshoot-wrong-port.md

validate-logs.md

validate-metrics.md

validate-shutdown.md

validate-traces.md

CHANGELOG.md

SKILL.md

tile.json