DEV Community

Mike Lane
Mike Lane

Posted on

How I Built Real-Time Dashboards for Claude Code Metrics with OTEL, Prometheus, and Grafana

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

You should see metrics like:

  • claude_code_token_usage_tokens_total
  • claude_code_cost_usage_USD_total
  • claude_code_active_time_seconds_total
  • claude_code_lines_of_code_count_total
  • claude_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:

  1. Claude Code Metrics - Token stats, cost breakdown, productivity ratio
  2. Daily/Weekly Summary - Aggregated stats with time-range awareness
  3. 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"})
Enter fullscreen mode Exit fullscreen mode

Lines per Dollar:

sum(sum_over_time(claude_code_lines_of_code_count_total[$__range])) 
/ sum(increase(claude_code_cost_usage_USD_total[$__range]))
Enter fullscreen mode Exit fullscreen mode

Equivalent Developer Hours (assuming 75 lines/hour):

sum(sum_over_time(claude_code_lines_of_code_count_total[$__range])) / 75
Enter fullscreen mode Exit fullscreen mode

Max Plan ROI (for $200/month subscribers):

sum(increase(claude_code_cost_usage_USD_total[$__range])) 
/ (6.67 * ($__range_s / 86400))
Enter fullscreen mode Exit fullscreen mode

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]))
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)