Token Usage Tracker
GitHubA local observability tool tracking LLM API spend across Claude Code, Gemini/Antigravity, and custom scripts, with a live dashboard and zero external dependencies.
By the numbers
- 0
- external dependencies
- ~5s
- capture latency
- 3
- telemetry sources
- 4
- independent processes
- 1.2k
- lines of source
- 3
- token buckets priced
Architecture
Four processes, one append-only file, no broker between them.
Overview
Token Usage Tracker answers a question that is surprisingly hard to answer otherwise: where did the tokens go? It captures spend in real time across Claude Code, Gemini via Antigravity, and any custom script, using nothing but the Python standard library.
Claude Code usage arrives by push rather than poll. A local OTLP/HTTP receiver ingests the editor's native OpenTelemetry export, logging every prompt within about five seconds with no polling loop and no transcript scraping. The receiver always answers 200, deliberately, because an OTLP exporter treats a non-2xx as failure and starts backing off, and a telemetry sink should never apply backpressure to the workload it is measuring.
Gemini usage is harder, and estimating it from character counts is guesswork dressed as data. Instead the tracker discovers Antigravity's local language server by scanning for its process and CSRF token, confirms the pairing with a heartbeat RPC, and pulls exact per-call backend usage: what was actually billed, deduplicated by response ID so a restart never double-counts. Anything else can report through a generic adapter that duck-types Anthropic, OpenAI, and Gemini response shapes and degrades to zeros rather than raising, because a meter must never break the thing it measures.
Cache accounting is where naive trackers go wrong. With prompt caching, a 30,000 token request can be 29,562 tokens of cache reads, billed at roughly a tenth of the fresh input rate. Cache reads and cache writes are kept separate from fresh input on every record, so the difference between a nine-cent estimate and a 1.3-cent reality is visible rather than averaged away.
Everything lands in one append-only JSON-lines file, which is the entire integration contract between four independent processes. A second standard-library server aggregates it into per-model totals, an hourly timeline, and sessions inferred from ten-minute gaps in activity, then serves a single-page vanilla JS dashboard with no build step, no framework, and no bundler.
Why It Matters
LLM spend is opaque and easy to overshoot, especially across several tools and providers with different pricing models and different caching rules. By the time a bill arrives, the sessions that caused it are weeks in the past.
Local telemetry gives immediate visibility into cost per session and per model without shipping prompt contents to a third-party service, which is the trade most observability vendors ask you to make silently.
It is also a demonstration that good observability does not require a heavyweight stack. A push receiver, a cost model that respects caching, an append-only log, and a parser that degrades instead of raising add up to trustworthy visibility in about 1,200 lines with nothing installed.
Stack
Python 3.10+ · stdlib HTTP servers · OTLP/JSON · local RPC · vanilla JS · zero dependencies