A self-contained observability stack for OpenCode, built on the
opencode-plugin-otel
plugin. Ships a Grafana dashboard with cost/token analytics, TraceQL-based explainability, and
a standalone session timeline (waterfall) explorer.
| Grafana dashboard | Trace Explorer — Overview |
|---|---|
![]() |
![]() |
| Trace Explorer — Sessions |
|---|
![]() |
- Docker with Compose v2 (
docker compose) just(optional — wraps common commands)- Bun (only if building the plugin from source — see below)
docker compose up -d
# or: just upOption A — npm (recommended, no build step):
Add the plugin to ~/.config/opencode/opencode.json (merge into your existing config):
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["@devtheops/opencode-plugin-otel"]
}OpenCode installs it automatically at startup from the npm registry. The published package includes pre-built output — no Bun required.
Option B — local file: path (for development/customization):
Clone and build the plugin manually first — OpenCode does not build it for you:
git clone https://github.com/DEVtheOPS/opencode-plugin-otel ~/projects/opencode-plugin-otel
cd ~/projects/opencode-plugin-otel
bun install
bun run buildThen reference it by absolute path:
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["@devtheops/opencode-plugin-otel@file:/home/you/projects/opencode-plugin-otel"]
}Note:
~is not valid here — use the full absolute path. OpenCode symlinks the directory into its cache; ifdist/is missing or stale the plugin loads silently but does nothing. Re-runbun run buildafter any source change.
Git URLs (e.g.
github:DEVtheOPS/opencode-plugin-otel) do not work — thepreparescript is absent so the build never runs anddist/is never produced.
Export environment variables before running opencode:
export OPENCODE_ENABLE_TELEMETRY=1
export OPENCODE_OTLP_ENDPOINT=http://localhost:4317
export OPENCODE_OTLP_PROTOCOL=grpcOr add these to your shell profile (.bashrc, .zshrc, etc.).
Dashboards will be empty until you run OpenCode (step 5).
| URL | Service |
|---|---|
| http://localhost:3000 | Grafana — "OpenCode Observability" (admin/admin) |
| http://localhost:8060 | Trace Explorer |
| http://localhost:9090 | Prometheus |
| http://localhost:3200 | Tempo |
| http://localhost:4317 | OTLP collector — gRPC ingest (used by the plugin) |
| http://localhost:3100 | Loki |
Now when you run opencode, traces and metrics will be emitted to the local OTLP collector and visible in the dashboards above.
See the Quick Start guide for the full walkthrough.
Stop the stack:
docker compose down
# or: just downRemove the plugin and its config:
rm -rf ~/projects/opencode-plugin-otelRemove the plugin entry from ~/.config/opencode/opencode.json:
{
"plugin": ["file:///home/you/projects/opencode-plugin-otel"]
}Delete that line (or the entire "plugin" key if it's the only entry).
Also remove the telemetry env vars from your shell profile if you added them.
- Cost & token analytics — usage by model, agent, and session; breakdown by token type
- Tool usage — call counts, average duration, and success rate per tool
- Productivity — lines added/removed, message counts per session
- TraceQL tables — LLM calls (prompt → model → outcome) and tool calls (tool → params → result)
- Trace → Logs linking — click a span in Grafana to jump to matching Loki logs
- Trace Explorer — React/FastAPI waterfall SPA with session timelines, subagent linking, and a cross-session usage dashboard
- Dashboard filters —
session_id,model, andagenttemplate variables apply to every panel
Full documentation is published at
schemaitat.github.io/opencode-otel-observability,
or browse it directly in docs/:
- Architecture — how the services fit together
- Quick Start — start the stack and connect OpenCode
- Metrics, Logs & Traces — what's exported and how to query it
- Dashboard — the Grafana "OpenCode Observability" dashboard
- Trace Explorer — the standalone waterfall + usage dashboard UI
- Configuration — collector, Tempo, and Grafana datasource details
- Development —
justtargets and local dev workflow


