move files to component-base

This commit is contained in:
Han Kang 2019-05-03 10:57:49 -07:00
parent 634ab0be53
commit 04db3dc9f7
12 changed files with 105 additions and 61 deletions

View File

@ -34,9 +34,6 @@ filegroup(
filegroup( filegroup(
name = "all-srcs", name = "all-srcs",
srcs = [ srcs = [":package-srcs"],
":package-srcs",
"//pkg/util/metrics/framework:all-srcs",
],
tags = ["automanaged"], tags = ["automanaged"],
) )

View File

@ -13,6 +13,7 @@ filegroup(
"//staging/src/k8s.io/component-base/cli/globalflag:all-srcs", "//staging/src/k8s.io/component-base/cli/globalflag:all-srcs",
"//staging/src/k8s.io/component-base/config:all-srcs", "//staging/src/k8s.io/component-base/config:all-srcs",
"//staging/src/k8s.io/component-base/logs:all-srcs", "//staging/src/k8s.io/component-base/logs:all-srcs",
"//staging/src/k8s.io/component-base/metrics:all-srcs",
], ],
tags = ["automanaged"], tags = ["automanaged"],
visibility = ["//visibility:public"], visibility = ["//visibility:public"],

View File

@ -16,9 +16,9 @@ go_library(
"version_parser.go", "version_parser.go",
"wrappers.go", "wrappers.go",
], ],
importpath = "k8s.io/kubernetes/pkg/util/metrics/framework", importmap = "k8s.io/kubernetes/vendor/k8s.io/component-base/metrics",
importpath = "k8s.io/component-base/metrics",
deps = [ deps = [
"//pkg/version:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/version:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/version:go_default_library",
"//vendor/github.com/blang/semver:go_default_library", "//vendor/github.com/blang/semver:go_default_library",
"//vendor/github.com/prometheus/client_golang/prometheus:go_default_library", "//vendor/github.com/prometheus/client_golang/prometheus:go_default_library",

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package framework package metrics
import ( import (
"github.com/blang/semver" "github.com/blang/semver"

View File

@ -14,22 +14,22 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package framework package metrics
import ( import (
"bytes" "bytes"
"github.com/blang/semver" "github.com/blang/semver"
"github.com/prometheus/common/expfmt" "github.com/prometheus/common/expfmt"
apimachineryversion "k8s.io/apimachinery/pkg/version"
"testing" "testing"
) )
func TestCounter(t *testing.T) { func TestCounter(t *testing.T) {
v115 := semver.MustParse("1.15.0")
v114 := semver.MustParse("1.14.0") v114 := semver.MustParse("1.14.0")
v115 := semver.MustParse("1.15.0")
var tests = []struct { var tests = []struct {
desc string desc string
*CounterOpts *CounterOpts
registryVersion *semver.Version
expectedMetricCount int expectedMetricCount int
expectedHelp string expectedHelp string
}{ }{
@ -42,7 +42,6 @@ func TestCounter(t *testing.T) {
StabilityLevel: ALPHA, StabilityLevel: ALPHA,
Help: "counter help", Help: "counter help",
}, },
registryVersion: &v115,
expectedMetricCount: 1, expectedMetricCount: 1,
expectedHelp: "[ALPHA] counter help", expectedHelp: "[ALPHA] counter help",
}, },
@ -56,7 +55,6 @@ func TestCounter(t *testing.T) {
StabilityLevel: ALPHA, StabilityLevel: ALPHA,
DeprecatedVersion: &v115, DeprecatedVersion: &v115,
}, },
registryVersion: &v115,
expectedMetricCount: 1, expectedMetricCount: 1,
expectedHelp: "[ALPHA] (Deprecated since 1.15.0) counter help", expectedHelp: "[ALPHA] (Deprecated since 1.15.0) counter help",
}, },
@ -70,14 +68,17 @@ func TestCounter(t *testing.T) {
StabilityLevel: ALPHA, StabilityLevel: ALPHA,
DeprecatedVersion: &v114, DeprecatedVersion: &v114,
}, },
registryVersion: &v115,
expectedMetricCount: 0, expectedMetricCount: 0,
}, },
} }
for _, test := range tests { for _, test := range tests {
t.Run(test.desc, func(t *testing.T) { t.Run(test.desc, func(t *testing.T) {
registry := newKubeRegistry(*test.registryVersion) registry := newKubeRegistry(&apimachineryversion.Info{
Major: "1",
Minor: "15",
GitVersion: "v1.15.0-alpha-1.12345",
})
c := NewCounter(test.CounterOpts) c := NewCounter(test.CounterOpts)
registry.MustRegister(c) registry.MustRegister(c)
@ -141,7 +142,6 @@ func TestCounterVec(t *testing.T) {
Help: "counter help", Help: "counter help",
}, },
labels: []string{"label_a", "label_b"}, labels: []string{"label_a", "label_b"},
registryVersion: &v115,
expectedMetricFamilyCount: 1, expectedMetricFamilyCount: 1,
expectedHelp: "counter help", expectedHelp: "counter help",
}, },
@ -155,7 +155,6 @@ func TestCounterVec(t *testing.T) {
DeprecatedVersion: &v115, DeprecatedVersion: &v115,
}, },
labels: []string{"label_a", "label_b"}, labels: []string{"label_a", "label_b"},
registryVersion: &v115,
expectedMetricFamilyCount: 1, expectedMetricFamilyCount: 1,
expectedHelp: "(Deprecated since 1.15.0) counter help", expectedHelp: "(Deprecated since 1.15.0) counter help",
}, },
@ -169,7 +168,6 @@ func TestCounterVec(t *testing.T) {
DeprecatedVersion: &v114, DeprecatedVersion: &v114,
}, },
labels: []string{"label_a", "label_b"}, labels: []string{"label_a", "label_b"},
registryVersion: &v115,
expectedMetricFamilyCount: 0, expectedMetricFamilyCount: 0,
expectedHelp: "counter help", expectedHelp: "counter help",
}, },
@ -177,7 +175,11 @@ func TestCounterVec(t *testing.T) {
for _, test := range tests { for _, test := range tests {
t.Run(test.desc, func(t *testing.T) { t.Run(test.desc, func(t *testing.T) {
registry := newKubeRegistry(*test.registryVersion) registry := newKubeRegistry(&apimachineryversion.Info{
Major: "1",
Minor: "15",
GitVersion: "v1.15.0-alpha-1.12345",
})
c := NewCounterVec(test.CounterOpts, test.labels) c := NewCounterVec(test.CounterOpts, test.labels)
registry.MustRegister(c) registry.MustRegister(c)
c.WithLabelValues("1", "2").Inc() c.WithLabelValues("1", "2").Inc()

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package framework package metrics
import ( import (
"github.com/blang/semver" "github.com/blang/semver"

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package framework package metrics
import ( import (
"fmt" "fmt"

View File

@ -14,38 +14,72 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package framework package metrics
import ( import (
"github.com/blang/semver" "github.com/blang/semver"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
dto "github.com/prometheus/client_model/go" dto "github.com/prometheus/client_model/go"
"k8s.io/klog" apimachineryversion "k8s.io/apimachinery/pkg/version"
"k8s.io/kubernetes/pkg/version" "sync"
) )
// DefaultGlobalRegistry is a stub for the global registry which prometheus client var globalRegistryFactory = metricsRegistryFactory{
// currently uses. globalRegistry: &noopKubeRegistry{},
var DefaultGlobalRegistry = NewKubeRegistry() }
// KubeRegistry is a wrapper around a prometheus registry-type object. Upon initialization // 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 {
Register(KubeCollector) error
MustRegister(...KubeCollector)
Unregister(KubeCollector) bool
Gather() ([]*dto.MetricFamily, error)
}
// kubeRegistry is a wrapper around a prometheus registry-type object. Upon initialization
// the kubernetes binary version information is loaded into the registry object, so that // the kubernetes binary version information is loaded into the registry object, so that
// automatic behavior can be configured for metric versioning. // automatic behavior can be configured for metric versioning.
type KubeRegistry struct { type kubeRegistry struct {
PromRegistry PromRegistry
version semver.Version 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. // Register registers a collectable metric, but it uses a global registry.
func Register(c KubeCollector) error { func Register(c KubeCollector) error {
return DefaultGlobalRegistry.Register(c) return globalRegistryFactory.globalRegistry.Register(c)
} }
// MustRegister works like Register but registers any number of // MustRegister works like Register but registers any number of
// Collectors and panics upon the first registration that causes an // Collectors and panics upon the first registration that causes an
// error. // error.
func MustRegister(cs ...KubeCollector) { func MustRegister(cs ...KubeCollector) {
DefaultGlobalRegistry.MustRegister(cs...) globalRegistryFactory.globalRegistry.MustRegister(cs...)
} }
// Register registers a new Collector to be included in metrics // Register registers a new Collector to be included in metrics
@ -53,7 +87,7 @@ func MustRegister(cs ...KubeCollector) {
// Collector are invalid or if they — in combination with descriptors of // Collector are invalid or if they — in combination with descriptors of
// already registered Collectors — do not fulfill the consistency and // already registered Collectors — do not fulfill the consistency and
// uniqueness criteria described in the documentation of metric.Desc. // uniqueness criteria described in the documentation of metric.Desc.
func (kr *KubeRegistry) Register(c KubeCollector) error { func (kr *kubeRegistry) Register(c KubeCollector) error {
if c.Create(&kr.version) { if c.Create(&kr.version) {
return kr.PromRegistry.Register(c) return kr.PromRegistry.Register(c)
} }
@ -63,7 +97,7 @@ func (kr *KubeRegistry) Register(c KubeCollector) error {
// MustRegister works like Register but registers any number of // MustRegister works like Register but registers any number of
// Collectors and panics upon the first registration that causes an // Collectors and panics upon the first registration that causes an
// error. // error.
func (kr *KubeRegistry) MustRegister(cs ...KubeCollector) { func (kr *kubeRegistry) MustRegister(cs ...KubeCollector) {
metrics := make([]prometheus.Collector, 0, len(cs)) metrics := make([]prometheus.Collector, 0, len(cs))
for _, c := range cs { for _, c := range cs {
if c.Create(&kr.version) { if c.Create(&kr.version) {
@ -79,7 +113,7 @@ func (kr *KubeRegistry) MustRegister(cs ...KubeCollector) {
// returns whether a Collector was unregistered. Note that an unchecked // returns whether a Collector was unregistered. Note that an unchecked
// Collector cannot be unregistered (as its Describe method does not // Collector cannot be unregistered (as its Describe method does not
// yield any descriptor). // yield any descriptor).
func (kr *KubeRegistry) Unregister(collector KubeCollector) bool { func (kr *kubeRegistry) Unregister(collector KubeCollector) bool {
return kr.PromRegistry.Unregister(collector) return kr.PromRegistry.Unregister(collector)
} }
@ -90,28 +124,31 @@ func (kr *KubeRegistry) Unregister(collector KubeCollector) bool {
// for valid exposition. As an exception to the strict consistency // for valid exposition. As an exception to the strict consistency
// requirements described for metric.Desc, Gather will tolerate // requirements described for metric.Desc, Gather will tolerate
// different sets of label names for metrics of the same metric family. // different sets of label names for metrics of the same metric family.
func (kr *KubeRegistry) Gather() ([]*dto.MetricFamily, error) { func (kr *kubeRegistry) Gather() ([]*dto.MetricFamily, error) {
return kr.PromRegistry.Gather() return kr.PromRegistry.Gather()
} }
// NewKubeRegistry creates a new kubernetes metric registry, loading in the kubernetes // NewKubeRegistry creates a new kubernetes metric registry, loading in the kubernetes
// version information available to the binary. // version information available to the binary.
func NewKubeRegistry() *KubeRegistry { func NewKubeRegistry() KubeRegistry {
v, err := parseVersion(version.Get()) return globalRegistryFactory.newKubeRegistry()
if err != nil {
klog.Fatalf("Can't initialize a registry without a valid version %v", err)
}
if v == nil {
klog.Fatalf("No valid version loaded for metrics registry")
}
return newKubeRegistry(semver.MustParse(*v))
} }
// newKubeRegistry creates a new vanilla Registry without any Collectors // newKubeRegistry creates a new vanilla Registry without any Collectors
// pre-registered. // pre-registered.
func newKubeRegistry(version semver.Version) *KubeRegistry { func newKubeRegistry(v *apimachineryversion.Info) KubeRegistry {
return &KubeRegistry{ return &kubeRegistry{
PromRegistry: prometheus.NewRegistry(), PromRegistry: prometheus.NewRegistry(),
version: version, 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 }

View File

@ -14,12 +14,13 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package framework package metrics
import ( import (
"github.com/blang/semver" "github.com/blang/semver"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
apimachineryversion "k8s.io/apimachinery/pkg/version"
"testing" "testing"
) )
@ -116,7 +117,11 @@ func TestRegister(t *testing.T) {
for _, test := range tests { for _, test := range tests {
t.Run(test.desc, func(t *testing.T) { t.Run(test.desc, func(t *testing.T) {
registry := newKubeRegistry(*test.registryVersion) registry := newKubeRegistry(&apimachineryversion.Info{
Major: "1",
Minor: "15",
GitVersion: "v1.15.0-alpha-1.12345",
})
for i, m := range test.metrics { for i, m := range test.metrics {
err := registry.Register(m) err := registry.Register(m)
if err != test.expectedErrors[i] && err.Error() != test.expectedErrors[i].Error() { if err != test.expectedErrors[i] && err.Error() != test.expectedErrors[i].Error() {
@ -183,7 +188,11 @@ func TestMustRegister(t *testing.T) {
for _, test := range tests { for _, test := range tests {
t.Run(test.desc, func(t *testing.T) { t.Run(test.desc, func(t *testing.T) {
registry := newKubeRegistry(*test.registryVersion) registry := newKubeRegistry(&apimachineryversion.Info{
Major: "1",
Minor: "15",
GitVersion: "v1.15.0-alpha-1.12345",
})
for i, m := range test.metrics { for i, m := range test.metrics {
if test.expectedPanics[i] { if test.expectedPanics[i] {
assert.Panics(t, assert.Panics(t,

View File

@ -14,10 +14,11 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package framework package metrics
import ( import (
"fmt" "fmt"
"github.com/blang/semver"
apimachineryversion "k8s.io/apimachinery/pkg/version" apimachineryversion "k8s.io/apimachinery/pkg/version"
"regexp" "regexp"
) )
@ -30,11 +31,11 @@ var (
versionRe = regexp.MustCompile(versionRegexpString) versionRe = regexp.MustCompile(versionRegexpString)
) )
func parseVersion(ver apimachineryversion.Info) (*string, error) { func parseVersion(ver apimachineryversion.Info) semver.Version {
matches := versionRe.FindAllStringSubmatch(ver.String(), -1) matches := versionRe.FindAllStringSubmatch(ver.String(), -1)
if len(matches) != 1 { if len(matches) != 1 {
return nil, fmt.Errorf("version string \"%v\" doesn't match expected regular expression: \"%v\"", ver.String(), versionRe.String()) panic(fmt.Sprintf("version string \"%v\" doesn't match expected regular expression: \"%v\"", ver.String(), versionRe.String()))
} }
return &matches[0][1], nil return semver.MustParse(matches[0][1])
} }

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package framework package metrics
import ( import (
apimachineryversion "k8s.io/apimachinery/pkg/version" apimachineryversion "k8s.io/apimachinery/pkg/version"
@ -44,12 +44,9 @@ func TestVersionParsing(t *testing.T) {
version := apimachineryversion.Info{ version := apimachineryversion.Info{
GitVersion: test.versionString, GitVersion: test.versionString,
} }
parsedV, err := parseVersion(version) parsedV := parseVersion(version)
if err != nil { if test.expectedVersion != parsedV.String() {
t.Fatalf("Should be able to parse %v", version) t.Errorf("Got %v, wanted %v", parsedV.String(), test.expectedVersion)
}
if test.expectedVersion != *parsedV {
t.Errorf("Got %v, wanted %v", *parsedV, test.expectedVersion)
} }
}) })
} }

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package framework package metrics
import ( import (
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"