Prometheus metrics
Prometheus scraping
This is the scrape endpoint for Prometheus-compatible monitoring systems. It returns the
Prometheus text exposition format
instead of JSON and intentionally lives at /metrics, outside the versioned /api/v1
routes.
curl --silent http://localhost:9875/metricsEach scrape contains metric declarations (# HELP and # TYPE) followed by the current
samples and their labels. The response uses text exposition version 0.0.4.
An empty response is healthy
Before the game publishes its first world snapshot, this endpoint returns an empty 200 OK
response. That state must not be treated as a failed scrape. Use Prometheus' generated up
metric to monitor whether the endpoint itself is reachable.
Prometheus configuration
When Prometheus runs on the same machine as the game, add this scrape job to
prometheus.yml:
scrape_configs:
- job_name: uptime
scrape_interval: 15s
static_configs:
- targets:
- 127.0.0.1:9875The API only listens locally. If Prometheus runs in Docker, 127.0.0.1 points to the
container—not the host. With Docker Desktop, use host.docker.internal:9875 and make sure the
container is allowed to reach the host service.
First PromQL queries
Use these queries to confirm the scrape and discover the emitted series:
up{job="uptime"}{job="uptime"}The first query is 1 when Prometheus can scrape the game and 0 when the scrape fails. The
second returns every series collected by the uptime job so you can inspect the current metric
names and labels before building dashboards or alerts.
Metric discovery through JSON
The versioned API also exposes machine-readable discovery endpoints:
- Metric catalog — names, types, units, and help text for every declared Prometheus metric.
- Metric paths — all metric paths present in the current registry capture.
- Metric series — decoded samples for one registry path.
Use /metrics for Prometheus scraping. Use the JSON endpoints when building custom tools that
need to browse declarations or inspect a decoded series without parsing the exposition format.
Overview
Deliberately OUTSIDE /api/v1, alongside /health, because that is where
every scraper expects to find it and versioning a scrape target would break
the convention for no benefit.
Returns 200 with an empty body before the first publish rather than 503: a scrape failure raises an alert, and "the game has not started yet" is not an incident.
Code example
curl -X GET "https://example.com/metrics"Response example
Response body
200Prometheus text exposition (version 0.0.4)