OpenTelemetry-based observability stack for monitoring AI coding assistants (Claude Code, Codex). Collects metrics, logs, and traces via OTLP and visualizes them in Grafana.
flowchart TB
subgraph Clients["AI Coding Assistants"]
CC[Claude Code]
CX[Codex]
end
CC -->|OTLP gRPC :4317| Collector
CX -->|OTLP HTTP :4318| Collector
subgraph Stack["Docker Compose Stack"]
subgraph Collector["OpenTelemetry Collector"]
direction TB
R[Receivers<br/>OTLP gRPC / HTTP]
P[Processors<br/>batch, deltatocumulative]
E[Exporters]
R --> P --> E
end
subgraph Storage
VictoriaMetrics[("VictoriaMetrics<br/>:8428<br/>Metrics")]
Loki[("Loki<br/>:3100<br/>Logs")]
ClickHouse[("ClickHouse<br/>:8123/:9000<br/>Analytics")]
end
Grafana["Grafana<br/>:3030<br/>Dashboard"]
E -->|remote write| VictoriaMetrics
E -->|push API| Loki
E -->|native protocol| ClickHouse
E -->|debug| Debug[Collector Logs]
VictoriaMetrics --> Grafana
Loki --> Grafana
ClickHouse --> Grafana
end
| Signal | Path |
|---|---|
| Metrics | Client → Collector → batch → deltatocumulative → VictoriaMetrics + ClickHouse → Grafana |
| Logs | Client → Collector → batch → Loki + ClickHouse → Grafana |
| Traces | Client → Collector → batch → ClickHouse → Grafana |
| Service | Image | Port |
|---|---|---|
| OpenTelemetry Collector | otel/opentelemetry-collector-contrib:0.120.0 |
4317, 4318 |
| VictoriaMetrics | victoriametrics/victoria-metrics:v1.108.1 |
8428 |
| Loki | grafana/loki:3.4.2 |
3100 |
| ClickHouse | clickhouse/clickhouse-server:25.3 |
8123, 9000 |
| Grafana | grafana/grafana:11.5.2 |
3030 |
docker compose up -dOpen Grafana at http://localhost:3030 — no login required (anonymous access enabled).
The pre-provisioned Claude Code dashboard shows:
- Overview — total cost, sessions, tokens, lines of code changed
- Cost & Tokens — cost by model, token usage by type
- Activity — lines of code, commits, pull requests, active time
- Tool Usage — code edit tool decisions, token usage by model
- Events — raw Claude Code event logs
Claude Code sends OTLP telemetry automatically when the collector is running on localhost:4317.
Add the following to ~/.codex/config.toml:
[otel]
exporter = { otlp-http = { endpoint = "http://localhost:4318/v1/logs", protocol = "binary" } }Codex emits structured log events (codex.conversation_starts, codex.api_request, codex.tool_decision, codex.tool_result, etc.) and metrics (counters/histograms for API, stream, and tool activity).
Set log_user_prompt = true under [otel] to include user prompts in logs (redacted by default).
| Metric | Labels |
|---|---|
claude_code_cost_usage_USD_total |
model |
claude_code_session_count_total |
— |
claude_code_token_usage_tokens_total |
type, model |
claude_code_lines_of_code_count_total |
type |
claude_code_commit_count_total |
— |
claude_code_pull_request_count_total |
— |
claude_code_active_time_seconds_total |
type |
claude_code_code_edit_tool_decision_total |
tool_name, decision |
| File | Purpose |
|---|---|
docker-compose.yml |
Service definitions and volumes |
otel-collector-config.yml |
Collector receivers, processors, exporters, pipelines |
prometheus.yml |
VictoriaMetrics scrape config (Prometheus-compatible format) |
clickhouse-users.xml |
ClickHouse user config (allows network access) |
grafana/provisioning/datasources/datasources.yml |
Grafana datasource definitions |
grafana/provisioning/dashboards/claude-code.json |
Pre-built Grafana dashboard |