...
1 package metrics
2
3 import (
4 "time"
5
6 "github.com/prometheus/client_golang/prometheus"
7 ctrl "sigs.k8s.io/controller-runtime"
8
9 "edge-infra.dev/pkg/k8s/runtime/conditions"
10 "edge-infra.dev/pkg/k8s/runtime/controller/metrics"
11 k8smetrics "edge-infra.dev/pkg/k8s/runtime/controller/metrics"
12 "edge-infra.dev/pkg/sds/display/constants"
13 v2 "edge-infra.dev/pkg/sds/display/k8s/apis/v2"
14 )
15
16 const (
17 nodeLabel = "node"
18 enabledLabel = "enabled"
19 configLabel = "config"
20 defaultLabel = "default"
21 statusLabel = "status"
22 )
23
24 var NodeDisplayConfigReadinessMetric prometheus.GaugeVec = *prometheus.NewGaugeVec(
25 prometheus.GaugeOpts{
26 Name: metrics.Name(constants.DisplayctlName, "nodedisplayconfig_readiness"),
27 Help: "Metric to show the NodeDisplayConfig readiness.",
28 },
29 []string{nodeLabel, enabledLabel, configLabel, defaultLabel, statusLabel},
30 )
31
32 var NodeDisplayConfigDurationMetric prometheus.HistogramVec = *prometheus.NewHistogramVec(
33 prometheus.HistogramOpts{
34 Name: metrics.Name(constants.DisplayctlName, "nodedisplayconfig_reconcile_duration_seconds"),
35 Help: "Metric to show the NodeDisplayConfig reconcile duration in seconds.",
36 Buckets: prometheus.LinearBuckets(0.0, 0.2, 10),
37 },
38 []string{nodeLabel},
39 )
40
41 type Metrics struct {
42 Metrics k8smetrics.Metrics
43 reconcileStart time.Time
44 }
45
46 func New(mgr ctrl.Manager, name string) *Metrics {
47 return &Metrics{
48 Metrics: k8smetrics.New(
49 mgr,
50 name,
51 k8smetrics.WithCollectors(
52 NodeDisplayConfigReadinessMetric,
53 NodeDisplayConfigDurationMetric,
54 ),
55 ),
56 }
57 }
58
59 func (m *Metrics) Reconciling() {
60 m.reconcileStart = time.Now()
61 NodeDisplayConfigReadinessMetric.Reset()
62 }
63
64 func (m *Metrics) RecordReconcile(nodeDisplayConfig *v2.NodeDisplayConfig) {
65 if !nodeDisplayConfig.DeletionTimestamp.IsZero() {
66 return
67 }
68
69 m.recordReadiness(nodeDisplayConfig)
70 m.recordReconcileDuration(nodeDisplayConfig)
71 }
72
73 func (m *Metrics) recordReadiness(nodeDisplayConfig *v2.NodeDisplayConfig) {
74 labels := map[string]string{
75 nodeLabel: nodeDisplayConfig.GetName(),
76 statusLabel: "",
77 defaultLabel: "True",
78 enabledLabel: "True",
79 configLabel: "False",
80 }
81
82 if condition := conditions.Get(nodeDisplayConfig, v2.DisplayManagerConfiguredCondition); condition != nil {
83 labels[statusLabel] = condition.Reason
84 }
85 if condition := conditions.Get(nodeDisplayConfig, v2.DefaultCondition); condition != nil {
86 labels[statusLabel] = string(condition.Status)
87 }
88 if condition := conditions.Get(nodeDisplayConfig, v2.DisplayctlEnabledCondition); condition != nil {
89 labels[statusLabel] = string(condition.Status)
90 }
91 if condition := conditions.Get(nodeDisplayConfig, v2.DisplayManagerConfigCondition); condition != nil {
92 labels[statusLabel] = string(condition.Status)
93 }
94
95 if conditions.IsReady(nodeDisplayConfig) {
96 NodeDisplayConfigReadinessMetric.With(labels).Set(1)
97 } else {
98 NodeDisplayConfigReadinessMetric.With(labels).Set(0)
99 }
100 }
101
102 func (m *Metrics) recordReconcileDuration(nodeDisplayConfig *v2.NodeDisplayConfig) {
103 labels := map[string]string{
104 nodeLabel: nodeDisplayConfig.GetName(),
105 }
106
107 seconds := time.Since(m.reconcileStart).Seconds()
108 NodeDisplayConfigDurationMetric.With(labels).Observe(seconds)
109 }
110
View as plain text