mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 19:31:44 +00:00
move global registry code into subdirectory 'legacyregistry'
This commit is contained in:
parent
04db3dc9f7
commit
7b619f5763
@ -53,6 +53,9 @@ filegroup(
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//staging/src/k8s.io/component-base/metrics/legacyregistry:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
@ -74,7 +74,7 @@ func TestCounter(t *testing.T) {
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
registry := newKubeRegistry(&apimachineryversion.Info{
|
||||
registry := NewKubeRegistry(&apimachineryversion.Info{
|
||||
Major: "1",
|
||||
Minor: "15",
|
||||
GitVersion: "v1.15.0-alpha-1.12345",
|
||||
@ -175,7 +175,7 @@ func TestCounterVec(t *testing.T) {
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
registry := newKubeRegistry(&apimachineryversion.Info{
|
||||
registry := NewKubeRegistry(&apimachineryversion.Info{
|
||||
Major: "1",
|
||||
Minor: "15",
|
||||
GitVersion: "v1.15.0-alpha-1.12345",
|
||||
|
@ -0,0 +1,41 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["registry.go"],
|
||||
importmap = "k8s.io/kubernetes/vendor/k8s.io/component-base/metrics/legacyregistry",
|
||||
importpath = "k8s.io/component-base/metrics/legacyregistry",
|
||||
deps = [
|
||||
"//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_model/go:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["registry_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//staging/src/k8s.io/apimachinery/pkg/version:go_default_library",
|
||||
"//staging/src/k8s.io/component-base/metrics:go_default_library",
|
||||
"//vendor/github.com/blang/semver:go_default_library",
|
||||
"//vendor/github.com/prometheus/client_golang/prometheus:go_default_library",
|
||||
"//vendor/github.com/stretchr/testify/assert:go_default_library",
|
||||
],
|
||||
)
|
@ -0,0 +1,89 @@
|
||||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package legacyregistry
|
||||
|
||||
import (
|
||||
apimachineryversion "k8s.io/apimachinery/pkg/version"
|
||||
"k8s.io/component-base/metrics"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var globalRegistryFactory = metricsRegistryFactory{
|
||||
registerQueue: make([]metrics.KubeCollector, 0),
|
||||
mustRegisterQueue: make([]metrics.KubeCollector, 0),
|
||||
}
|
||||
|
||||
type metricsRegistryFactory struct {
|
||||
globalRegistry metrics.KubeRegistry
|
||||
kubeVersion *apimachineryversion.Info
|
||||
registrationLock sync.Mutex
|
||||
registerQueue []metrics.KubeCollector
|
||||
mustRegisterQueue []metrics.KubeCollector
|
||||
}
|
||||
|
||||
// SetRegistryFactoryVersion sets the kubernetes version information for all
|
||||
// subsequent metrics registry initializations. Only the first call has an effect.
|
||||
// If a version is not set, then metrics registry creation will no-opt
|
||||
func SetRegistryFactoryVersion(ver *apimachineryversion.Info) []error {
|
||||
globalRegistryFactory.registrationLock.Lock()
|
||||
defer globalRegistryFactory.registrationLock.Unlock()
|
||||
if globalRegistryFactory.kubeVersion != nil {
|
||||
return nil
|
||||
}
|
||||
registrationErrs := make([]error, 0)
|
||||
globalRegistryFactory.globalRegistry = metrics.NewKubeRegistry(ver)
|
||||
globalRegistryFactory.kubeVersion = ver
|
||||
for _, c := range globalRegistryFactory.registerQueue {
|
||||
err := globalRegistryFactory.globalRegistry.Register(c)
|
||||
if err != nil {
|
||||
registrationErrs = append(registrationErrs, err)
|
||||
}
|
||||
}
|
||||
for _, c := range globalRegistryFactory.mustRegisterQueue {
|
||||
globalRegistryFactory.globalRegistry.MustRegister(c)
|
||||
}
|
||||
return registrationErrs
|
||||
}
|
||||
|
||||
// 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 {
|
||||
globalRegistryFactory.registrationLock.Lock()
|
||||
defer globalRegistryFactory.registrationLock.Unlock()
|
||||
|
||||
if globalRegistryFactory.kubeVersion != nil {
|
||||
return globalRegistryFactory.globalRegistry.Register(c)
|
||||
}
|
||||
globalRegistryFactory.registerQueue = append(globalRegistryFactory.registerQueue, c)
|
||||
return nil
|
||||
}
|
||||
|
||||
// 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) {
|
||||
globalRegistryFactory.registrationLock.Lock()
|
||||
defer globalRegistryFactory.registrationLock.Unlock()
|
||||
|
||||
if globalRegistryFactory.kubeVersion != nil {
|
||||
globalRegistryFactory.globalRegistry.MustRegister(cs...)
|
||||
return
|
||||
}
|
||||
for _, c := range cs {
|
||||
globalRegistryFactory.mustRegisterQueue = append(globalRegistryFactory.mustRegisterQueue, c)
|
||||
}
|
||||
}
|
@ -0,0 +1,195 @@
|
||||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package legacyregistry
|
||||
|
||||
import (
|
||||
"github.com/blang/semver"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"k8s.io/component-base/metrics"
|
||||
"testing"
|
||||
|
||||
apimachineryversion "k8s.io/apimachinery/pkg/version"
|
||||
)
|
||||
|
||||
func init() {
|
||||
SetRegistryFactoryVersion(&apimachineryversion.Info{
|
||||
Major: "1",
|
||||
Minor: "15",
|
||||
GitVersion: "v1.15.0-alpha-1.12345",
|
||||
})
|
||||
}
|
||||
|
||||
var (
|
||||
v115 = semver.MustParse("1.15.0")
|
||||
v114 = semver.MustParse("1.14.0")
|
||||
alphaCounter = metrics.NewCounter(
|
||||
&metrics.CounterOpts{
|
||||
Namespace: "some_namespace",
|
||||
Name: "test_counter_name",
|
||||
Subsystem: "subsystem",
|
||||
StabilityLevel: metrics.ALPHA,
|
||||
Help: "counter help",
|
||||
},
|
||||
)
|
||||
alphaDeprecatedCounter = metrics.NewCounter(
|
||||
&metrics.CounterOpts{
|
||||
Namespace: "some_namespace",
|
||||
Name: "test_alpha_dep_counter",
|
||||
Subsystem: "subsystem",
|
||||
StabilityLevel: metrics.ALPHA,
|
||||
Help: "counter help",
|
||||
DeprecatedVersion: &v115,
|
||||
},
|
||||
)
|
||||
alphaHiddenCounter = metrics.NewCounter(
|
||||
&metrics.CounterOpts{
|
||||
Namespace: "some_namespace",
|
||||
Name: "test_alpha_hidden_counter",
|
||||
Subsystem: "subsystem",
|
||||
StabilityLevel: metrics.ALPHA,
|
||||
Help: "counter help",
|
||||
DeprecatedVersion: &v114,
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
func TestRegister(t *testing.T) {
|
||||
var tests = []struct {
|
||||
desc string
|
||||
metrics []*metrics.Counter
|
||||
registryVersion *semver.Version
|
||||
expectedErrors []error
|
||||
expectedIsCreatedValues []bool
|
||||
expectedIsDeprecated []bool
|
||||
expectedIsHidden []bool
|
||||
}{
|
||||
{
|
||||
desc: "test registering same metric multiple times",
|
||||
metrics: []*metrics.Counter{alphaCounter, alphaCounter},
|
||||
expectedErrors: []error{nil, prometheus.AlreadyRegisteredError{}},
|
||||
expectedIsCreatedValues: []bool{true, true},
|
||||
expectedIsDeprecated: []bool{false, false},
|
||||
expectedIsHidden: []bool{false, false},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
//t.Errorf("len %v - %v\n", len(test.metrics), len(test.expectedErrors))
|
||||
for i, m := range test.metrics {
|
||||
//t.Errorf("m %v\n", m)
|
||||
err := Register(m)
|
||||
if err != test.expectedErrors[i] && err.Error() != test.expectedErrors[i].Error() {
|
||||
t.Errorf("Got unexpected error %v, wanted %v", err, test.expectedErrors[i])
|
||||
}
|
||||
if m.IsCreated() != test.expectedIsCreatedValues[i] {
|
||||
t.Errorf("Got isCreated == %v, wanted isCreated to be %v", m.IsCreated(), test.expectedIsCreatedValues[i])
|
||||
}
|
||||
if m.IsDeprecated() != test.expectedIsDeprecated[i] {
|
||||
t.Errorf("Got IsDeprecated == %v, wanted IsDeprecated to be %v", m.IsDeprecated(), test.expectedIsDeprecated[i])
|
||||
}
|
||||
if m.IsHidden() != test.expectedIsHidden[i] {
|
||||
t.Errorf("Got IsHidden == %v, wanted IsHidden to be %v", m.IsHidden(), test.expectedIsDeprecated[i])
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMustRegister(t *testing.T) {
|
||||
var tests = []struct {
|
||||
desc string
|
||||
metrics []*metrics.Counter
|
||||
registryVersion *semver.Version
|
||||
expectedPanics []bool
|
||||
}{
|
||||
{
|
||||
desc: "test must registering same deprecated metric",
|
||||
metrics: []*metrics.Counter{alphaDeprecatedCounter, alphaDeprecatedCounter},
|
||||
expectedPanics: []bool{false, true},
|
||||
},
|
||||
{
|
||||
desc: "test alpha hidden metric",
|
||||
metrics: []*metrics.Counter{alphaHiddenCounter},
|
||||
expectedPanics: []bool{false},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
for i, m := range test.metrics {
|
||||
if test.expectedPanics[i] {
|
||||
assert.Panics(t,
|
||||
func() { MustRegister(m) },
|
||||
"Did not panic even though we expected it.")
|
||||
} else {
|
||||
MustRegister(m)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeferredRegister(t *testing.T) {
|
||||
// reset the global registry for this test.
|
||||
globalRegistryFactory = metricsRegistryFactory{
|
||||
registerQueue: make([]metrics.KubeCollector, 0),
|
||||
mustRegisterQueue: make([]metrics.KubeCollector, 0),
|
||||
}
|
||||
var err error
|
||||
err = Register(alphaDeprecatedCounter)
|
||||
if err != nil {
|
||||
t.Errorf("Got err == %v, expected no error", err)
|
||||
}
|
||||
err = Register(alphaDeprecatedCounter)
|
||||
if err != nil {
|
||||
t.Errorf("Got err == %v, expected no error", err)
|
||||
}
|
||||
// set the global registry version
|
||||
errs := SetRegistryFactoryVersion(&apimachineryversion.Info{
|
||||
Major: "1",
|
||||
Minor: "15",
|
||||
GitVersion: "v1.15.0-alpha-1.12345",
|
||||
})
|
||||
if len(errs) != 1 {
|
||||
t.Errorf("Got %d errs, expected 1", len(errs))
|
||||
for _, err := range errs {
|
||||
t.Logf("\t Got %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeferredMustRegister(t *testing.T) {
|
||||
// reset the global registry for this test.
|
||||
globalRegistryFactory = metricsRegistryFactory{
|
||||
registerQueue: make([]metrics.KubeCollector, 0),
|
||||
mustRegisterQueue: make([]metrics.KubeCollector, 0),
|
||||
}
|
||||
MustRegister(alphaDeprecatedCounter)
|
||||
|
||||
MustRegister(alphaDeprecatedCounter)
|
||||
assert.Panics(t,
|
||||
func() {
|
||||
SetRegistryFactoryVersion(&apimachineryversion.Info{
|
||||
Major: "1",
|
||||
Minor: "15",
|
||||
GitVersion: "v1.15.0-alpha-1.12345",
|
||||
})
|
||||
},
|
||||
"Did not panic even though we expected it.")
|
||||
}
|
@ -32,7 +32,7 @@ method call depending on whether the metric is deprecated or not.
|
||||
*/
|
||||
type KubeCollector interface {
|
||||
Collector
|
||||
LazyMetric
|
||||
lazyKubeMetric
|
||||
DeprecatedVersion() *semver.Version
|
||||
// Each collector metric should provide an initialization function
|
||||
// for both deprecated and non-deprecated variants of a metric. This
|
||||
@ -43,11 +43,11 @@ type KubeCollector interface {
|
||||
}
|
||||
|
||||
/*
|
||||
LazyMetric defines our registration functionality. LazyMetric objects are expected
|
||||
lazyKubeMetric defines our metric registration interface. lazyKubeMetric objects are expected
|
||||
to lazily instantiate metrics (i.e defer metric instantiation until when
|
||||
the Create() function is explicitly called).
|
||||
*/
|
||||
type LazyMetric interface {
|
||||
type lazyKubeMetric interface {
|
||||
Create(*semver.Version) bool
|
||||
IsCreated() bool
|
||||
IsHidden() bool
|
||||
@ -55,7 +55,7 @@ type LazyMetric interface {
|
||||
}
|
||||
|
||||
/*
|
||||
lazyMetric implements LazyMetric. A lazy metric is lazy because it waits until metric
|
||||
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.
|
||||
|
@ -21,28 +21,8 @@ import (
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
dto "github.com/prometheus/client_model/go"
|
||||
apimachineryversion "k8s.io/apimachinery/pkg/version"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var globalRegistryFactory = metricsRegistryFactory{
|
||||
globalRegistry: &noopKubeRegistry{},
|
||||
}
|
||||
|
||||
// NewKubeRegistry creates a new kubernetes metric registry, loading in the kubernetes
|
||||
// version information available to the binary.
|
||||
func (r metricsRegistryFactory) newKubeRegistry() KubeRegistry {
|
||||
if r.kubeVersion == nil {
|
||||
return noopKubeRegistry{}
|
||||
}
|
||||
return newKubeRegistry(r.kubeVersion)
|
||||
}
|
||||
|
||||
type metricsRegistryFactory struct {
|
||||
globalRegistry KubeRegistry
|
||||
kubeVersion *apimachineryversion.Info
|
||||
setVersionOnce sync.Once
|
||||
}
|
||||
|
||||
// KubeRegistry is an interface which implements a subset of prometheus.Registerer and
|
||||
// prometheus.Gatherer interfaces
|
||||
type KubeRegistry interface {
|
||||
@ -60,28 +40,6 @@ type kubeRegistry struct {
|
||||
version semver.Version
|
||||
}
|
||||
|
||||
// SetRegistryFactoryVersion sets the kubernetes version information for all
|
||||
// subsequent metrics registry initializations. Only the first call has an effect.
|
||||
// If a version is not set, then metrics registry creation will no-opt
|
||||
func SetRegistryFactoryVersion(ver *apimachineryversion.Info) {
|
||||
globalRegistryFactory.setVersionOnce.Do(func() {
|
||||
globalRegistryFactory.globalRegistry = newKubeRegistry(ver)
|
||||
globalRegistryFactory.kubeVersion = ver
|
||||
})
|
||||
}
|
||||
|
||||
// Register registers a collectable metric, but it uses a global registry.
|
||||
func Register(c KubeCollector) error {
|
||||
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.
|
||||
func MustRegister(cs ...KubeCollector) {
|
||||
globalRegistryFactory.globalRegistry.MustRegister(cs...)
|
||||
}
|
||||
|
||||
// Register registers a new Collector to be included in metrics
|
||||
// collection. It returns an error if the descriptors provided by the
|
||||
// Collector are invalid or if they — in combination with descriptors of
|
||||
@ -128,27 +86,11 @@ func (kr *kubeRegistry) Gather() ([]*dto.MetricFamily, error) {
|
||||
return kr.PromRegistry.Gather()
|
||||
}
|
||||
|
||||
// NewKubeRegistry creates a new kubernetes metric registry, loading in the kubernetes
|
||||
// version information available to the binary.
|
||||
func NewKubeRegistry() KubeRegistry {
|
||||
return globalRegistryFactory.newKubeRegistry()
|
||||
}
|
||||
|
||||
// newKubeRegistry creates a new vanilla Registry without any Collectors
|
||||
// NewKubeRegistry creates a new vanilla Registry without any Collectors
|
||||
// pre-registered.
|
||||
func newKubeRegistry(v *apimachineryversion.Info) KubeRegistry {
|
||||
func NewKubeRegistry(v *apimachineryversion.Info) KubeRegistry {
|
||||
return &kubeRegistry{
|
||||
PromRegistry: prometheus.NewRegistry(),
|
||||
version: parseVersion(*v),
|
||||
}
|
||||
}
|
||||
|
||||
// noop registry
|
||||
var noopRegistry = &noopKubeRegistry{}
|
||||
|
||||
type noopKubeRegistry struct{}
|
||||
|
||||
func (noopKubeRegistry) Register(KubeCollector) error { return nil }
|
||||
func (noopKubeRegistry) MustRegister(...KubeCollector) {}
|
||||
func (noopKubeRegistry) Unregister(KubeCollector) bool { return false }
|
||||
func (noopKubeRegistry) Gather() ([]*dto.MetricFamily, error) { return nil, nil }
|
||||
|
@ -56,15 +56,6 @@ var (
|
||||
DeprecatedVersion: &v114,
|
||||
},
|
||||
)
|
||||
stableCounter = NewCounter(
|
||||
&CounterOpts{
|
||||
Namespace: "some_namespace",
|
||||
Name: "test_some_other_counter",
|
||||
Subsystem: "subsystem",
|
||||
StabilityLevel: STABLE,
|
||||
Help: "counter help",
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
func TestRegister(t *testing.T) {
|
||||
@ -99,7 +90,7 @@ func TestRegister(t *testing.T) {
|
||||
desc: "test alpha deprecated metric",
|
||||
metrics: []*Counter{alphaDeprecatedCounter},
|
||||
registryVersion: &v115,
|
||||
expectedErrors: []error{nil, prometheus.AlreadyRegisteredError{}},
|
||||
expectedErrors: []error{nil},
|
||||
expectedIsCreatedValues: []bool{true},
|
||||
expectedIsDeprecated: []bool{true},
|
||||
expectedIsHidden: []bool{false},
|
||||
@ -108,7 +99,7 @@ func TestRegister(t *testing.T) {
|
||||
desc: "test alpha hidden metric",
|
||||
metrics: []*Counter{alphaHiddenCounter},
|
||||
registryVersion: &v115,
|
||||
expectedErrors: []error{nil, prometheus.AlreadyRegisteredError{}},
|
||||
expectedErrors: []error{nil},
|
||||
expectedIsCreatedValues: []bool{false},
|
||||
expectedIsDeprecated: []bool{true},
|
||||
expectedIsHidden: []bool{true},
|
||||
@ -117,7 +108,7 @@ func TestRegister(t *testing.T) {
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
registry := newKubeRegistry(&apimachineryversion.Info{
|
||||
registry := NewKubeRegistry(&apimachineryversion.Info{
|
||||
Major: "1",
|
||||
Minor: "15",
|
||||
GitVersion: "v1.15.0-alpha-1.12345",
|
||||
@ -188,7 +179,7 @@ func TestMustRegister(t *testing.T) {
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
registry := newKubeRegistry(&apimachineryversion.Info{
|
||||
registry := NewKubeRegistry(&apimachineryversion.Info{
|
||||
Major: "1",
|
||||
Minor: "15",
|
||||
GitVersion: "v1.15.0-alpha-1.12345",
|
||||
|
Loading…
Reference in New Issue
Block a user