prometheus
206 строк · 7.0 Кб
1// Copyright 2018 The Prometheus Authors
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14package discovery
15
16import (
17"context"
18"fmt"
19"net/url"
20"time"
21
22"github.com/prometheus/client_golang/prometheus"
23"k8s.io/client-go/tools/metrics"
24"k8s.io/client-go/util/workqueue"
25)
26
27// This file registers metrics used by the Kubernetes Go client (k8s.io/client-go).
28// Unfortunately, k8s.io/client-go metrics are global.
29// If we instantiate multiple k8s SD instances, their k8s/client-go metrics will overlap.
30// To prevent us from displaying misleading metrics, we register k8s.io/client-go metrics
31// outside of the Kubernetes SD.
32
33const (
34KubernetesMetricsNamespace = "prometheus_sd_kubernetes"
35workqueueMetricsNamespace = KubernetesMetricsNamespace + "_workqueue"
36)
37
38var (
39clientGoRequestMetrics = &clientGoRequestMetricAdapter{}
40clientGoWorkloadMetrics = &clientGoWorkqueueMetricsProvider{}
41)
42
43var (
44// Metrics for client-go's HTTP requests.
45clientGoRequestResultMetricVec = prometheus.NewCounterVec(
46prometheus.CounterOpts{
47Namespace: KubernetesMetricsNamespace,
48Name: "http_request_total",
49Help: "Total number of HTTP requests to the Kubernetes API by status code.",
50},
51[]string{"status_code"},
52)
53clientGoRequestLatencyMetricVec = prometheus.NewSummaryVec(
54prometheus.SummaryOpts{
55Namespace: KubernetesMetricsNamespace,
56Name: "http_request_duration_seconds",
57Help: "Summary of latencies for HTTP requests to the Kubernetes API by endpoint.",
58Objectives: map[float64]float64{},
59},
60[]string{"endpoint"},
61)
62
63// Definition of metrics for client-go workflow metrics provider.
64clientGoWorkqueueDepthMetricVec = prometheus.NewGaugeVec(
65prometheus.GaugeOpts{
66Namespace: workqueueMetricsNamespace,
67Name: "depth",
68Help: "Current depth of the work queue.",
69},
70[]string{"queue_name"},
71)
72clientGoWorkqueueAddsMetricVec = prometheus.NewCounterVec(
73prometheus.CounterOpts{
74Namespace: workqueueMetricsNamespace,
75Name: "items_total",
76Help: "Total number of items added to the work queue.",
77},
78[]string{"queue_name"},
79)
80clientGoWorkqueueLatencyMetricVec = prometheus.NewSummaryVec(
81prometheus.SummaryOpts{
82Namespace: workqueueMetricsNamespace,
83Name: "latency_seconds",
84Help: "How long an item stays in the work queue.",
85Objectives: map[float64]float64{},
86},
87[]string{"queue_name"},
88)
89clientGoWorkqueueUnfinishedWorkSecondsMetricVec = prometheus.NewGaugeVec(
90prometheus.GaugeOpts{
91Namespace: workqueueMetricsNamespace,
92Name: "unfinished_work_seconds",
93Help: "How long an item has remained unfinished in the work queue.",
94},
95[]string{"queue_name"},
96)
97clientGoWorkqueueLongestRunningProcessorMetricVec = prometheus.NewGaugeVec(
98prometheus.GaugeOpts{
99Namespace: workqueueMetricsNamespace,
100Name: "longest_running_processor_seconds",
101Help: "Duration of the longest running processor in the work queue.",
102},
103[]string{"queue_name"},
104)
105clientGoWorkqueueWorkDurationMetricVec = prometheus.NewSummaryVec(
106prometheus.SummaryOpts{
107Namespace: workqueueMetricsNamespace,
108Name: "work_duration_seconds",
109Help: "How long processing an item from the work queue takes.",
110Objectives: map[float64]float64{},
111},
112[]string{"queue_name"},
113)
114)
115
116// Definition of dummy metric used as a placeholder if we don't want to observe some data.
117type noopMetric struct{}
118
119func (noopMetric) Inc() {}
120func (noopMetric) Dec() {}
121func (noopMetric) Observe(float64) {}
122func (noopMetric) Set(float64) {}
123
124// Definition of client-go metrics adapters for HTTP requests observation.
125type clientGoRequestMetricAdapter struct{}
126
127// Returns all of the Prometheus metrics derived from k8s.io/client-go.
128// This may be used tu register and unregister the metrics.
129func clientGoMetrics() []prometheus.Collector {
130return []prometheus.Collector{
131clientGoRequestResultMetricVec,
132clientGoRequestLatencyMetricVec,
133clientGoWorkqueueDepthMetricVec,
134clientGoWorkqueueAddsMetricVec,
135clientGoWorkqueueLatencyMetricVec,
136clientGoWorkqueueUnfinishedWorkSecondsMetricVec,
137clientGoWorkqueueLongestRunningProcessorMetricVec,
138clientGoWorkqueueWorkDurationMetricVec,
139}
140}
141
142func RegisterK8sClientMetricsWithPrometheus(registerer prometheus.Registerer) error {
143clientGoRequestMetrics.RegisterWithK8sGoClient()
144clientGoWorkloadMetrics.RegisterWithK8sGoClient()
145
146for _, collector := range clientGoMetrics() {
147err := registerer.Register(collector)
148if err != nil {
149return fmt.Errorf("failed to register Kubernetes Go Client metrics: %w", err)
150}
151}
152return nil
153}
154
155func (f *clientGoRequestMetricAdapter) RegisterWithK8sGoClient() {
156metrics.Register(
157metrics.RegisterOpts{
158RequestLatency: f,
159RequestResult: f,
160},
161)
162}
163
164func (clientGoRequestMetricAdapter) Increment(_ context.Context, code, _, _ string) {
165clientGoRequestResultMetricVec.WithLabelValues(code).Inc()
166}
167
168func (clientGoRequestMetricAdapter) Observe(_ context.Context, _ string, u url.URL, latency time.Duration) {
169clientGoRequestLatencyMetricVec.WithLabelValues(u.EscapedPath()).Observe(latency.Seconds())
170}
171
172// Definition of client-go workqueue metrics provider definition.
173type clientGoWorkqueueMetricsProvider struct{}
174
175func (f *clientGoWorkqueueMetricsProvider) RegisterWithK8sGoClient() {
176workqueue.SetProvider(f)
177}
178
179func (f *clientGoWorkqueueMetricsProvider) NewDepthMetric(name string) workqueue.GaugeMetric {
180return clientGoWorkqueueDepthMetricVec.WithLabelValues(name)
181}
182
183func (f *clientGoWorkqueueMetricsProvider) NewAddsMetric(name string) workqueue.CounterMetric {
184return clientGoWorkqueueAddsMetricVec.WithLabelValues(name)
185}
186
187func (f *clientGoWorkqueueMetricsProvider) NewLatencyMetric(name string) workqueue.HistogramMetric {
188return clientGoWorkqueueLatencyMetricVec.WithLabelValues(name)
189}
190
191func (f *clientGoWorkqueueMetricsProvider) NewWorkDurationMetric(name string) workqueue.HistogramMetric {
192return clientGoWorkqueueWorkDurationMetricVec.WithLabelValues(name)
193}
194
195func (f *clientGoWorkqueueMetricsProvider) NewUnfinishedWorkSecondsMetric(name string) workqueue.SettableGaugeMetric {
196return clientGoWorkqueueUnfinishedWorkSecondsMetricVec.WithLabelValues(name)
197}
198
199func (f *clientGoWorkqueueMetricsProvider) NewLongestRunningProcessorSecondsMetric(name string) workqueue.SettableGaugeMetric {
200return clientGoWorkqueueLongestRunningProcessorMetricVec.WithLabelValues(name)
201}
202
203func (clientGoWorkqueueMetricsProvider) NewRetriesMetric(string) workqueue.CounterMetric {
204// Retries are not used so the metric is omitted.
205return noopMetric{}
206}
207