I wanted to know exactly what I was getting out of Claude Code. Not vibes. Numbers.
So I built some Grafana dashboards that track everything: tokens, cost, lines of code, productivity ratios, ROI. Here's how to set it up yourself.
The Stack
- Claude Code with native OTEL telemetry (yes, it has this built in)
- Prometheus as the metrics backend
- Grafana for visualization
Step 1: Enable OTEL Export from Claude Code
Add these to your shell profile (~/.zshrc or ~/.bashrc):
export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_METRICS_EXPORTER=otlp
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:9090/api/v1/otlp
Restart your terminal or source the file.
Step 2: Configure Prometheus
Prometheus needs two flags to accept OTLP metrics:
prometheus \
--config.file=prometheus.yml \
--web.enable-otlp-receiver \
--enable-feature=otlp-deltatocumulative
If you're using Homebrew on macOS, you might need to edit the service plist or create a wrapper script.
The otlp-deltatocumulative flag is important. Some Claude Code metrics (like lines of code) are delta metrics, not cumulative. This flag handles the conversion automatically.
Step 3: Verify Metrics Are Flowing
Once you've used Claude Code with the new env vars, check that Prometheus is receiving data:
curl 'http://localhost:9090/api/v1/label/__name__/values' | jq '.data[]' | grep claude
You should see metrics like:
claude_code_token_usage_tokens_totalclaude_code_cost_usage_USD_totalclaude_code_active_time_seconds_totalclaude_code_lines_of_code_count_totalclaude_code_session_count_total
The Metrics Claude Code Exports
| Metric | Labels | What It Tracks |
|---|---|---|
claude_code_token_usage_tokens_total |
type (input/output/cacheRead/cacheCreation), model
|
Token consumption |
claude_code_cost_usage_USD_total |
model |
Estimated API cost |
claude_code_active_time_seconds_total |
type (cli/user) |
Time tracking |
claude_code_lines_of_code_count_total |
type (added/removed) |
Code output (delta metric) |
The active_time metric is interesting. cli is how long Claude was working. user is how long you were interacting. The ratio between them is your productivity multiplier.
Step 4: Import the Dashboards
I've created three dashboards:
- Claude Code Metrics - Token stats, cost breakdown, productivity ratio
- Daily/Weekly Summary - Aggregated stats with time-range awareness
- Engineering Economics - ROI calculations, team equivalence, business metrics
The dashboards use Grafana variables so you can customize:
- Your hourly rate (for ROI calculations)
- Average developer lines/hour (for team equivalence)
Key Queries
Productivity Ratio (CLI time / User time):
sum(claude_code_active_time_seconds_total{type="cli"})
/ sum(claude_code_active_time_seconds_total{type="user"})
Lines per Dollar:
sum(sum_over_time(claude_code_lines_of_code_count_total[$__range]))
/ sum(increase(claude_code_cost_usage_USD_total[$__range]))
Equivalent Developer Hours (assuming 75 lines/hour):
sum(sum_over_time(claude_code_lines_of_code_count_total[$__range])) / 75
Max Plan ROI (for $200/month subscribers):
sum(increase(claude_code_cost_usage_USD_total[$__range]))
/ (6.67 * ($__range_s / 86400))
A Note on Lines of Code
The lines_of_code metric is a delta metric, not cumulative. This means you need sum_over_time() instead of increase():
# Wrong - will give weird extrapolated values
sum(increase(claude_code_lines_of_code_count_total[$__range]))
# Correct
sum(sum_over_time(claude_code_lines_of_code_count_total[$__range]))
Results
Here's what one hour looked like for me:
- 27,000 lines of code
- 11 minutes of my time
- 362x velocity multiplier
- $47K equivalent output value
The productivity ratio peaked at over 10,000x when I had multiple parallel agents running.
Dashboard JSON
I'll put the dashboard JSON files in a GitHub gist. You can import them directly into Grafana via Dashboards → Import.
[Link to gist coming]
What About Datadog/Other Backends?
The OTEL export should work with any OTLP-compatible backend. Just change the endpoint:
export OTEL_EXPORTER_OTLP_ENDPOINT=https://your-backend-endpoint
For Datadog, you'd point to their OTLP intake endpoint. Same metrics, different destination.
What's Next
I'm planning to add:
- Alerts when productivity ratio drops (maybe I'm stuck?)
- Cost projections based on current burn rate
- Comparison panels for different projects
If you build on this, let me know what you come up with.
Top comments (0)