crewshipd exposes a Prometheus text-format endpoint at GET /metrics on the
main HTTP port. It serves two groups of series: process gauges (uptime, memory,
goroutines, WebSocket connections) and domain metrics — the counters and gauges
an operator alerts on.
Authorization
/metrics is not public:
- Requests from loopback (the true client IP, X-Forwarded-For aware) are always allowed — the typical node-local Prometheus or sidecar scrape.
- Remote scrapers must send
Authorization: Bearer <token>matching theCREWSHIP_METRICS_TOKENenvironment variable. - With no token configured, non-loopback requests get a
404.
Process metrics
Every series carries a
hostname label.
Domain metrics
Assignments and queue
Queue depth is deliberately aggregated, not labeled per crew — crews are
user-created and unbounded, and per-crew labels would grow the series set
without limit. The three aggregates cover the alerting cases: total backlog
growing, backlog spreading across crews, and a single crew wedged
(
depth_max climbing while depth is flat).
Pipeline runs
Agent runs
Alert on failure rate with the usual counter recipe:
rate() /
increase() treat that as a normal counter reset.
LLM cost (paymaster)
Provider label values are capped (overflow folds into
provider="other") so
the series set stays bounded. Spend-rate alert:
Containers
Database
Freshness and cost
The DB-derived block is computed from indexed counts and cached for 15 seconds — scraping more often than that returns the same snapshot. At typical 15–60s scrape intervals this is invisible; it exists so a scraper retry storm (or an abusive client that got hold of the token) cannot turn/metrics into a query amplifier.
For traces and OTLP export, see OTLP setup.