Skip to content

JuanjoFuchs/claudefana

Repository files navigation

claudefana

Real-time observability for Claude Code. One command gives you a Grafana dashboard tracking costs, tokens, tool usage, cache efficiency, and rate limits — all from the OTEL telemetry Claude Code already emits.

Dashboard Screenshot

Why

Claude Code emits rich OpenTelemetry metrics and logs out of the box — cost per request, token counts by type, tool calls, edit decisions, session activity, and more. But without a backend to collect them, all that data disappears.

claudefana gives you the backend (OTEL Collector + Prometheus + Loki) and a pre-built Grafana dashboard so you can see exactly where your tokens and dollars are going.

Quick Start

1. Enable Claude Code telemetry

Add to your ~/.claude/settings.json:

{
  "env": {
    "CLAUDE_CODE_ENABLE_TELEMETRY": "1",
    "OTEL_METRICS_EXPORTER": "otlp",
    "OTEL_LOGS_EXPORTER": "otlp",
    "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4317"
  }
}

2. Start the stack

git clone https://github.com/JuanjoFuchs/claudefana.git
cd claudefana
docker compose -f docker-compose.otel.yaml up -d

All services use restart: unless-stopped, so they start automatically whenever Docker runs (e.g., on reboot). You only need to run up -d once. To stop the stack permanently, use docker compose -f docker-compose.otel.yaml down.

3. Restart Claude Code

OTEL settings require a full restart of Claude Code to take effect. After restarting, metrics begin flowing within seconds.

4. Open Grafana

http://localhost:3000 — no login required (anonymous access enabled by default).

What You Get

A 26-panel dashboard across 8 sections:

Overview

  • Total Cost — lifetime spend with threshold coloring
  • Sessions / Prompts Sent / Active Time / Commits — key counters at a glance
  • Cost per Prompt / Cost per Session / Cost per Commit — efficiency signals

Cost & Tokens

  • Model Mix (by cost) — donut chart showing spend per model
  • Token Usage by Type — stacked timeseries of input, output, cache read, and cache creation tokens
  • Token Usage by Model — stacked timeseries of total tokens per model
  • Cache Hit Ratio — gauge showing what fraction of tokens come from cache (higher = cheaper)

Activity

  • Tool Usage — ranked bar chart of every tool Claude Code uses (Read, Edit, Bash, etc.)
  • Requests by Model — donut chart of API call distribution
  • API Latency by Model — average request duration per model in milliseconds
  • Tool Call Weight — donut chart showing each tool's share of total invocations

Code & Edits

  • Edits by Language — which languages Claude is modifying
  • Terminal / IDE — where you're running Claude Code
  • Lines of Code — added vs. removed
  • Edit Accept Rate — what percentage of Claude's suggested edits you accepted

Session Activity

  • Sessions Per Day / Active Time Per Day — adoption and investment trends
  • Cost Per Session Trend — $/session over time (declining = getting more efficient)
  • Lines Per Dollar — rising trend = more output per dollar spent
  • User Prompts Over Time — prompt rate over time
  • Lines of Code Over Time — added (green, above zero) vs. removed (red, below zero)

Usage Limits

  • Rate Limit Utilization — gauges for each rolling limit window (5h, 7d all models, 7d Sonnet, 7d Opus, extra monthly). Requires the optional usage exporter (see below).

Event Log

  • Event Stream — live log feed from Loki showing Claude Code events

Architecture

Claude Code ──OTLP──▶ OTEL Collector ──▶ Prometheus ──▶ Grafana
                            │
                            ▼
                          Loki (logs) ──────────────────▶ Grafana
Service Port Purpose
OTEL Collector 4317 (gRPC), 4318 (HTTP) Receives telemetry, converts logs to metrics
Prometheus 9090 Time-series storage
Loki 3100 Log aggregation
Grafana 3000 Dashboard UI

The OTEL Collector does the heavy lifting: it receives raw telemetry from Claude Code and uses two connectors (count and signaltometrics) to convert structured log events into Prometheus metrics — API request counts, tool call counts, per-request cost, token breakdowns, and request duration.

Metrics Reference

Native Claude Code Metrics (emitted directly)

Metric Description
claude_code_cost_usage_USD_total Cumulative cost in USD per session
claude_code_token_usage_tokens_total Tokens by type (input/output/cacheRead/cacheCreation)
claude_code_active_time_seconds_total Active CLI time per session
claude_code_session_count_total Session starts
claude_code_lines_of_code_count_total Lines added/removed
claude_code_code_edit_tool_decision_total Edit accept/reject decisions by tool and language

Derived Metrics (converted from logs by the collector)

Metric Description
claude_code_api_requests_total API request count by model
claude_code_tool_calls_total Tool invocations by tool name
claude_code_user_prompts_total User prompts submitted
claude_code_cost_usd_total Cost extracted from log attributes
claude_code_input_tokens_total Input tokens per request
claude_code_output_tokens_total Output tokens per request
claude_code_cache_read_tokens_total Cache hit tokens
claude_code_cache_creation_tokens_total Cache miss tokens
claude_code_request_duration_ms Request latency

Usage Limits Exporter (Optional)

The included claude-usage-exporter.py scrapes Anthropic's Usage API to power the rate limit gauges. It starts automatically with the stack. If you don't have credentials or don't want limit tracking, the rest of the dashboard works fine without it.

Credentials

The exporter tries three sources in order:

Source When to use
CLAUDE_OAUTH_TOKEN env var macOS Docker users (Keychain can't be accessed from inside a container)
macOS Keychain Running the exporter natively on macOS (auto-detected)
~/.claude/.credentials.json Linux and Windows (default)

Linux / Windows — works out of the box. Claude Code writes credentials to ~/.claude/.credentials.json, which is bind-mounted into the container.

macOS — Claude Code stores credentials in Keychain, not the file. Extract the token and pass it as an env var:

# Extract token from Keychain
export CLAUDE_OAUTH_TOKEN=$(security find-generic-password -s "Claude Code-credentials" -w \
  | python3 -c "import sys,json; print(json.load(sys.stdin)['claudeAiOauth']['accessToken'])")

# Start the stack (or add to your shell profile to persist across reboots)
docker compose -f docker-compose.otel.yaml up -d

Then uncomment the CLAUDE_OAUTH_TOKEN line in docker-compose.otel.yaml.

Note: OAuth tokens expire periodically. If the exporter starts failing (claude_code_usage_scrape_success 0), re-extract the token after re-authenticating Claude Code (/logout then /login).

To customize the credentials file path instead:

CLAUDE_CREDENTIALS_PATH=/path/to/credentials.json docker compose -f docker-compose.otel.yaml up -d

Alert Rules

Built-in Prometheus alerts in prometheus-alerts/:

Alert Fires when
Usage limit warning 5h rolling or 7d limit hits 70%
Usage limit critical 5h rolling or 7d limit hits 85%
Usage limit exhausted 5h rolling limit hits 95%
High burn rate Consuming >20% of limit per hour
Low cache efficiency Cache hit ratio below 50%
No API activity No Claude Code requests for 30+ minutes

Configuration

Grafana

Anonymous access is enabled by default so you don't need to log in. To set a password instead:

# Copy and edit .env
cp .env.example .env
# Set GF_SECURITY_ADMIN_PASSWORD=yourpassword

OTEL Export Interval

Claude Code defaults to a 60-second metric export interval. For more responsive dashboards:

{
  "env": {
    "OTEL_METRIC_EXPORT_INTERVAL": "5000"
  }
}

Known Limitations

  • Thinking tokens are not in OTEL — Claude's internal reasoning can be 3-10x visible output and counts toward rate limits, but is not exported. Feature request: #16943
  • Usage limits only via API — rate limit data requires the optional exporter, not native OTEL. Feature request: #16942
  • No project/repo context — there's no OTEL label indicating which codebase a session is working on
  • Single-user scope — this stack is designed for individual use. For multi-user/org dashboards, see the enterprise section below.

Enterprise / Multi-User

For organization-level dashboards with team breakdowns, department rollups, and productivity correlation:

claudefana-enterprise adds:

  • Microsoft Graph integration — user profiles, department/manager/job title enrichment
  • Jira + Tempo integration — issues resolved, story points, time tracking correlation
  • Org hierarchy tree panel — rollup cost and activity by manager chain
  • 40+ panel dashboard with Organization and Jira correlation rows
  • Kubernetes deployment manifests

Contributing

Contributions welcome! Please open an issue to discuss before submitting large changes.

License

MIT

About

Real-time observability for Claude Code. One command gives you a Grafana dashboard tracking costs, tokens, tool usage, cache efficiency, and rate limits.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages