mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-21 02:41:25 +00:00
Merge pull request #78877 from logicalhan/global-registry
use noopRegistry for default global legacy prom registry, expose an http handler, introduce registerable interface
This commit is contained in:
commit
5ae55b992b
@ -22,7 +22,7 @@ import (
|
||||
)
|
||||
|
||||
// Counter is our internal representation for our wrapping struct around prometheus
|
||||
// counters. Counter implements both KubeCollector and CounterMetric.
|
||||
// counters. Counter implements both kubeCollector and CounterMetric.
|
||||
type Counter struct {
|
||||
CounterMetric
|
||||
*CounterOpts
|
||||
@ -30,7 +30,7 @@ type Counter struct {
|
||||
selfCollector
|
||||
}
|
||||
|
||||
// NewCounter returns an object which satisfies the KubeCollector and CounterMetric interfaces.
|
||||
// NewCounter returns an object which satisfies the kubeCollector and CounterMetric interfaces.
|
||||
// However, the object returned will not measure anything unless the collector is first
|
||||
// registered, since the metric is lazily instantiated.
|
||||
func NewCounter(opts *CounterOpts) *Counter {
|
||||
@ -74,7 +74,7 @@ func (c *Counter) initializeDeprecatedMetric() {
|
||||
}
|
||||
|
||||
// CounterVec is the internal representation of our wrapping struct around prometheus
|
||||
// counterVecs. CounterVec implements both KubeCollector and CounterVecMetric.
|
||||
// counterVecs. CounterVec implements both kubeCollector and CounterVecMetric.
|
||||
type CounterVec struct {
|
||||
*prometheus.CounterVec
|
||||
*CounterOpts
|
||||
@ -82,7 +82,7 @@ type CounterVec struct {
|
||||
originalLabels []string
|
||||
}
|
||||
|
||||
// NewCounterVec returns an object which satisfies the KubeCollector and CounterVecMetric interfaces.
|
||||
// NewCounterVec returns an object which satisfies the kubeCollector and CounterVecMetric interfaces.
|
||||
// However, the object returned will not measure anything unless the collector is first
|
||||
// registered, since the metric is lazily instantiated.
|
||||
func NewCounterVec(opts *CounterOpts, labels []string) *CounterVec {
|
||||
|
@ -22,7 +22,7 @@ import (
|
||||
)
|
||||
|
||||
// Gauge is our internal representation for our wrapping struct around prometheus
|
||||
// gauges. kubeGauge implements both KubeCollector and KubeGauge.
|
||||
// gauges. kubeGauge implements both kubeCollector and KubeGauge.
|
||||
type Gauge struct {
|
||||
GaugeMetric
|
||||
*GaugeOpts
|
||||
@ -30,7 +30,7 @@ type Gauge struct {
|
||||
selfCollector
|
||||
}
|
||||
|
||||
// NewGauge returns an object which satisfies the KubeCollector and KubeGauge interfaces.
|
||||
// NewGauge returns an object which satisfies the kubeCollector and KubeGauge interfaces.
|
||||
// However, the object returned will not measure anything unless the collector is first
|
||||
// registered, since the metric is lazily instantiated.
|
||||
func NewGauge(opts *GaugeOpts) *Gauge {
|
||||
@ -74,7 +74,7 @@ func (g *Gauge) initializeDeprecatedMetric() {
|
||||
}
|
||||
|
||||
// GaugeVec is the internal representation of our wrapping struct around prometheus
|
||||
// gaugeVecs. kubeGaugeVec implements both KubeCollector and KubeGaugeVec.
|
||||
// gaugeVecs. kubeGaugeVec implements both kubeCollector and KubeGaugeVec.
|
||||
type GaugeVec struct {
|
||||
*prometheus.GaugeVec
|
||||
*GaugeOpts
|
||||
@ -82,7 +82,7 @@ type GaugeVec struct {
|
||||
originalLabels []string
|
||||
}
|
||||
|
||||
// NewGaugeVec returns an object which satisfies the KubeCollector and KubeGaugeVec interfaces.
|
||||
// NewGaugeVec returns an object which satisfies the kubeCollector and KubeGaugeVec interfaces.
|
||||
// However, the object returned will not measure anything unless the collector is first
|
||||
// registered, since the metric is lazily instantiated.
|
||||
func NewGaugeVec(opts *GaugeOpts, labels []string) *GaugeVec {
|
||||
|
@ -23,7 +23,7 @@ import (
|
||||
)
|
||||
|
||||
// Histogram is our internal representation for our wrapping struct around prometheus
|
||||
// histograms. Summary implements both KubeCollector and ObserverMetric
|
||||
// histograms. Summary implements both kubeCollector and ObserverMetric
|
||||
type Histogram struct {
|
||||
ObserverMetric
|
||||
*HistogramOpts
|
||||
@ -82,7 +82,7 @@ type HistogramVec struct {
|
||||
originalLabels []string
|
||||
}
|
||||
|
||||
// NewHistogramVec returns an object which satisfies KubeCollector and wraps the
|
||||
// NewHistogramVec returns an object which satisfies kubeCollector and wraps the
|
||||
// prometheus.HistogramVec object. However, the object returned will not measure
|
||||
// anything unless the collector is first registered, since the metric is lazily instantiated.
|
||||
func NewHistogramVec(opts *HistogramOpts, labels []string) *HistogramVec {
|
||||
|
@ -11,6 +11,8 @@ go_library(
|
||||
"//staging/src/k8s.io/apimachinery/pkg/version:go_default_library",
|
||||
"//staging/src/k8s.io/component-base/metrics:go_default_library",
|
||||
"//vendor/github.com/prometheus/client_golang/prometheus:go_default_library",
|
||||
"//vendor/github.com/prometheus/client_golang/prometheus/promhttp:go_default_library",
|
||||
"//vendor/github.com/prometheus/client_model/go:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -18,24 +18,46 @@ package legacyregistry
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"sync"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
dto "github.com/prometheus/client_model/go"
|
||||
|
||||
apimachineryversion "k8s.io/apimachinery/pkg/version"
|
||||
"k8s.io/component-base/metrics"
|
||||
)
|
||||
|
||||
var globalRegistryFactory = metricsRegistryFactory{
|
||||
registerQueue: make([]metrics.KubeCollector, 0),
|
||||
mustRegisterQueue: make([]metrics.KubeCollector, 0),
|
||||
var (
|
||||
globalRegistryFactory = metricsRegistryFactory{
|
||||
registerQueue: make([]metrics.Registerable, 0),
|
||||
mustRegisterQueue: make([]metrics.Registerable, 0),
|
||||
globalRegistry: noopRegistry{},
|
||||
}
|
||||
)
|
||||
|
||||
type noopRegistry struct{}
|
||||
|
||||
func (noopRegistry) Register(metrics.Registerable) error { return nil }
|
||||
func (noopRegistry) MustRegister(...metrics.Registerable) {}
|
||||
func (noopRegistry) Unregister(metrics.Registerable) bool { return true }
|
||||
func (noopRegistry) Gather() ([]*dto.MetricFamily, error) { return nil, nil }
|
||||
|
||||
type metricsRegistryFactory struct {
|
||||
globalRegistry metrics.KubeRegistry
|
||||
kubeVersion *apimachineryversion.Info
|
||||
registrationLock sync.Mutex
|
||||
registerQueue []metrics.KubeCollector
|
||||
mustRegisterQueue []metrics.KubeCollector
|
||||
registerQueue []metrics.Registerable
|
||||
mustRegisterQueue []metrics.Registerable
|
||||
}
|
||||
|
||||
// HandlerForGlobalRegistry returns a http handler for the global registry. This
|
||||
// allows us to return a handler for the global registry without having to expose
|
||||
// the global registry itself directly.
|
||||
func HandlerForGlobalRegistry(opts promhttp.HandlerOpts) http.Handler {
|
||||
return promhttp.HandlerFor(globalRegistryFactory.globalRegistry, opts)
|
||||
}
|
||||
|
||||
// SetRegistryFactoryVersion sets the kubernetes version information for all
|
||||
@ -73,29 +95,31 @@ func SetRegistryFactoryVersion(ver apimachineryversion.Info) []error {
|
||||
|
||||
// Register registers a collectable metric, but it uses a global registry. Registration is deferred
|
||||
// until the global registry has a version to use.
|
||||
func Register(c metrics.KubeCollector) error {
|
||||
func Register(c metrics.Registerable) error {
|
||||
globalRegistryFactory.registrationLock.Lock()
|
||||
defer globalRegistryFactory.registrationLock.Unlock()
|
||||
|
||||
if globalRegistryFactory.kubeVersion != nil {
|
||||
return globalRegistryFactory.globalRegistry.Register(c)
|
||||
}
|
||||
if reflect.DeepEqual(globalRegistryFactory.globalRegistry, noopRegistry{}) {
|
||||
globalRegistryFactory.registerQueue = append(globalRegistryFactory.registerQueue, c)
|
||||
return nil
|
||||
}
|
||||
|
||||
return globalRegistryFactory.globalRegistry.Register(c)
|
||||
}
|
||||
|
||||
// MustRegister works like Register but registers any number of
|
||||
// Collectors and panics upon the first registration that causes an
|
||||
// error. Registration is deferred until the global registry has a version to use.
|
||||
func MustRegister(cs ...metrics.KubeCollector) {
|
||||
func MustRegister(cs ...metrics.Registerable) {
|
||||
globalRegistryFactory.registrationLock.Lock()
|
||||
defer globalRegistryFactory.registrationLock.Unlock()
|
||||
|
||||
if globalRegistryFactory.kubeVersion != nil {
|
||||
globalRegistryFactory.globalRegistry.MustRegister(cs...)
|
||||
return
|
||||
}
|
||||
if reflect.DeepEqual(globalRegistryFactory.globalRegistry, noopRegistry{}) {
|
||||
for _, c := range cs {
|
||||
globalRegistryFactory.mustRegisterQueue = append(globalRegistryFactory.mustRegisterQueue, c)
|
||||
}
|
||||
return
|
||||
}
|
||||
globalRegistryFactory.globalRegistry.MustRegister(cs...)
|
||||
return
|
||||
}
|
||||
|
@ -148,8 +148,9 @@ func TestMustRegister(t *testing.T) {
|
||||
func TestDeferredRegister(t *testing.T) {
|
||||
// reset the global registry for this test.
|
||||
globalRegistryFactory = metricsRegistryFactory{
|
||||
registerQueue: make([]metrics.KubeCollector, 0),
|
||||
mustRegisterQueue: make([]metrics.KubeCollector, 0),
|
||||
registerQueue: make([]metrics.Registerable, 0),
|
||||
mustRegisterQueue: make([]metrics.Registerable, 0),
|
||||
globalRegistry: noopRegistry{},
|
||||
}
|
||||
var err error
|
||||
err = Register(alphaDeprecatedCounter)
|
||||
@ -177,8 +178,9 @@ func TestDeferredRegister(t *testing.T) {
|
||||
func TestDeferredMustRegister(t *testing.T) {
|
||||
// reset the global registry for this test.
|
||||
globalRegistryFactory = metricsRegistryFactory{
|
||||
registerQueue: make([]metrics.KubeCollector, 0),
|
||||
mustRegisterQueue: make([]metrics.KubeCollector, 0),
|
||||
registerQueue: make([]metrics.Registerable, 0),
|
||||
mustRegisterQueue: make([]metrics.Registerable, 0),
|
||||
globalRegistry: noopRegistry{},
|
||||
}
|
||||
MustRegister(alphaDeprecatedCounter)
|
||||
|
||||
@ -197,8 +199,8 @@ func TestDeferredMustRegister(t *testing.T) {
|
||||
func TestPreloadedMetrics(t *testing.T) {
|
||||
// reset the global registry for this test.
|
||||
globalRegistryFactory = metricsRegistryFactory{
|
||||
registerQueue: make([]metrics.KubeCollector, 0),
|
||||
mustRegisterQueue: make([]metrics.KubeCollector, 0),
|
||||
registerQueue: make([]metrics.Registerable, 0),
|
||||
mustRegisterQueue: make([]metrics.Registerable, 0),
|
||||
}
|
||||
|
||||
SetRegistryFactoryVersion(apimachineryversion.Info{
|
||||
|
@ -25,12 +25,12 @@ import (
|
||||
)
|
||||
|
||||
/*
|
||||
KubeCollector extends the prometheus.Collector interface to allow customization of the metric
|
||||
kubeCollector extends the prometheus.Collector interface to allow customization of the metric
|
||||
registration process. Defer metric initialization until Create() is called, which then
|
||||
delegates to the underlying metric's initializeMetric or initializeDeprecatedMetric
|
||||
method call depending on whether the metric is deprecated or not.
|
||||
*/
|
||||
type KubeCollector interface {
|
||||
type kubeCollector interface {
|
||||
Collector
|
||||
lazyKubeMetric
|
||||
DeprecatedVersion() *semver.Version
|
||||
@ -57,8 +57,8 @@ type lazyKubeMetric interface {
|
||||
/*
|
||||
lazyMetric implements lazyKubeMetric. A lazy metric is lazy because it waits until metric
|
||||
registration time before instantiation. Add it as an anonymous field to a struct that
|
||||
implements KubeCollector to get deferred registration behavior. You must call lazyInit
|
||||
with the KubeCollector itself as an argument.
|
||||
implements kubeCollector to get deferred registration behavior. You must call lazyInit
|
||||
with the kubeCollector itself as an argument.
|
||||
*/
|
||||
type lazyMetric struct {
|
||||
isDeprecated bool
|
||||
@ -66,17 +66,17 @@ type lazyMetric struct {
|
||||
isCreated bool
|
||||
markDeprecationOnce sync.Once
|
||||
createOnce sync.Once
|
||||
self KubeCollector
|
||||
self kubeCollector
|
||||
}
|
||||
|
||||
func (r *lazyMetric) IsCreated() bool {
|
||||
return r.isCreated
|
||||
}
|
||||
|
||||
// lazyInit provides the lazyMetric with a reference to the KubeCollector it is supposed
|
||||
// lazyInit provides the lazyMetric with a reference to the kubeCollector it is supposed
|
||||
// to allow lazy initialization for. It should be invoked in the factory function which creates new
|
||||
// KubeCollector type objects.
|
||||
func (r *lazyMetric) lazyInit(self KubeCollector) {
|
||||
// kubeCollector type objects.
|
||||
func (r *lazyMetric) lazyInit(self kubeCollector) {
|
||||
r.self = self
|
||||
}
|
||||
|
||||
|
@ -23,12 +23,19 @@ import (
|
||||
apimachineryversion "k8s.io/apimachinery/pkg/version"
|
||||
)
|
||||
|
||||
// Registerable is an interface for a collector metric which we
|
||||
// will register with KubeRegistry.
|
||||
type Registerable interface {
|
||||
prometheus.Collector
|
||||
Create(version *semver.Version) bool
|
||||
}
|
||||
|
||||
// KubeRegistry is an interface which implements a subset of prometheus.Registerer and
|
||||
// prometheus.Gatherer interfaces
|
||||
type KubeRegistry interface {
|
||||
Register(KubeCollector) error
|
||||
MustRegister(...KubeCollector)
|
||||
Unregister(KubeCollector) bool
|
||||
Register(Registerable) error
|
||||
MustRegister(...Registerable)
|
||||
Unregister(Registerable) bool
|
||||
Gather() ([]*dto.MetricFamily, error)
|
||||
}
|
||||
|
||||
@ -45,7 +52,7 @@ type kubeRegistry struct {
|
||||
// Collector are invalid or if they — in combination with descriptors of
|
||||
// already registered Collectors — do not fulfill the consistency and
|
||||
// uniqueness criteria described in the documentation of metric.Desc.
|
||||
func (kr *kubeRegistry) Register(c KubeCollector) error {
|
||||
func (kr *kubeRegistry) Register(c Registerable) error {
|
||||
if c.Create(&kr.version) {
|
||||
return kr.PromRegistry.Register(c)
|
||||
}
|
||||
@ -55,7 +62,7 @@ func (kr *kubeRegistry) Register(c KubeCollector) error {
|
||||
// MustRegister works like Register but registers any number of
|
||||
// Collectors and panics upon the first registration that causes an
|
||||
// error.
|
||||
func (kr *kubeRegistry) MustRegister(cs ...KubeCollector) {
|
||||
func (kr *kubeRegistry) MustRegister(cs ...Registerable) {
|
||||
metrics := make([]prometheus.Collector, 0, len(cs))
|
||||
for _, c := range cs {
|
||||
if c.Create(&kr.version) {
|
||||
@ -71,7 +78,7 @@ func (kr *kubeRegistry) MustRegister(cs ...KubeCollector) {
|
||||
// returns whether a Collector was unregistered. Note that an unchecked
|
||||
// Collector cannot be unregistered (as its Describe method does not
|
||||
// yield any descriptor).
|
||||
func (kr *kubeRegistry) Unregister(collector KubeCollector) bool {
|
||||
func (kr *kubeRegistry) Unregister(collector Registerable) bool {
|
||||
return kr.PromRegistry.Unregister(collector)
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ import (
|
||||
)
|
||||
|
||||
// Summary is our internal representation for our wrapping struct around prometheus
|
||||
// summaries. Summary implements both KubeCollector and ObserverMetric
|
||||
// summaries. Summary implements both kubeCollector and ObserverMetric
|
||||
//
|
||||
// DEPRECATED: as per the metrics overhaul KEP
|
||||
type Summary struct {
|
||||
@ -87,7 +87,7 @@ type SummaryVec struct {
|
||||
originalLabels []string
|
||||
}
|
||||
|
||||
// NewSummaryVec returns an object which satisfies KubeCollector and wraps the
|
||||
// NewSummaryVec returns an object which satisfies kubeCollector and wraps the
|
||||
// prometheus.SummaryVec object. However, the object returned will not measure
|
||||
// anything unless the collector is first registered, since the metric is lazily instantiated.
|
||||
//
|
||||
|
@ -59,6 +59,8 @@ type CounterVecMetric interface {
|
||||
// GaugeMetric is an interface which defines a subset of the interface provided by prometheus.Gauge
|
||||
type GaugeMetric interface {
|
||||
Set(float64)
|
||||
Inc()
|
||||
Dec()
|
||||
}
|
||||
|
||||
// ObserverMetric captures individual observations.
|
||||
|
Loading…
Reference in New Issue
Block a user