Metrics Reference¶
All metrics carry the default label app="omp-usage-exporter"; Prometheus adds job and instance.
LLM counters are computed from the SQLite aggregates on every scrape. They are monotonic, survive exporter restarts and never double count re-imported files.
LLM metrics¶
| Metric | Type | Labels | Meaning |
|---|---|---|---|
omp_llm_tokens_total |
counter | provider, model, direction |
Tokens by direction: input, output, cache_read, cache_write |
omp_llm_reasoning_tokens_total |
counter | provider, model |
Reasoning/thinking tokens. Subset of output, never add them to output |
omp_llm_requests_total |
counter | provider, model, status |
Assistant messages: success, error (stopReason=error), aborted |
omp_llm_stop_reasons_total |
counter | provider, model, stop_reason |
Assistant messages by raw stop reason (stop, length, toolUse, error, aborted, unknown, …) |
omp_llm_reported_cost_usd_total |
counter | provider, model |
Cost reported by the provider through OMP, in USD |
omp_llm_usage_missing_total |
counter | provider, model |
Messages without usage (usage: null) |
omp_llm_cost_missing_total |
counter | provider, model |
Messages with usage but without a reported cost |
Accounting rules¶
| Rule | Implementation |
|---|---|
| Reasoning ⊆ output | reasoningTokens is exported separately and never added to output |
No totalTokens double count |
totalTokens is stored but not exported |
| Error is a failed attempt | stopReason="error" → status="error"; tokens reported with an error are still counted |
| Missing ≠ zero | usage: null increments usage_missing, a missing cost increments cost_missing |
| Reported cost ≠ invoice | Free tiers report 0; routers may report estimates |
| Router aliases | openrouter/free is exported as openrouter/free; the underlying model is not guessed |
increase() follows scrapes |
Prometheus attributes increments to scrape time, not to the original event timestamp |
| Importing old JSONL is not a backfill | Old events appear as a step at the time they are first imported |
| OMP vs llama.cpp | Local generations may appear in both; never sum the two |
Label values¶
Label values are exported verbatim: openrouter/free, qwen3.6-35b-a3b:Q4_K_M and llama.cpp are all valid Prometheus label values. Control characters are replaced with _ and values are truncated to 128 characters.
Upgrading from 0.2.x: older versions replaced /, - and . with _ (openrouter/free → openrouter_free). Dashboards or rules matching the old values must be updated. Prometheus treats the new values as new series.
Cardinality limit¶
At most --max-label-cardinality (default 1000) distinct (provider, model) pairs are exported, in first-seen order. Usage of additional pairs is still stored and counted, folded into provider="_other", model="_other". Watch omp_usage_label_overflow_pairs > 0.
Operational metrics¶
| Metric | Type | Labels | Meaning |
|---|---|---|---|
omp_usage_events_imported_total |
counter | Events stored in the database | |
omp_usage_invalid_records_total |
counter | reason |
Skipped lines: invalid_json, invalid_schema, unknown_schema_version, line_too_long, invalid_utf8 (persisted) |
omp_usage_import_errors_total |
counter | reason |
Failed file imports since process start: io, database, other |
omp_usage_file_resets_total |
counter | reason |
Files re-read from offset 0: replaced, truncated, rewritten |
omp_usage_last_import_timestamp_seconds |
gauge | Unix time of the last successful cycle (0 before the first) | |
omp_usage_last_import_success |
gauge | 1 if the last cycle had no file errors | |
omp_usage_last_import_duration_seconds |
gauge | Duration of the last cycle | |
omp_usage_files_tracked |
gauge | Files with a cursor | |
omp_usage_label_cardinality |
gauge | Exported (provider, model) pairs |
|
omp_usage_label_overflow_pairs |
gauge | Pairs folded into _other |
|
omp_usage_build_info |
gauge | version, node_version |
Always 1 |
omp_usage_process_*, omp_usage_nodejs_* |
various | Standard Node.js process metrics |
omp_usage_last_import_timestamp (without _seconds) from 0.2.x was renamed.
Price metrics¶
Exported only with --pricing-file: omp_llm_price_usd_per_million_tokens, omp_llm_reference_price_usd_per_million_tokens, omp_llm_pricing_info and omp_usage_pricing_*. See Pricing & Equivalent Cost.
PromQL examples¶
# Tokens per model over the selected Grafana range
sum by (model) (increase(omp_llm_tokens_total[$__range]))
# Input vs output rate
sum by (direction) (rate(omp_llm_tokens_total[5m]))
# Error ratio per provider
sum by (provider) (rate(omp_llm_requests_total{status="error"}[15m]))
/ sum by (provider) (rate(omp_llm_requests_total[15m]))
# Prompt cache hit ratio
sum(rate(omp_llm_tokens_total{direction="cache_read"}[1h]))
/ sum(rate(omp_llm_tokens_total{direction=~"input|cache_read"}[1h]))
# Reported cost in the last 24 hours
sum(increase(omp_llm_reported_cost_usd_total[24h]))
# Exporter freshness
time() - omp_usage_last_import_timestamp_seconds