Skip to content

feat(pds): Prometheus metrics + structured logging for rsky-pds - #249

Open
afbase wants to merge 1 commit into
mainfrom
worktree-agent-a0df98d4c1f7c0d57
Open

feat(pds): Prometheus metrics + structured logging for rsky-pds#249
afbase wants to merge 1 commit into
mainfrom
worktree-agent-a0df98d4c1f7c0d57

Conversation

@afbase

@afbase afbase commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • rsky-pds was the only service in its own workspace with no telemetry: a bare FmtSubscriber::new(), no /metrics endpoint, nothing to scrape.
  • Adds Prometheus metrics via the metrics + metrics-exporter-prometheus crates, reusing exactly the pattern rsky-relay already established in this workspace (no new/third metrics facade introduced).
  • New counters/gauges: pds_xrpc_requests_total{method,status}, pds_xrpc_request_duration_seconds{method,status}, pds_auth_login_total{outcome}, pds_auth_service_tokens_issued_total, pds_repo_writes_total{op}, pds_blob_uploads_total / pds_blob_upload_bytes_total, pds_firehose_subscribers (gauge, RAII-guarded across every exit path).
  • Replaces the bare tracing subscriber with a layered tracing_subscriber::registry() + EnvFilter.
  • Cross-checked against cocoon (Go, prometheus/client_golang) and tranquil-pds, which independently already uses the identical metrics + metrics-exporter-prometheus combination — validating this as the right shared convention for the workspace.

Test plan

  • cargo build -p rsky-pds
  • cargo test -p rsky-pds — 310 lib tests + integration suites incl. new tests/metrics_tests.rs (real Rocket instance, checks /metrics output and label correctness), all passing
  • cargo fmt -p rsky-pds / cargo clippy -p rsky-pds --all-targets clean
  • Confirmed rsky-relay's one flaky, pre-existing test is unrelated (git diff --stat -- rsky-relay/ shows zero changes there)

🤖 Generated with Claude Code

rsky-pds previously had no telemetry: main.rs used a bare
FmtSubscriber::new() with no EnvFilter, and there was no /metrics
endpoint. This brings it to parity with rsky-relay's existing
metrics/logging pattern in the same workspace, standardizing on the
`metrics` + `metrics-exporter-prometheus` facade (rsky-wintermute and
rsky-video use the `prometheus` crate directly; we don't add a third
facade to the workspace).

- src/metrics.rs: idempotent describe()/install_recorder() (OnceLock-
  guarded, so repeated build_rocket() calls in tests share one
  recorder), a Rocket XrpcMetrics fairing that records XRPC request
  count + latency labelled by lexicon method and HTTP status, plus
  record_* helpers for auth (login success/failure, service-auth
  token issuance), repo write throughput (create/update/delete),
  blob upload count/bytes, and a firehose subscriber gauge tracked via
  an RAII guard so every subscribeRepos exit path decrements it.
- GET /metrics renders the Prometheus exposition text through a normal
  Rocket route (rsky-relay binds a second TCP listener via
  with_http_listener; Rocket already owns a listener here).
- main.rs: tracing_subscriber::registry() + EnvFilter + fmt layer,
  replacing the bare FmtSubscriber (matches rsky-relay's layered
  registry shape).
- Instrumented create_session, get_service_auth, upload_blob,
  create_record/put_record/delete_record/apply_writes, and
  subscribe_repos with the corresponding record_* calls.
- Cargo.toml: added metrics = "0.24" and metrics-exporter-prometheus
  "0.17" (default-features off), matching rsky-relay's/tranquil-pds's
  already-resolved versions; tracing-subscriber gained the
  "env-filter" feature.
- Tests: unit tests in metrics.rs (idempotent describe/install,
  per-metric increment/observe assertions) plus tests/metrics_tests.rs
  exercising a real Rocket instance (GET /metrics returns valid
  Prometheus text; a real XRPC request and a failed login show up
  with the right method/status/outcome labels).

Out of scope: OpenTelemetry/distributed tracing (tracing-opentelemetry
over existing spans) -- left as a follow-on, per task instructions.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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