package metrics import ( "time" "github.com/prometheus/client_golang/prometheus" ctrl "sigs.k8s.io/controller-runtime" "edge-infra.dev/pkg/k8s/runtime/conditions" "edge-infra.dev/pkg/k8s/runtime/controller/metrics" k8smetrics "edge-infra.dev/pkg/k8s/runtime/controller/metrics" "edge-infra.dev/pkg/sds/display/constants" v2 "edge-infra.dev/pkg/sds/display/k8s/apis/v2" ) const ( nodeLabel = "node" enabledLabel = "enabled" configLabel = "config" defaultLabel = "default" statusLabel = "status" ) var NodeDisplayConfigReadinessMetric prometheus.GaugeVec = *prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: metrics.Name(constants.DisplayctlName, "nodedisplayconfig_readiness"), Help: "Metric to show the NodeDisplayConfig readiness.", }, []string{nodeLabel, enabledLabel, configLabel, defaultLabel, statusLabel}, ) var NodeDisplayConfigDurationMetric prometheus.HistogramVec = *prometheus.NewHistogramVec( prometheus.HistogramOpts{ Name: metrics.Name(constants.DisplayctlName, "nodedisplayconfig_reconcile_duration_seconds"), Help: "Metric to show the NodeDisplayConfig reconcile duration in seconds.", Buckets: prometheus.LinearBuckets(0.0, 0.2, 10), }, []string{nodeLabel}, ) type Metrics struct { Metrics k8smetrics.Metrics reconcileStart time.Time } func New(mgr ctrl.Manager, name string) *Metrics { return &Metrics{ Metrics: k8smetrics.New( mgr, name, k8smetrics.WithCollectors( NodeDisplayConfigReadinessMetric, NodeDisplayConfigDurationMetric, ), ), } } func (m *Metrics) Reconciling() { m.reconcileStart = time.Now() NodeDisplayConfigReadinessMetric.Reset() } func (m *Metrics) RecordReconcile(nodeDisplayConfig *v2.NodeDisplayConfig) { if !nodeDisplayConfig.DeletionTimestamp.IsZero() { return } m.recordReadiness(nodeDisplayConfig) m.recordReconcileDuration(nodeDisplayConfig) } func (m *Metrics) recordReadiness(nodeDisplayConfig *v2.NodeDisplayConfig) { labels := map[string]string{ nodeLabel: nodeDisplayConfig.GetName(), statusLabel: "", defaultLabel: "True", enabledLabel: "True", configLabel: "False", } if condition := conditions.Get(nodeDisplayConfig, v2.DisplayManagerConfiguredCondition); condition != nil { labels[statusLabel] = condition.Reason } if condition := conditions.Get(nodeDisplayConfig, v2.DefaultCondition); condition != nil { labels[statusLabel] = string(condition.Status) } if condition := conditions.Get(nodeDisplayConfig, v2.DisplayctlEnabledCondition); condition != nil { labels[statusLabel] = string(condition.Status) } if condition := conditions.Get(nodeDisplayConfig, v2.DisplayManagerConfigCondition); condition != nil { labels[statusLabel] = string(condition.Status) } if conditions.IsReady(nodeDisplayConfig) { NodeDisplayConfigReadinessMetric.With(labels).Set(1) } else { NodeDisplayConfigReadinessMetric.With(labels).Set(0) } } func (m *Metrics) recordReconcileDuration(nodeDisplayConfig *v2.NodeDisplayConfig) { labels := map[string]string{ nodeLabel: nodeDisplayConfig.GetName(), } seconds := time.Since(m.reconcileStart).Seconds() NodeDisplayConfigDurationMetric.With(labels).Observe(seconds) }