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

Published: (December 17, 2025 at 02:54 PM EST)
3 min read
Source: Dev.to

Source: Dev.to

Overview

I wanted concrete numbers from Claude Code—tokens, cost, lines of code, productivity ratios, ROI. This guide shows how to collect telemetry with OTEL, store it in Prometheus, and visualize it in Grafana.

Prerequisites

  • Claude Code with native OTEL telemetry enabled
  • Prometheus (v2.45+ recommended)
  • Grafana (v10+ recommended)
  • jq for JSON parsing (optional, for verification)

1. Enable Telemetry in Claude Code

Add the following environment variables to your shell profile (~/.zshrc, ~/.bashrc, etc.):

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

After editing, reload the profile:

source ~/.zshrc   # or source ~/.bashrc

2. Configure Prometheus to Receive OTLP Metrics

Prometheus must be started with the OTLP receiver enabled and the delta‑to‑cumulative conversion flag:

prometheus \
  --config.file=prometheus.yml \
  --web.enable-otlp-receiver \
  --enable-feature=otlp-deltatocumulative

Note: On macOS with Homebrew, you may need to edit the service plist or wrap the command in a script to include these flags.

Why otlp-deltatocumulative?

Some Claude Code metrics (e.g., lines of code) are delta metrics. The flag automatically converts them to cumulative counters, which Prometheus expects.

3. Verify Data Ingestion

Run the following command to list metric names that Prometheus has received:

curl 'http://localhost:9090/api/v1/label/__name__/values' | jq '.data[]' | grep claude

You should see metrics such as:

  • 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

4. Metric Reference

MetricLabelsDescription
claude_code_token_usage_tokens_totaltype (input/output/cacheRead/cacheCreation), modelToken consumption
claude_code_cost_usage_USD_totalmodelEstimated API cost (USD)
claude_code_active_time_seconds_totaltype (cli/user)Time tracking (CLI vs. user)
claude_code_lines_of_code_count_totaltype (added/removed)Code output (delta metric)
claude_code_session_count_totalNumber of Claude sessions

Interpreting active_time

  • type="cli" – how long Claude was processing.
  • type="user" – how long you were interacting.

The productivity multiplier is cli time / user time.

5. Grafana Dashboards

I 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.

Importing

Export the JSON files to a GitHub gist (link pending) and import via Dashboards → Import in Grafana.

6. Grafana Variables & Useful Queries

Define variables for:

  • Hourly rate – used in ROI calculations.
  • Average developer lines/hour – for team equivalence.
  • Productivity RatioCLI time / User time.

Example Queries

Productivity Ratio

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))

Handling Delta Metrics

claude_code_lines_of_code_count_total is a delta metric, so use sum_over_time() instead of increase():

# Incorrect – yields 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]))

7. Sample Output (One Hour)

  • 27,000 lines of code
  • 11 minutes of user time
  • 362× velocity multiplier
  • $47 K equivalent output value

The productivity ratio peaked above 10,000× when running multiple parallel agents.

8. Exporting to Other OTLP Backends

The OTEL exporter works with any OTLP‑compatible endpoint. Simply change the endpoint variable:

export OTEL_EXPORTER_OTLP_ENDPOINT=https://your-backend-endpoint

For Datadog, point to their OTLP intake URL; the metric names remain the same.

9. Future Enhancements

  • Alerts when the productivity ratio drops (e.g., you’re stuck).
  • Cost projections based on current burn rate.
  • Comparison panels for different projects or teams.

If you extend this setup, feel free to share your results!

Back to Blog

Related posts

Read more »