feat(metrics): Prometheus collectors and /metrics handler

This commit is contained in:
2026-05-22 12:59:53 +02:00
parent 2be2fdf325
commit 952189eb09
3 changed files with 117 additions and 3 deletions
+69
View File
@@ -0,0 +1,69 @@
// Package metrics defines and registers the Prometheus collectors
// exported on /metrics.
package metrics
import (
"net/http"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
// Metrics bundles all collectors. Each field is the public handle the
// rest of the service uses to record observations.
type Metrics struct {
BuildInfo *prometheus.GaugeVec
HTTPRequests *prometheus.CounterVec
UpdateJobs *prometheus.CounterVec
UpdateDuration *prometheus.HistogramVec
QueueDepth prometheus.Gauge
LastUpdateTime *prometheus.GaugeVec
DockerPingUp prometheus.Gauge
}
// New constructs Metrics and registers them with the given registry.
// Use prometheus.NewRegistry() in tests so collectors don't leak between
// runs; production code uses prometheus.DefaultRegisterer.
func New(reg prometheus.Registerer) *Metrics {
m := &Metrics{
BuildInfo: prometheus.NewGaugeVec(prometheus.GaugeOpts{
Name: "package_updater_build_info",
Help: "Always 1. Labels carry version/commit for dashboards.",
}, []string{"version", "commit"}),
HTTPRequests: prometheus.NewCounterVec(prometheus.CounterOpts{
Name: "package_updater_http_requests_total",
Help: "HTTP requests handled, labelled by endpoint and status.",
}, []string{"endpoint", "status_code"}),
UpdateJobs: prometheus.NewCounterVec(prometheus.CounterOpts{
Name: "package_updater_update_jobs_total",
Help: "Update jobs executed, labelled by project/service/status.",
}, []string{"project", "service", "status"}),
UpdateDuration: prometheus.NewHistogramVec(prometheus.HistogramOpts{
Name: "package_updater_update_duration_seconds",
Help: "Time taken to pull + up a single service.",
Buckets: []float64{0.5, 1, 2, 5, 10, 30, 60, 120, 300},
}, []string{"project", "service"}),
QueueDepth: prometheus.NewGauge(prometheus.GaugeOpts{
Name: "package_updater_queue_depth",
Help: "Current number of submissions waiting in the queue.",
}),
LastUpdateTime: prometheus.NewGaugeVec(prometheus.GaugeOpts{
Name: "package_updater_last_update_timestamp",
Help: "Unix timestamp of the most recent successful update per service.",
}, []string{"project", "service"}),
DockerPingUp: prometheus.NewGauge(prometheus.GaugeOpts{
Name: "package_updater_docker_ping_up",
Help: "1 if the Docker socket responded to ping, 0 otherwise.",
}),
}
reg.MustRegister(
m.BuildInfo, m.HTTPRequests, m.UpdateJobs, m.UpdateDuration,
m.QueueDepth, m.LastUpdateTime, m.DockerPingUp,
)
return m
}
// Handler returns the /metrics HTTP handler bound to the given registry.
func Handler(gatherer prometheus.Gatherer) http.Handler {
return promhttp.HandlerFor(gatherer, promhttp.HandlerOpts{})
}