Skip to content

Commit 9103ac4

Browse files
Use a global setter
1 parent db73121 commit 9103ac4

File tree

15 files changed

+554
-518
lines changed

15 files changed

+554
-518
lines changed

pkg/config/controller.go

-5
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import (
2020
"time"
2121

2222
"github.com/go-logr/logr"
23-
"sigs.k8s.io/controller-runtime/pkg/metrics"
2423
)
2524

2625
// Controller contains configuration options for controllers. It only includes options
@@ -67,10 +66,6 @@ type Controller struct {
6766
// Note: This flag is disabled by default until a future version. It's currently in beta.
6867
UsePriorityQueue *bool
6968

70-
// MetricsProvider allows users to override the location where controller metrics are emitted.
71-
// By default, metrics are emitted to a pre-configured Prometheus registry
72-
MetricsProvider metrics.ControllerMetricsProvider
73-
7469
// Logger is the logger controllers should use.
7570
Logger logr.Logger
7671
}

pkg/controller/controller.go

-14
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import (
2525
"k8s.io/client-go/util/workqueue"
2626
"k8s.io/klog/v2"
2727
"k8s.io/utils/ptr"
28-
"sigs.k8s.io/controller-runtime/pkg/metrics"
2928

3029
"sigs.k8s.io/controller-runtime/pkg/config"
3130
"sigs.k8s.io/controller-runtime/pkg/controller/priorityqueue"
@@ -85,10 +84,6 @@ type TypedOptions[request comparable] struct {
8584
// Logger will be used to build a default LogConstructor if unset.
8685
Logger logr.Logger
8786

88-
// MetricsProvider allows users to override the location where controller metrics are emitted.
89-
// By default, metrics are emitted to a pre-configured Prometheus registry
90-
MetricsProvider metrics.ControllerMetricsProvider
91-
9287
// LogConstructor is used to construct a logger used for this controller and passed
9388
// to each reconciliation via the context field.
9489
LogConstructor func(request *request) logr.Logger
@@ -106,10 +101,6 @@ func (options *TypedOptions[request]) DefaultFromConfig(config config.Controller
106101
options.Logger = config.Logger
107102
}
108103

109-
if options.MetricsProvider == nil {
110-
options.MetricsProvider = config.MetricsProvider
111-
}
112-
113104
if options.SkipNameValidation == nil {
114105
options.SkipNameValidation = config.SkipNameValidation
115106
}
@@ -205,10 +196,6 @@ func NewTypedUnmanaged[request comparable](name string, options TypedOptions[req
205196
}
206197
}
207198

208-
if options.MetricsProvider == nil {
209-
options.MetricsProvider = metrics.NewPrometheusProvider()
210-
}
211-
212199
if options.LogConstructor == nil {
213200
log := options.Logger.WithValues(
214201
"controller", name,
@@ -263,7 +250,6 @@ func NewTypedUnmanaged[request comparable](name string, options TypedOptions[req
263250
MaxConcurrentReconciles: options.MaxConcurrentReconciles,
264251
CacheSyncTimeout: options.CacheSyncTimeout,
265252
Name: name,
266-
MetricsProvider: options.MetricsProvider,
267253
LogConstructor: options.LogConstructor,
268254
RecoverPanic: options.RecoverPanic,
269255
LeaderElected: options.NeedLeaderElection,

pkg/controller/metrics/metrics.go

+195
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
/*
2+
Copyright 2018 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package metrics
18+
19+
import (
20+
"time"
21+
22+
"github.com/prometheus/client_golang/prometheus"
23+
internalmetrics "sigs.k8s.io/controller-runtime/pkg/internal/metrics"
24+
"sigs.k8s.io/controller-runtime/pkg/metrics"
25+
)
26+
27+
var (
28+
// reconcileTotal is a prometheus counter metrics which holds the total
29+
// number of reconciliations per controller. It has two labels. controller label refers
30+
// to the controller name and result label refers to the reconcile result i.e
31+
// success, error, requeue, requeue_after.
32+
reconcileTotal = prometheus.NewCounterVec(prometheus.CounterOpts{
33+
Name: "controller_runtime_reconcile_total",
34+
Help: "Total number of reconciliations per controller",
35+
}, []string{"controller", "result"})
36+
37+
// reconcileErrors is a prometheus counter metrics which holds the total
38+
// number of errors from the Reconciler.
39+
reconcileErrors = prometheus.NewCounterVec(prometheus.CounterOpts{
40+
Name: "controller_runtime_reconcile_errors_total",
41+
Help: "Total number of reconciliation errors per controller",
42+
}, []string{"controller"})
43+
44+
// terminalReconcileErrors is a prometheus counter metrics which holds the total
45+
// number of terminal errors from the Reconciler.
46+
terminalReconcileErrors = prometheus.NewCounterVec(prometheus.CounterOpts{
47+
Name: "controller_runtime_terminal_reconcile_errors_total",
48+
Help: "Total number of terminal reconciliation errors per controller",
49+
}, []string{"controller"})
50+
51+
// reconcilePanics is a prometheus counter metrics which holds the total
52+
// number of panics from the Reconciler.
53+
reconcilePanics = prometheus.NewCounterVec(prometheus.CounterOpts{
54+
Name: "controller_runtime_reconcile_panics_total",
55+
Help: "Total number of reconciliation panics per controller",
56+
}, []string{"controller"})
57+
58+
// reconcileTime is a prometheus metric which keeps track of the duration
59+
// of reconciliations.
60+
reconcileTime = prometheus.NewHistogramVec(prometheus.HistogramOpts{
61+
Name: "controller_runtime_reconcile_time_seconds",
62+
Help: "Length of time per reconciliation per controller",
63+
Buckets: []float64{0.005, 0.01, 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0,
64+
1.25, 1.5, 1.75, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30, 40, 50, 60},
65+
NativeHistogramBucketFactor: 1.1,
66+
NativeHistogramMaxBucketNumber: 100,
67+
NativeHistogramMinResetDuration: 1 * time.Hour,
68+
}, []string{"controller"})
69+
70+
// workerCount is a prometheus metric which holds the number of
71+
// concurrent reconciles per controller.
72+
workerCount = prometheus.NewGaugeVec(prometheus.GaugeOpts{
73+
Name: "controller_runtime_max_concurrent_reconciles",
74+
Help: "Maximum number of concurrent reconciles per controller",
75+
}, []string{"controller"})
76+
77+
// activeWorkers is a prometheus metric which holds the number
78+
// of active workers per controller.
79+
activeWorkers = prometheus.NewGaugeVec(prometheus.GaugeOpts{
80+
Name: "controller_runtime_active_workers",
81+
Help: "Number of currently used workers per controller",
82+
}, []string{"controller"})
83+
)
84+
85+
// ControllerMetricsProvider is an interface that provides methods for firing controller metrics
86+
type ControllerMetricsProvider interface {
87+
// ReconcileTotal is a prometheus counter metrics which holds the total
88+
// number of reconciliations per controller. It has two labels. controller label refers
89+
// to the controller name and result label refers to the reconcile result i.e
90+
// success, error, requeue, requeue_after.
91+
ReconcileTotal() internalmetrics.CounterMetric
92+
// ReconcileErrors is a prometheus counter metrics which holds the total
93+
// number of errors from the Reconciler.
94+
ReconcileErrors() internalmetrics.CounterMetric
95+
// TerminalReconcileErrors is a prometheus counter metrics which holds the total
96+
// number of terminal errors from the Reconciler.
97+
TerminalReconcileErrors() internalmetrics.CounterMetric
98+
// ReconcilePanics is a prometheus counter metrics which holds the total
99+
// number of panics from the Reconciler.
100+
ReconcilePanics() internalmetrics.CounterMetric
101+
// ReconcileTime is a prometheus metric which keeps track of the duration
102+
// of reconciliations.
103+
ReconcileTime() internalmetrics.HistogramMetric
104+
// WorkerCount is a prometheus metric which holds the number of
105+
// concurrent reconciles per controller.
106+
WorkerCount() internalmetrics.GaugeMetric
107+
// ActiveWorkers is a prometheus metric which holds the number
108+
// of active workers per controller.
109+
ActiveWorkers() internalmetrics.GaugeMetric
110+
}
111+
112+
// PrometheusProvider is a metrics.ControllerMetricsProvider and a metrics.LeaderElectionMetricsProvider
113+
// that registers and fires prometheus metrics in response to leader election and controller events
114+
type PrometheusProvider struct {
115+
reconcileTotal *prometheus.CounterVec
116+
reconcileErrors *prometheus.CounterVec
117+
terminalReconcileErrors *prometheus.CounterVec
118+
reconcilePanics *prometheus.CounterVec
119+
reconcileTime *prometheus.HistogramVec
120+
workerCount *prometheus.GaugeVec
121+
activeWorkers *prometheus.GaugeVec
122+
}
123+
124+
// NewPrometheusProvider creates a PrometheusProvider
125+
func NewPrometheusProvider() *PrometheusProvider {
126+
return &PrometheusProvider{
127+
reconcileTotal: reconcileTotal,
128+
reconcileErrors: reconcileErrors,
129+
terminalReconcileErrors: terminalReconcileErrors,
130+
reconcilePanics: reconcilePanics,
131+
reconcileTime: reconcileTime,
132+
workerCount: workerCount,
133+
activeWorkers: activeWorkers,
134+
}
135+
}
136+
137+
// ReconcileTotal returns a Prometheus counter that fulfills the CounterMetric interface
138+
func (p PrometheusProvider) ReconcileTotal() internalmetrics.CounterMetric {
139+
return &internalmetrics.PrometheusCounterAdapter{CounterVec: p.reconcileTotal}
140+
}
141+
142+
// ReconcileErrors returns a Prometheus counter that fulfills the CounterMetric interface
143+
func (p PrometheusProvider) ReconcileErrors() internalmetrics.CounterMetric {
144+
return &internalmetrics.PrometheusCounterAdapter{CounterVec: p.reconcileErrors}
145+
}
146+
147+
// TerminalReconcileErrors returns a Prometheus counter that fulfills the CounterMetric interface
148+
func (p PrometheusProvider) TerminalReconcileErrors() internalmetrics.CounterMetric {
149+
return &internalmetrics.PrometheusCounterAdapter{CounterVec: p.terminalReconcileErrors}
150+
}
151+
152+
// ReconcilePanics returns a Prometheus counter that fulfills the CounterMetric interface
153+
func (p PrometheusProvider) ReconcilePanics() internalmetrics.CounterMetric {
154+
return &internalmetrics.PrometheusCounterAdapter{CounterVec: p.reconcilePanics}
155+
}
156+
157+
// ReconcileTime returns a Prometheus histogram that fulfills the ObservationMetric interface
158+
func (p PrometheusProvider) ReconcileTime() internalmetrics.HistogramMetric {
159+
return &internalmetrics.PrometheusHistogramAdapter{HistogramVec: p.reconcileTime}
160+
}
161+
162+
// WorkerCount returns a Prometheus gauge that fulfills the GaugeMetric interface
163+
func (p PrometheusProvider) WorkerCount() internalmetrics.GaugeMetric {
164+
return &internalmetrics.PrometheusGaugeAdapter{GaugeVec: p.workerCount}
165+
}
166+
167+
// ActiveWorkers returns a Prometheus gauge that fulfills the GaugeMetric interface
168+
func (p PrometheusProvider) ActiveWorkers() internalmetrics.GaugeMetric {
169+
return &internalmetrics.PrometheusGaugeAdapter{GaugeVec: p.activeWorkers}
170+
}
171+
172+
func init() {
173+
metrics.Registry.MustRegister(
174+
reconcileTotal,
175+
reconcileErrors,
176+
terminalReconcileErrors,
177+
reconcilePanics,
178+
reconcileTime,
179+
workerCount,
180+
activeWorkers,
181+
)
182+
}
183+
184+
var controllerMetricsProvider ControllerMetricsProvider = NewPrometheusProvider()
185+
186+
// SetControllerMetricsProvider assigns a provider to the ControllerMetricsProvider for exposing controller metrics.
187+
// The PrometheusProvider will be used by default if the provider is not overridden
188+
func SetControllerMetricsProvider(provider ControllerMetricsProvider) {
189+
controllerMetricsProvider = provider
190+
}
191+
192+
// GetControllerMetricsProvider returns the controller metrics provider being used by the controller reconciliation
193+
func GetControllerMetricsProvider() ControllerMetricsProvider {
194+
return controllerMetricsProvider
195+
}

pkg/controller/priorityqueue/metrics.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import (
66

77
"k8s.io/client-go/util/workqueue"
88
"k8s.io/utils/clock"
9-
"sigs.k8s.io/controller-runtime/pkg/internal/metrics"
9+
"sigs.k8s.io/controller-runtime/pkg/metrics"
1010
)
1111

1212
// This file is mostly a copy of unexported code from

pkg/controller/priorityqueue/metrics_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import (
44
"sync"
55

66
"k8s.io/client-go/util/workqueue"
7-
"sigs.k8s.io/controller-runtime/pkg/internal/metrics"
7+
"sigs.k8s.io/controller-runtime/pkg/metrics"
88
)
99

1010
func newFakeMetricsProvider() *fakeMetricsProvider {

pkg/controller/priorityqueue/priorityqueue.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import (
1212
"k8s.io/utils/clock"
1313
"k8s.io/utils/ptr"
1414

15-
"sigs.k8s.io/controller-runtime/pkg/internal/metrics"
15+
"sigs.k8s.io/controller-runtime/pkg/metrics"
1616
)
1717

1818
// AddOpts describes the options for adding items to the queue.
@@ -56,7 +56,7 @@ func New[T comparable](name string, o ...Opt[T]) PriorityQueue[T] {
5656
}
5757

5858
if opts.MetricProvider == nil {
59-
opts.MetricProvider = metrics.WorkqueueMetricsProvider{}
59+
opts.MetricProvider = metrics.PrometheusWorkqueueMetricsProvider{}
6060
}
6161

6262
pq := &priorityqueue[T]{

0 commit comments

Comments
 (0)