Skip to content
Get Prometheus metrics on Runway

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: 9090

The 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: true

Never set this under spec.values in fairway.yaml. That bakes it into the chart’s defaults — and the same chart ships to environments (Self-Managed, Dedicated, Cells) that may not have the ServiceMonitor CRD, 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_greeter

Under Caproni the same chart serves the same endpoint in your local cluster — port-forward 9090 and curl it there.

Related

Last updated on