Skip to content

cotelClaude Code Telemetry

One container. OTLP ingest + interactive analytics dashboard for Claude Code.

Quick start ​

bash
docker run -d \
  --name cotel \
  -p 4318:4318 \
  -p 8080:8080 \
  -v cotel-data:/data \
  ghcr.io/flopsstuff/cotel:main

Open http://localhost:8080 for the dashboard.

Point Claude Code at cotel ​

Add to your ~/.claude/settings.json:

json
{
  "env": {
    "CLAUDE_CODE_ENABLE_TELEMETRY": "1",
    "CLAUDE_CODE_ENHANCED_TELEMETRY_BETA": "1",
    "OTEL_TRACES_EXPORTER": "otlp",
    "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT": "http://localhost:4318/v1/traces"
  }
}

Restart Claude Code. Telemetry starts flowing immediately.

Ports ​

PortPurpose
4318OTLP/HTTP trace ingest (POST /v1/traces)
8080Analytics dashboard

Environment variables ​

VariableDefaultDescription
COTEL_DB_PATH/data/cotel.duckdbDuckDB file path
COTEL_INGEST_ADDR:4318Ingest listener address
COTEL_DASH_ADDR:8080Dashboard listener address
COTEL_RETENTION_RAW_DAYS30Raw span retention in days (roll-up consumes whole days, so spans survive up to a day longer)
COTEL_RETENTION_AGGREGATE_DAYS90Daily aggregate retention in days
COTEL_RETENTION_INTERVAL6hRetention worker tick interval

Data & retention ​

Data lives in the named volume at /data/cotel.duckdb. You can query it directly:

bash
docker run --rm -v cotel-data:/data ubuntu \
  duckdb /data/cotel.duckdb "SELECT model, COUNT(*) FROM spans GROUP BY model"
TierPeriodTable
Raw spans30 daysspans
Daily aggregates90 daysdaily_usage

Architecture ​

Claude Code  →  OTLP/HTTP (port 4318)  →  ingest handler
                                           ↓
                                        DuckDB (named volume)
                                           ↓
dashboard (port 8080)  ←─────────────────┘

Single Go binary. Single DuckDB file. Single named volume. No sidecars.

Documentation ​

Released under the MIT License.