Skip to content

Latest commit

 

History

History
100 lines (72 loc) · 2.8 KB

File metadata and controls

100 lines (72 loc) · 2.8 KB

cc-o11y-stack

A local observability stack for Claude Code.

Architecture

Architecture

Subscription usage limit collection (via statusline)

Subscription (Pro/Max) usage limits are not included in OTel telemetry, so they are collected through the statusline.
The JSON that Claude Code passes to the statusline script's stdin officially contains rate_limits (used_percentage and resets_at for the five_hour / seven_day windows). scripts/statusline.sh extracts these values and pushes them to the VictoriaMetrics push API (/api/v1/import/prometheus) as:

  • claude_code_rate_limit_used_percent{window=...}
  • claude_code_rate_limit_resets_at_timestamp_seconds{window=...}

Required tools

  • Docker (Compose v2)
  • jq — used by make setting and scripts/statusline.sh
  • aqua — manages yq / shellcheck / shfmt / actionlint used by make check (install with aqua i -l; only needed for that target)

Setup

1. Configure Claude Code telemetry

make setting

This merges the following into the env of ~/.claude/settings.json (the existing file is backed up to .bak first):

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

2. (Optional) Register the statusline for usage limit collection

Add to ~/.claude/settings.json, piping into your own display script:

{
  "statusLine": {
    "type": "command",
    "command": "/path/to/cc-o11y-stack/scripts/statusline.sh | ~/.claude/my-statusline.sh",
    "refreshInterval": 60
  }
}

Do not register statusline.sh alone — it passes the raw JSON through to stdout, so without a display script the JSON itself would show up in the statusline.

Running the stack

# Start all services
make up

# Open the dashboards ("Claude Code" and "Docker Compose Services" are auto-provisioned)
open http://localhost:3000

Use Claude Code as usual — metrics are exported every 60 seconds and logs every 5 seconds by default.

# Follow logs (narrow with SERVICE=<name>)
make logs

# Stop (data is kept in named volumes)
make down

# Stop and delete all data
make clean

Validating configuration

make check

Validates every config file and fails if any formatter would produce a diff:

  • compose.yamldocker compose config
  • All YAML / JSON files — syntax check with yq / jq
  • alloy/config.alloyalloy fmt --test and alloy validate
  • otel-collector/config.yamlotelcol validate
  • loki/config.yamlloki -verify-config
  • scripts/*.shshellcheck and shfmt -d