Files
openclaw-usage-exporter/README.md
T

149 lines
5.8 KiB
Markdown

# OpenClaw Usage Exporter
FastAPI Prometheus exporter for OpenClaw usage, session, and runtime-adjacent metrics.
## What it exports
Reads OpenClaw session data from disk and exposes `/metrics` with as much non-sensitive data as possible.
### Why timeframe switching looked wrong before
Prometheus scrapes snapshots. The old exporter leaned heavily on "today so far" gauges, so a Grafana timeframe change could look almost unchanged unless the panel query explicitly used range math.
The exporter now also exposes:
- monotonic all-time counters for tokens, cost, and usage entries
- retained daily buckets
- retained hourly buckets
That gives dashboards something real to aggregate over a selected time range.
### Daily usage metrics
- `openclaw_daily_total_tokens`
- `openclaw_daily_input_tokens`
- `openclaw_daily_output_tokens`
- `openclaw_daily_cache_read_tokens`
- `openclaw_daily_cache_write_tokens`
- `openclaw_daily_reasoning_tokens`
- `openclaw_daily_usage_entries`
- `openclaw_daily_cost_input`
- `openclaw_daily_cost_output`
- `openclaw_daily_cost_cache_read`
- `openclaw_daily_cost_cache_write`
- `openclaw_daily_cost_total`
- `openclaw_daily_message_records`
- `openclaw_daily_non_message_records`
- `openclaw_daily_unique_sessions`
- `openclaw_daily_unique_models`
- `openclaw_daily_unique_providers`
### Daily breakdowns
- `openclaw_daily_messages_total{role=...}`
- `openclaw_daily_stop_reasons_total{stop_reason=...,model=...,provider=...}`
- `openclaw_daily_tool_calls_total{tool_name=...}`
- `openclaw_daily_errors_total{error_type=...}`
- `openclaw_daily_model_total_tokens{model=...,provider=...}`
- `openclaw_daily_model_input_tokens{model=...,provider=...}`
- `openclaw_daily_model_output_tokens{model=...,provider=...}`
- `openclaw_daily_model_reasoning_tokens{model=...,provider=...}`
- `openclaw_daily_session_total_tokens{session_id=...}`
- `openclaw_daily_session_input_tokens{session_id=...}`
- `openclaw_daily_session_output_tokens{session_id=...}`
- `openclaw_daily_session_messages_total{session_id=...,role=...}`
- `openclaw_daily_session_errors_total{session_id=...}`
- `openclaw_daily_session_tool_calls_total{session_id=...,tool_name=...}`
### Session inventory metrics
Derived from `sessions.json`:
- `openclaw_sessions_visible_count`
- `openclaw_sessions_total_count`
- `openclaw_sessions_has_more`
- `openclaw_session_info{session_id=...,status=...,chat_type=...,last_channel=...,model=...,provider=...,auth_profile_override=...,system_sent=...,aborted_last_run=...,total_tokens_fresh=...}`
- `openclaw_session_age_seconds{session_id=...}`
- `openclaw_session_updated_timestamp_seconds{session_id=...}`
- `openclaw_session_started_timestamp_seconds{session_id=...}`
- `openclaw_session_last_interaction_timestamp_seconds{session_id=...}`
- `openclaw_session_total_tokens{session_id=...}`
- `openclaw_session_input_tokens{session_id=...}`
- `openclaw_session_output_tokens{session_id=...}`
- `openclaw_session_context_tokens{session_id=...}`
- `openclaw_session_runtime_seconds{session_id=...}`
- `openclaw_session_estimated_cost_usd{session_id=...}`
- `openclaw_session_compaction_count{session_id=...}`
- `openclaw_session_usage_family_session_count{session_id=...}`
### Time-range-friendly counters and buckets
- `openclaw_total_tokens_total`
- `openclaw_input_tokens_total`
- `openclaw_output_tokens_total`
- `openclaw_cache_read_tokens_total`
- `openclaw_cache_write_tokens_total`
- `openclaw_reasoning_tokens_total`
- `openclaw_usage_entries_total`
- `openclaw_cost_input_usd_total`
- `openclaw_cost_output_usd_total`
- `openclaw_cost_cache_read_usd_total`
- `openclaw_cost_cache_write_usd_total`
- `openclaw_cost_total_usd_total`
- `openclaw_message_records_total`
- `openclaw_non_message_records_total`
- `openclaw_model_total_tokens_total{model=...,provider=...}`
- `openclaw_model_input_tokens_total{model=...,provider=...}`
- `openclaw_model_output_tokens_total{model=...,provider=...}`
- `openclaw_session_total_tokens_total{session_id=...}`
- `openclaw_day_total_tokens{date=...,tz=...}`
- `openclaw_day_cost_total{date=...,tz=...}`
- `openclaw_day_usage_entries{date=...,tz=...}`
- `openclaw_hour_total_tokens{hour=...,tz=...}`
- `openclaw_hour_cost_total{hour=...,tz=...}`
- `openclaw_hour_usage_entries{hour=...,tz=...}`
### Exporter/runtime metrics
- `openclaw_exporter_files_scanned`
- `openclaw_exporter_lines_scanned`
- `openclaw_exporter_parse_errors`
- `openclaw_exporter_history_days_retained`
- `openclaw_exporter_history_hours_retained`
- `openclaw_usage_cost_cache_files_tracked`
- `openclaw_usage_cost_cache_version`
- `openclaw_usage_cost_cache_updated_timestamp_seconds`
## Privacy boundary
This exporter intentionally skips obvious revealing fields like message content, sender labels, sender ids, phone numbers, response ids, idempotency keys, and session keys.
Session ids are exported.
## Run locally
```bash
python3 -m venv .venv
. .venv/bin/activate
pip install -r requirements.txt
uvicorn app:app --host 0.0.0.0 --port 9487
```
## Runtime
- Canonical repo path: `/root/projects/openclaw-usage-exporter`
- Compatibility workspace path: `/root/.openclaw/workspace/openclaw-daily-tokens-exporter`
- systemd user unit: `~/.config/systemd/user/openclaw-daily-tokens-exporter.service`
- Direct metrics: `http://100.74.255.106:9487/metrics`
- Tailscale Serve path: `https://luna.taile7522.ts.net/openclaw-daily-tokens`
## Env
- `OPENCLAW_SESSIONS_DIR` default: `/root/.openclaw/agents/main/sessions`
- `OPENCLAW_EXPORTER_TZ` default: `Europe/Berlin`
- `OPENCLAW_SESSIONS_INDEX` default: `/root/.openclaw/agents/main/sessions/sessions.json`
- `OPENCLAW_USAGE_COST_CACHE` default: `/root/.openclaw/agents/main/sessions/.usage-cost-cache.json`
- `OPENCLAW_HISTORY_DAYS` default: `30`
- `OPENCLAW_HISTORY_HOURS` default: `168`
- `PORT` ignored by app directly; set it in the service or uvicorn command