Skip to content

feat: telemetry surface (/status extras, /metrics, /usage)#1

Merged
leonardocardoso merged 2 commits into
mainfrom
feat/telemetry
Jun 19, 2026
Merged

feat: telemetry surface (/status extras, /metrics, /usage)#1
leonardocardoso merged 2 commits into
mainfrom
feat/telemetry

Conversation

@leonardocardoso

Copy link
Copy Markdown
Member

What

Adds the in-process telemetry surface that makes "RigPilot + Jano" strictly richer than "RigPilot + plain Ollama." Because Jano sits above the backends and owns every request, response, and swap, it can expose telemetry no single backend (Ollama, llama-server, mlx-lm.server) can produce on its own.

All of it is bounded ring buffers and counters in code paths that already exist. Existing /health and /status callers keep working.

Extended GET /status

Queue/concurrency (inFlight, oldestWaitingMs), swap economics (currentModelLoadedAt, lastSwapDurationMs, swapsLast15m/Hour), rolling throughput across all callers (recentGenTokS, recentPromptTokS, tokSByModel), cumulative counters (requestsServedTotal, tokensGeneratedTotal, both per-model, requestsPerMinute, uptimeSeconds), and error/health signal (errorsLast15m, lastError, backendHealth).

New GET /metrics

Prometheus text exposition: counters, queue gauges, swap-duration histogram + per-transition cost table, backend-up gauges.

New GET /usage?limit=N

Ring of recent per-request records {ts, model, status, total_ms, ttfb_ms, prompt_tokens, gen_tokens, gen_tok_s, prompt_tok_s}. Size via USAGE_RECORDS_MAX (default 500).

How

  • telemetry.ts — bounded aggregator, clock-injectable (like FailureBudget)
  • responseStats.ts — normalizes OpenAI usage, llama.cpp timings, and Ollama nanosecond fields to tok/s
  • bodyTap.ts — captures just enough of a forwarded body to read stats without buffering the stream
  • metrics.ts — the live singleton; dispatcher records swaps/errors/in-flight, HTTP layer records per-request token/timing

Out of scope

Hardware metrics (GPU temp/util/fan, system RAM/CPU/power) and a relay heartbeat stay the sidecar's job.

Tests

35 new tests (86 total); all four CI gates pass (format, lint, typecheck, test).

Expose the router-only telemetry no single backend can produce: queue
backlog, swap economics, rolling throughput, cumulative counters, a
recent-request log, and error/health signal. Jano already sees every
request/response and invokes every swap, so this is mostly counters and
small ring buffers in existing code paths.

- extend GET /status with inFlight, oldestWaitingMs, currentModelLoadedAt,
  lastSwapDurationMs, swaps{15m,Hour}, recent{Gen,Prompt}TokS, tokSByModel,
  uptime, cumulative counters, requestsPerMinute, errors, backendHealth
- add GET /metrics (Prometheus: counters, queue gauges, swap-duration
  histogram + per-transition cost table, backend health)
- add GET /usage?limit=N (recent per-request token/timing records)
- telemetry.ts: bounded ring buffers + counters, clock-injectable
- responseStats.ts: normalize OpenAI usage / llama.cpp timings / Ollama
  nanosecond fields to tok/s; bodyTap.ts captures stats without buffering
- USAGE_RECORDS_MAX env (default 500)

Hardware metrics and relay heartbeat stay out of scope (sidecar's job).
35 new tests.
@leonardocardoso leonardocardoso merged commit 677613f into main Jun 19, 2026
1 check passed
@leonardocardoso leonardocardoso deleted the feat/telemetry branch June 19, 2026 21:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant