package metrics import ( "github.com/prometheus/client_golang/prometheus" ) // BuildCollector holds all Prometheus metrics for the builder. type BuildCollector struct { buildsTotal *prometheus.CounterVec buildHostTotal *prometheus.CounterVec buildDuration *prometheus.HistogramVec buildLastTimestamp *prometheus.GaugeVec buildLastSuccessTime *prometheus.GaugeVec buildLastFailureTime *prometheus.GaugeVec } // NewBuildCollector creates a new build metrics collector and registers it with the given registerer. func NewBuildCollector(reg prometheus.Registerer) *BuildCollector { c := &BuildCollector{ buildsTotal: prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "homelab_deploy_builds_total", Help: "Total builds processed", }, []string{"repo", "status"}, ), buildHostTotal: prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "homelab_deploy_build_host_total", Help: "Total host builds processed", }, []string{"repo", "host", "status"}, ), buildDuration: prometheus.NewHistogramVec( prometheus.HistogramOpts{ Name: "homelab_deploy_build_duration_seconds", Help: "Build execution time per host", Buckets: []float64{5, 10, 30, 60, 120, 300, 600, 1800, 3600, 7200, 14400}, }, []string{"repo", "host"}, ), buildLastTimestamp: prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "homelab_deploy_build_last_timestamp", Help: "Timestamp of last build attempt", }, []string{"repo"}, ), buildLastSuccessTime: prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "homelab_deploy_build_last_success_timestamp", Help: "Timestamp of last successful build", }, []string{"repo"}, ), buildLastFailureTime: prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "homelab_deploy_build_last_failure_timestamp", Help: "Timestamp of last failed build", }, []string{"repo"}, ), } reg.MustRegister(c.buildsTotal) reg.MustRegister(c.buildHostTotal) reg.MustRegister(c.buildDuration) reg.MustRegister(c.buildLastTimestamp) reg.MustRegister(c.buildLastSuccessTime) reg.MustRegister(c.buildLastFailureTime) return c } // RecordBuildSuccess records a successful build. func (c *BuildCollector) RecordBuildSuccess(repo string) { c.buildsTotal.WithLabelValues(repo, "success").Inc() c.buildLastTimestamp.WithLabelValues(repo).SetToCurrentTime() c.buildLastSuccessTime.WithLabelValues(repo).SetToCurrentTime() } // RecordBuildFailure records a failed build. func (c *BuildCollector) RecordBuildFailure(repo, errorCode string) { c.buildsTotal.WithLabelValues(repo, "failure").Inc() c.buildLastTimestamp.WithLabelValues(repo).SetToCurrentTime() c.buildLastFailureTime.WithLabelValues(repo).SetToCurrentTime() } // RecordHostBuildSuccess records a successful host build. func (c *BuildCollector) RecordHostBuildSuccess(repo, host string, durationSeconds float64) { c.buildHostTotal.WithLabelValues(repo, host, "success").Inc() c.buildDuration.WithLabelValues(repo, host).Observe(durationSeconds) } // RecordHostBuildFailure records a failed host build. func (c *BuildCollector) RecordHostBuildFailure(repo, host string, durationSeconds float64) { c.buildHostTotal.WithLabelValues(repo, host, "failure").Inc() c.buildDuration.WithLabelValues(repo, host).Observe(durationSeconds) }