Get Prometheus metrics on Runway
Metrics on Runway take one line of manifest and one deploy-time switch. LabKit
v2 serves the endpoint, Fairway generates the scrape wiring, and the cluster’s
collector ships everything to Mimir under the runway tenant — where Grafana,
dashboards, and SLO alerting already know how to find it.
1. What your service already does
app.New(ctx) creates a Metrics instance (available as a.Metrics()) with
an isolated Prometheus registry, and the scaffold’s composition root hands it
to the HTTP server:
srv := httpserver.NewWithConfig(&httpserver.Config{
Addr: ":8080",
Logger: a.Logger(),
Tracer: a.Tracer(),
Metrics: a.Metrics(), // serves /-/metrics on the probe port
})That serves /-/metrics on the dedicated probe port :9090 — next to
/-/liveness and /-/readiness, and away from application traffic. Go
runtime and process metrics (go_*, process_*) are registered for free.
2. Register your own metrics
Use the same instance for domain metrics, with BuildName keeping names on
the fleet-wide gitlab_<subsystem>_<name> convention:
m := a.Metrics()
greetings := prometheus.NewCounterVec(prometheus.CounterOpts{
Name: m.BuildName("greeter", "greetings_total"), // gitlab_greeter_greetings_total
Help: "Greetings served, by outcome.",
}, []string{"status"})
m.MustRegister(greetings)
// in the handler:
greetings.WithLabelValues("ok").Inc()For histograms, start from metrics.DurationBuckets — its bounds are aligned
with the SLO thresholds the alerting stack uses.
3. Declare the endpoint in your Fairway manifest
# .runway/fairway.yaml
spec:
metrics:
- port: 9090The path defaults to /-/metrics, so a LabKit v2 service only names the
port. The generated chart now exposes the port on the pod, renders a
metrics Service, and includes a ServiceMonitor template that is off by
default.
4. Enable scraping per deployment
Flip the switch in your Runway deployment values:
# .runway/values.yaml
metrics:
prometheus:
serviceMonitor:
enabled: trueNever set this under
spec.valuesinfairway.yaml. That bakes it into the chart’s defaults — and the same chart ships to environments (Self-Managed, Dedicated, Cells) that may not have theServiceMonitorCRD, where the install would then fail. Enablement belongs to each deployment.
No extra labels are needed: the cluster’s collector discovers every
ServiceMonitor automatically. From the next deploy, your metrics flow to
Mimir.
5. Query your metrics
In
Grafana, pick the
Mimir - Runway datasource. Your namespace equals your Runway service
ID, so:
sum by (status) (
rate(gitlab_greeter_greetings_total{env="production", k8s_namespace_name="<runway_service_id>"}[5m])
)Every scraped series also carries cloud_provider, cloud_runtime,
cloud_region, and k8s_cluster_name for slicing across regions and
runtimes.
6. Dashboards, SLOs, and alerts
Raw metrics in Mimir are the input; the
runbooks metrics catalog turns them
into an overview dashboard, SLO recording rules, and alert routing. Register
your service there with the runway-k8s-archetype — the
Runway observability reference
walks through the setup.
7. Verify locally first (optional)
The endpoint needs no platform to exist:
go run ./cmd/server &
curl -s http://localhost:9090/-/metrics | grep gitlab_greeterUnder
Caproni the same chart serves the same
endpoint in your local cluster — port-forward 9090 and curl it there.
Related
- Get Started — scaffold a service with all of this wired in
- LabKit — the library layer, including
v2/metricsandv2/httpserver - Fairway manifest schema —
spec.metricsin context - Runway observability reference — the platform-side reference: label tables, alerting, runbooks setup