feat(telemetry): add Prometheus metrics with feature-gated instrumentation - #35
Merged
Merged
Conversation
Add opt-in Prometheus metrics infrastructure behind a `metrics` cargo feature flag. Defines metric handles (counters, histograms, gauges) for LLM requests, tool calls, memory operations, and active workers via a global registry. Exposes a /metrics endpoint on a configurable port (default 9090) using axum, spawned as a separate tokio task. Metric handles are defined but call-site instrumentation is deferred to a follow-up change. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ograms Wire metric handles into LLM completions (counter + duration histogram), tool execution (counter + duration via hook timer map), memory operations (read/write counters), and worker lifecycle (active_workers gauge inc/dec). All instrumentation is cfg-gated behind the `metrics` feature flag. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
METRICS.md documents every exposed metric with type, labels, instrumentation location, cardinality estimates, and known limitations. examples/prometheus.yml provides a ready-to-use scrape config. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- LLM histogram buckets max at 10s, need upper buckets for 15-60s range - memory_entry_count gauge defined but not wired to any call site - TOOL_CALL_TIMERS can retain orphaned entries on abnormal termination - LLM metrics use hardcoded "unknown" for agent_id and tier labels No implementation changes. Comments only. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…rics # Conflicts: # src/config.rs
l33t0
added a commit
to l33t0/spacebot
that referenced
this pull request
Feb 21, 2026
…and per-agent context Wire the metrics server startup, fix LLM histogram buckets, and resolve all known limitations from spacedriveapp#35: agent_id/tier labels are no longer hardcoded to "unknown", memory_entry_count gauge is instrumented, and six new metrics cover token usage, estimated USD cost, branch/worker lifecycle, process errors, and memory audit trail. - Wire start_metrics_server() call in main.rs - Extend LLM duration buckets to [0.1 … 120s] - Add agent_id + process_type context to SpacebotModel, wired at all 7 call sites - Add spacebot_llm_tokens_total (input/output/cached_input) - Add spacebot_llm_estimated_cost_dollars with static pricing table (src/llm/pricing.rs) - Add spacebot_active_branches gauge - Add spacebot_worker_duration_seconds histogram - Add spacebot_process_errors_total counter with error classification - Add spacebot_memory_updates_total counter (save/delete/forget) - Wire memory_entry_count gauge in MemoryStore save/delete - Add metrics docs page for docs.spacebot.sh - Update METRICS.md and docs/metrics.md with full inventory Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Merged
6 tasks
rktmeister
pushed a commit
to rktmeister/spacebot
that referenced
this pull request
Mar 11, 2026
feat(telemetry): add Prometheus metrics with feature-gated instrumentation
rktmeister
pushed a commit
to rktmeister/spacebot
that referenced
this pull request
Mar 11, 2026
…and per-agent context Wire the metrics server startup, fix LLM histogram buckets, and resolve all known limitations from spacedriveapp#35: agent_id/tier labels are no longer hardcoded to "unknown", memory_entry_count gauge is instrumented, and six new metrics cover token usage, estimated USD cost, branch/worker lifecycle, process errors, and memory audit trail. - Wire start_metrics_server() call in main.rs - Extend LLM duration buckets to [0.1 … 120s] - Add agent_id + process_type context to SpacebotModel, wired at all 7 call sites - Add spacebot_llm_tokens_total (input/output/cached_input) - Add spacebot_llm_estimated_cost_dollars with static pricing table (src/llm/pricing.rs) - Add spacebot_active_branches gauge - Add spacebot_worker_duration_seconds histogram - Add spacebot_process_errors_total counter with error classification - Add spacebot_memory_updates_total counter (save/delete/forget) - Wire memory_entry_count gauge in MemoryStore save/delete - Add metrics docs page for docs.spacebot.sh - Update METRICS.md and docs/metrics.md with full inventory Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
pasogott
pushed a commit
to pasogott/spacebot
that referenced
this pull request
Aug 15, 2026
Task spacedriveapp#35, the linkage autonomy needs before it can run the board. tasks.worker_id names the run executing now and is overwritten by the next spawn, so a task retried three times remembered only the last one, and it is cleared on reassignment rather than archived. worker_runs carries no task reference at all, so nothing could answer "what has already been tried on this task and how did it end" — the question a loop has to answer before spawning. task_worker_runs is that history: append-only, one row per attempt, with the outcome, who asked for it, and which channel it came from. The attempt ordinal is allocated inside the transaction so racing spawns cannot claim the same one, re-recording a worker returns its existing row so a retried bind is idempotent, and terminal state is written once so a duplicated completion cannot rewrite how a run ended. The worker reference carries no foreign key deliberately. Tasks live in the instance database and worker_runs in the per-agent one, so the link crosses a database boundary that SQLite cannot enforce. A run whose worker row was pruned still records that the attempt happened. Spawning refuses a task that already has a live run. The existing delegation check is per-channel, so two channels could previously spawn on the same task without either noticing. The board renders what has been tried inline, in one query for the whole board rather than one per task, naming at most three attempts so a heavily retried task cannot crowd out the rest. GET /tasks/{number}/attempts exposes the same history, and a worker resolves back to its task. Outcomes mirror the worker's own rather than collapsing to success/failure, so partial and blocked stay distinguishable from failed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
metricscargo feature flag with optionalprometheusdependencyLazyLocksingleton/metrics(Prometheus text format) and/healthendpoints via a dedicated axum server on configurable portMetrics
spacebot_llm_requests_totalspacebot_llm_request_duration_secondsspacebot_tool_calls_totalspacebot_tool_call_duration_secondsspacebot_memory_reads_totalspacebot_memory_writes_totalspacebot_active_workersspacebot_memory_entry_countKnown limitations
agent_idandtierlabels on LLM metrics are hardcoded to"unknown"(SpacebotModel lacks process context)memory_entry_countgauge is registered but not instrumentedAll tracked as inline TODO comments and documented in METRICS.md.
Test plan
cargo checkpasses with and without--features metricscargo clippy --features metrics -- -D warningscleancargo test— 43 tests pass in both configurationsmetrics.enabled = true, curllocalhost:9090/metricsreturns valid Prometheus text/healthreturns 200