A local observability stack for monitoring Claude Code usage, costs, and productivity metrics using OpenTelemetry, Prometheus, Loki, and Grafana.
This project was almost entirely auto-generated by Claude Opus 4.5 using Claude Code.
Claude Code → OpenTelemetry Collector (4317) → Prometheus (metrics) → Grafana (8000)
→ Loki (logs) ↗
| Service | Purpose | Port |
|---|---|---|
| OpenTelemetry Collector | Receives telemetry from Claude Code | 4317 (gRPC), 4318 (HTTP) |
| Prometheus | Time-series database for metrics | 9090 |
| Loki | Log aggregation for events | 3100 |
| Grafana | Visualization & dashboards | 8000 |
git clone https://github.com/acreeger/claude-code-metrics-stack.git
cd claude-code-metrics-stack
make upAdd these to your ~/.zshrc or ~/.bashrc:
# Claude Code Telemetry - sends metrics to local Grafana stack
export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_METRICS_EXPORTER=otlp
export OTEL_LOGS_EXPORTER=otlp
export OTEL_EXPORTER_OTLP_PROTOCOL=grpc
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
export OTEL_METRIC_EXPORT_INTERVAL=10000
export OTEL_LOGS_EXPORT_INTERVAL=5000Then reload your shell:
source ~/.zshrc- URL: http://localhost:8000
- Login:
admin/admin - Dashboard: Pre-provisioned under "Claude Code" folder
| Metric | Description |
|---|---|
claude_code.session.count |
CLI sessions started |
claude_code.cost.usage |
Session cost in USD (by model) |
claude_code.token.usage |
Tokens consumed (input/output/cache) |
claude_code.lines_of_code.count |
Lines added/removed |
claude_code.commit.count |
Git commits created |
claude_code.pull_request.count |
PRs created |
claude_code.code_edit_tool.decision |
Tool accept/reject decisions |
Claude Code also sends events that can be searched in Loki:
claude_code.user_prompt- Your prompts to Claudeclaude_code.tool_result- Tool executions (Read, Edit, Bash, etc.)claude_code.api_request- API calls with token countsclaude_code.api_error- Any failures
- Go to Grafana → Explore (compass icon)
- Select Loki as data source
- Query examples:
{service_name="claude-code"} {service_name="claude-code"} |= "error" {service_name="claude-code"} | json
make up # Start all services
make down # Stop all services
make restart # Restart all services
make status # Check service health
make logs # View all logs
make logs-collector # View OTel collector logs
make clean # Stop and remove volumes
make setup-claude # Show Claude Code config instructions| File | Purpose |
|---|---|
docker-compose.yml |
Service definitions |
collector-config.yaml |
OpenTelemetry collector config |
prometheus/prometheus.yml |
Prometheus scrape config |
loki/loki-config.yaml |
Loki storage config |
grafana/provisioning/ |
Auto-configured datasources & dashboards |
grafana/dashboards/claude-code-dashboard.json |
Pre-built dashboard |
export OTEL_LOG_USER_PROMPTS=1export OTEL_RESOURCE_ATTRIBUTES="team.id=your-team,department=engineering"export OTEL_METRICS_INCLUDE_SESSION_ID=false
export OTEL_METRICS_INCLUDE_ACCOUNT_UUID=false- Claude Code Monitoring Docs - Official documentation
- Reddit: Complete Docker Compose Setup - Community post that inspired this project
- Reddit: TIL Claude Code has OpenTelemetry metrics
- ColeMurray/claude-code-otel - Similar project
- Quesma Blog - Claude Code + Grafana
MIT