llm-cost-tracker
Track and report LLM token usage and cost for OpenClaw via OpenRouter.
Quick Start
python3 scripts/collect_usage.py --init # first-time: create DB + backfill
python3 scripts/run_tracker.py # telegram report (default)
python3 scripts/run_tracker.py --output terminal # full terminal report
python3 scripts/run_tracker.py --output debug # per-request debug
Core Design
- Source of truth:
usage.cost.totalfrom OpenRouter — never recomputed from token counts - Data source: OpenClaw session JSONL files (including
.resetfiles from context compaction) - Deduplication: by
openrouter_request_id— safe to re-run backfill anytime - Time windows: 24h rolling (UTC); 7d/30d/90d/365d calendar days (configurable timezone)
Schema: request_facts
| Column | Source |
|---|---|
| openrouter_request_id | responseId (unique key) |
| created_at_utc | entry timestamp |
| model | model ID |
| prompt_tokens | usage.input |
| completion_tokens | usage.output |
| cached_tokens | usage.cacheRead |
| cache_write_tokens | usage.cacheWrite |
| reasoning_tokens | usage.reasoning |
| total_tokens | usage.totalTokens |
| billed_cost | usage.cost.total (canonical) |
Configuration
config/env.json (all fields optional):
{
"SESSIONS_DIR": "",
"TIMEZONE": "Asia/Hong_Kong",
"UTC_OFFSET_HOURS": 8
}
SESSIONS_DIR: override session file location (empty = auto-detect)TIMEZONE/UTC_OFFSET_HOURS: for calendar-day window calculations- API key: auto-detected from
~/.openclaw/agents/main/agent/auth-profiles.jsonorOPENROUTER_API_KEYenv var
Scheduled Reports
openclaw cron add --name "llm-cost:collect" --message "collect usage data" \
--cron "5 0 * * *" --tz "Asia/Hong_Kong" --session isolated --no-deliver
openclaw cron add --name "llm-cost:daily" --message "llm cost" \
--cron "0 9 * * *" --tz "Asia/Hong_Kong" --session isolated