@@ -19,32 +19,29 @@ package stats
19
19
import (
20
20
"time"
21
21
22
+ "k8s.io/component-base/metrics"
22
23
"k8s.io/klog"
23
24
stats "k8s.io/kubernetes/pkg/kubelet/apis/stats/v1alpha1"
24
-
25
- "github.com/prometheus/client_golang/prometheus"
26
25
)
27
26
28
27
// NodeResourceMetric describes a metric for the node
29
28
type NodeResourceMetric struct {
30
- Name string
31
- Description string
32
- ValueFn func (stats.NodeStats ) (* float64 , time.Time )
29
+ Desc * metrics.Desc
30
+ ValueFn func (stats.NodeStats ) (* float64 , time.Time )
33
31
}
34
32
35
- func (n * NodeResourceMetric ) desc () * prometheus .Desc {
36
- return prometheus . NewDesc ( n . Name , n . Description , [] string {}, nil )
33
+ func (n * NodeResourceMetric ) desc () * metrics .Desc {
34
+ return n . Desc
37
35
}
38
36
39
37
// ContainerResourceMetric describes a metric for containers
40
38
type ContainerResourceMetric struct {
41
- Name string
42
- Description string
43
- ValueFn func (stats.ContainerStats ) (* float64 , time.Time )
39
+ Desc * metrics.Desc
40
+ ValueFn func (stats.ContainerStats ) (* float64 , time.Time )
44
41
}
45
42
46
- func (n * ContainerResourceMetric ) desc () * prometheus .Desc {
47
- return prometheus . NewDesc ( n . Name , n . Description , [] string { "container" , "pod" , "namespace" }, nil )
43
+ func (n * ContainerResourceMetric ) desc () * metrics .Desc {
44
+ return n . Desc
48
45
}
49
46
50
47
// ResourceMetricsConfig specifies which metrics to collect and export
@@ -53,29 +50,34 @@ type ResourceMetricsConfig struct {
53
50
ContainerMetrics []ContainerResourceMetric
54
51
}
55
52
56
- // NewPrometheusResourceMetricCollector returns a prometheus.Collector which exports resource metrics
57
- func NewPrometheusResourceMetricCollector (provider SummaryProvider , config ResourceMetricsConfig ) prometheus. Collector {
53
+ // NewPrometheusResourceMetricCollector returns a metrics.StableCollector which exports resource metrics
54
+ func NewPrometheusResourceMetricCollector (provider SummaryProvider , config ResourceMetricsConfig ) metrics. StableCollector {
58
55
return & resourceMetricCollector {
59
56
provider : provider ,
60
57
config : config ,
61
- errors : prometheus .NewGauge (prometheus.GaugeOpts {
62
- Name : "scrape_error" ,
63
- Help : "1 if there was an error while getting container metrics, 0 otherwise" ,
64
- }),
58
+ errors : metrics .NewDesc ("scrape_error" ,
59
+ "1 if there was an error while getting container metrics, 0 otherwise" ,
60
+ nil ,
61
+ nil ,
62
+ metrics .ALPHA ,
63
+ "" ),
65
64
}
66
65
}
67
66
68
67
type resourceMetricCollector struct {
68
+ metrics.BaseStableCollector
69
+
69
70
provider SummaryProvider
70
71
config ResourceMetricsConfig
71
- errors prometheus. Gauge
72
+ errors * metrics. Desc
72
73
}
73
74
74
- var _ prometheus.Collector = & resourceMetricCollector {}
75
+ var _ metrics.StableCollector = & resourceMetricCollector {}
76
+
77
+ // DescribeWithStability implements metrics.StableCollector
78
+ func (rc * resourceMetricCollector ) DescribeWithStability (ch chan <- * metrics.Desc ) {
79
+ ch <- rc .errors
75
80
76
- // Describe implements prometheus.Collector
77
- func (rc * resourceMetricCollector ) Describe (ch chan <- * prometheus.Desc ) {
78
- rc .errors .Describe (ch )
79
81
for _ , metric := range rc .config .NodeMetrics {
80
82
ch <- metric .desc ()
81
83
}
@@ -84,33 +86,35 @@ func (rc *resourceMetricCollector) Describe(ch chan<- *prometheus.Desc) {
84
86
}
85
87
}
86
88
87
- // Collect implements prometheus.Collector
88
- // Since new containers are frequently created and removed, using the prometheus. Gauge Collector would
89
+ // CollectWithStability implements metrics.StableCollector
90
+ // Since new containers are frequently created and removed, using the Gauge would
89
91
// leak metric collectors for containers or pods that no longer exist. Instead, implement
90
- // prometheus.Collector in a way that only collects metrics for active containers.
91
- func (rc * resourceMetricCollector ) Collect (ch chan <- prometheus.Metric ) {
92
- rc .errors .Set (0 )
93
- defer rc .errors .Collect (ch )
92
+ // custom collector in a way that only collects metrics for active containers.
93
+ func (rc * resourceMetricCollector ) CollectWithStability (ch chan <- metrics.Metric ) {
94
+ var errorCount float64
95
+ defer func () {
96
+ ch <- metrics .NewLazyConstMetric (rc .errors , metrics .GaugeValue , errorCount )
97
+ }()
94
98
summary , err := rc .provider .GetCPUAndMemoryStats ()
95
99
if err != nil {
96
- rc . errors . Set ( 1 )
100
+ errorCount = 1
97
101
klog .Warningf ("Error getting summary for resourceMetric prometheus endpoint: %v" , err )
98
102
return
99
103
}
100
104
101
105
for _ , metric := range rc .config .NodeMetrics {
102
106
if value , timestamp := metric .ValueFn (summary .Node ); value != nil {
103
- ch <- prometheus . NewMetricWithTimestamp (timestamp ,
104
- prometheus . MustNewConstMetric (metric .desc (), prometheus .GaugeValue , * value ))
107
+ ch <- metrics . NewLazyMetricWithTimestamp (timestamp ,
108
+ metrics . NewLazyConstMetric (metric .desc (), metrics .GaugeValue , * value ))
105
109
}
106
110
}
107
111
108
112
for _ , pod := range summary .Pods {
109
113
for _ , container := range pod .Containers {
110
114
for _ , metric := range rc .config .ContainerMetrics {
111
115
if value , timestamp := metric .ValueFn (container ); value != nil {
112
- ch <- prometheus . NewMetricWithTimestamp (timestamp ,
113
- prometheus . MustNewConstMetric (metric .desc (), prometheus .GaugeValue , * value , container .Name , pod .PodRef .Name , pod .PodRef .Namespace ))
116
+ ch <- metrics . NewLazyMetricWithTimestamp (timestamp ,
117
+ metrics . NewLazyConstMetric (metric .desc (), metrics .GaugeValue , * value , container .Name , pod .PodRef .Name , pod .PodRef .Namespace ))
114
118
}
115
119
}
116
120
}
0 commit comments