mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-31 23:37:01 +00:00
add additional documentation around exposed functionality
This commit is contained in:
parent
e6fbb593bb
commit
634ab0be53
@ -21,24 +21,24 @@ import (
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
// kubeCounter is our internal representation for our wrapping struct around prometheus
|
||||
// counters. kubeCounter implements both KubeCollector and KubeCounter.
|
||||
type kubeCounter struct {
|
||||
KubeCounter
|
||||
// Counter is our internal representation for our wrapping struct around prometheus
|
||||
// counters. Counter implements both KubeCollector and CounterMetric.
|
||||
type Counter struct {
|
||||
CounterMetric
|
||||
*CounterOpts
|
||||
lazyMetric
|
||||
selfCollector
|
||||
}
|
||||
|
||||
// NewCounter returns an object which satisfies the KubeCollector and KubeCounter 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) *kubeCounter {
|
||||
func NewCounter(opts *CounterOpts) *Counter {
|
||||
// todo: handle defaulting better
|
||||
if opts.StabilityLevel == "" {
|
||||
opts.StabilityLevel = ALPHA
|
||||
}
|
||||
kc := &kubeCounter{
|
||||
kc := &Counter{
|
||||
CounterOpts: opts,
|
||||
lazyMetric: lazyMetric{},
|
||||
}
|
||||
@ -47,20 +47,20 @@ func NewCounter(opts *CounterOpts) *kubeCounter {
|
||||
return kc
|
||||
}
|
||||
|
||||
// setPrometheusCounter sets the underlying KubeCounter object, i.e. the thing that does the measurement.
|
||||
func (c *kubeCounter) setPrometheusCounter(counter prometheus.Counter) {
|
||||
c.KubeCounter = counter
|
||||
// setPrometheusCounter sets the underlying CounterMetric object, i.e. the thing that does the measurement.
|
||||
func (c *Counter) setPrometheusCounter(counter prometheus.Counter) {
|
||||
c.CounterMetric = counter
|
||||
c.initSelfCollection(counter)
|
||||
}
|
||||
|
||||
// DeprecatedVersion returns a pointer to the Version or nil
|
||||
func (c *kubeCounter) DeprecatedVersion() *semver.Version {
|
||||
func (c *Counter) DeprecatedVersion() *semver.Version {
|
||||
return c.CounterOpts.DeprecatedVersion
|
||||
}
|
||||
|
||||
// initializeMetric invocation creates the actual underlying Counter. Until this method is called
|
||||
// the underlying counter is a no-op.
|
||||
func (c *kubeCounter) initializeMetric() {
|
||||
func (c *Counter) initializeMetric() {
|
||||
c.CounterOpts.annotateStabilityLevel()
|
||||
// this actually creates the underlying prometheus counter.
|
||||
c.setPrometheusCounter(prometheus.NewCounter(c.CounterOpts.toPromCounterOpts()))
|
||||
@ -68,25 +68,25 @@ func (c *kubeCounter) initializeMetric() {
|
||||
|
||||
// initializeDeprecatedMetric invocation creates the actual (but deprecated) Counter. Until this method
|
||||
// is called the underlying counter is a no-op.
|
||||
func (c *kubeCounter) initializeDeprecatedMetric() {
|
||||
func (c *Counter) initializeDeprecatedMetric() {
|
||||
c.CounterOpts.markDeprecated()
|
||||
c.initializeMetric()
|
||||
}
|
||||
|
||||
// kubeCounterVec is the internal representation of our wrapping struct around prometheus
|
||||
// counterVecs. kubeCounterVec implements both KubeCollector and KubeCounterVec.
|
||||
type kubeCounterVec struct {
|
||||
// CounterVec is the internal representation of our wrapping struct around prometheus
|
||||
// counterVecs. CounterVec implements both KubeCollector and CounterVecMetric.
|
||||
type CounterVec struct {
|
||||
*prometheus.CounterVec
|
||||
*CounterOpts
|
||||
lazyMetric
|
||||
originalLabels []string
|
||||
}
|
||||
|
||||
// NewCounterVec returns an object which satisfies the KubeCollector and KubeCounterVec 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) *kubeCounterVec {
|
||||
cv := &kubeCounterVec{
|
||||
func NewCounterVec(opts *CounterOpts, labels []string) *CounterVec {
|
||||
cv := &CounterVec{
|
||||
CounterVec: noopCounterVec,
|
||||
CounterOpts: opts,
|
||||
originalLabels: labels,
|
||||
@ -97,19 +97,19 @@ func NewCounterVec(opts *CounterOpts, labels []string) *kubeCounterVec {
|
||||
}
|
||||
|
||||
// DeprecatedVersion returns a pointer to the Version or nil
|
||||
func (v *kubeCounterVec) DeprecatedVersion() *semver.Version {
|
||||
func (v *CounterVec) DeprecatedVersion() *semver.Version {
|
||||
return v.CounterOpts.DeprecatedVersion
|
||||
}
|
||||
|
||||
// initializeMetric invocation creates the actual underlying CounterVec. Until this method is called
|
||||
// the underlying counterVec is a no-op.
|
||||
func (v *kubeCounterVec) initializeMetric() {
|
||||
func (v *CounterVec) initializeMetric() {
|
||||
v.CounterVec = prometheus.NewCounterVec(v.CounterOpts.toPromCounterOpts(), v.originalLabels)
|
||||
}
|
||||
|
||||
// initializeDeprecatedMetric invocation creates the actual (but deprecated) CounterVec. Until this method is called
|
||||
// the underlying counterVec is a no-op.
|
||||
func (v *kubeCounterVec) initializeDeprecatedMetric() {
|
||||
func (v *CounterVec) initializeDeprecatedMetric() {
|
||||
v.CounterOpts.markDeprecated()
|
||||
v.initializeMetric()
|
||||
}
|
||||
@ -121,17 +121,23 @@ func (v *kubeCounterVec) initializeDeprecatedMetric() {
|
||||
// for perpetuity (i.e. throughout application lifecycle).
|
||||
//
|
||||
// For reference: https://github.com/prometheus/client_golang/blob/v0.9.2/prometheus/counter.go#L179-L197
|
||||
//
|
||||
// This method returns a no-op metric if the metric is not actually created/registered, avoiding that
|
||||
// memory leak.
|
||||
func (v *kubeCounterVec) WithLabelValues(lvs ...string) KubeCounter {
|
||||
|
||||
// WithLabelValues returns the Counter for the given slice of label
|
||||
// values (same order as the VariableLabels in Desc). If that combination of
|
||||
// label values is accessed for the first time, a new Counter is created IFF the counterVec
|
||||
// has been registered to a metrics registry.
|
||||
func (v *CounterVec) WithLabelValues(lvs ...string) CounterMetric {
|
||||
if !v.IsCreated() {
|
||||
return noop // return no-op counter
|
||||
}
|
||||
return v.CounterVec.WithLabelValues(lvs...)
|
||||
}
|
||||
|
||||
func (v *kubeCounterVec) With(labels prometheus.Labels) KubeCounter {
|
||||
// With returns the Counter for the given Labels map (the label names
|
||||
// must match those of the VariableLabels in Desc). If that label map is
|
||||
// accessed for the first time, a new Counter is created IFF the counterVec has
|
||||
// been registered to a metrics registry.
|
||||
func (v *CounterVec) With(labels prometheus.Labels) CounterMetric {
|
||||
if !v.IsCreated() {
|
||||
return noop // return no-op counter
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ import (
|
||||
)
|
||||
|
||||
/*
|
||||
This 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.
|
||||
|
@ -41,13 +41,19 @@ type KubeOpts struct {
|
||||
StabilityLevel StabilityLevel
|
||||
}
|
||||
|
||||
// StabilityLevel represents the API guarantees for a given defined metric.
|
||||
type StabilityLevel string
|
||||
|
||||
const (
|
||||
ALPHA StabilityLevel = "ALPHA"
|
||||
// ALPHA metrics have no stability guarantees, as such, labels may
|
||||
// be arbitrarily added/removed and the metric may be deleted at any time.
|
||||
ALPHA StabilityLevel = "ALPHA"
|
||||
// STABLE metrics are guaranteed not be mutated and removal is governed by
|
||||
// the deprecation policy outlined in by the control plane metrics stability KEP.
|
||||
STABLE StabilityLevel = "STABLE"
|
||||
)
|
||||
|
||||
// CounterOpts is an alias for Opts. See there for doc comments.
|
||||
type CounterOpts KubeOpts
|
||||
|
||||
// Modify help description on the metric description.
|
||||
|
@ -24,8 +24,13 @@ import (
|
||||
"k8s.io/kubernetes/pkg/version"
|
||||
)
|
||||
|
||||
// DefaultGlobalRegistry is a stub for the global registry which prometheus client
|
||||
// currently uses.
|
||||
var DefaultGlobalRegistry = NewKubeRegistry()
|
||||
|
||||
// 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
|
||||
// automatic behavior can be configured for metric versioning.
|
||||
type KubeRegistry struct {
|
||||
PromRegistry
|
||||
version semver.Version
|
||||
@ -43,6 +48,11 @@ func MustRegister(cs ...KubeCollector) {
|
||||
DefaultGlobalRegistry.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
|
||||
// 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 {
|
||||
if c.Create(&kr.version) {
|
||||
return kr.PromRegistry.Register(c)
|
||||
@ -50,6 +60,9 @@ func (kr *KubeRegistry) Register(c KubeCollector) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 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) {
|
||||
metrics := make([]prometheus.Collector, 0, len(cs))
|
||||
for _, c := range cs {
|
||||
@ -60,14 +73,29 @@ func (kr *KubeRegistry) MustRegister(cs ...KubeCollector) {
|
||||
kr.PromRegistry.MustRegister(metrics...)
|
||||
}
|
||||
|
||||
// Unregister unregisters the Collector that equals the Collector passed
|
||||
// in as an argument. (Two Collectors are considered equal if their
|
||||
// Describe method yields the same set of descriptors.) The function
|
||||
// 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 {
|
||||
return kr.PromRegistry.Unregister(collector)
|
||||
}
|
||||
|
||||
// Gather calls the Collect method of the registered Collectors and then
|
||||
// gathers the collected metrics into a lexicographically sorted slice
|
||||
// of uniquely named MetricFamily protobufs. Gather ensures that the
|
||||
// returned slice is valid and self-consistent so that it can be used
|
||||
// for valid exposition. As an exception to the strict consistency
|
||||
// requirements described for metric.Desc, Gather will tolerate
|
||||
// different sets of label names for metrics of the same metric family.
|
||||
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 {
|
||||
v, err := parseVersion(version.Get())
|
||||
if err != nil {
|
||||
|
@ -69,7 +69,7 @@ var (
|
||||
func TestRegister(t *testing.T) {
|
||||
var tests = []struct {
|
||||
desc string
|
||||
metrics []*kubeCounter
|
||||
metrics []*Counter
|
||||
registryVersion *semver.Version
|
||||
expectedErrors []error
|
||||
expectedIsCreatedValues []bool
|
||||
@ -78,7 +78,7 @@ func TestRegister(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
desc: "test alpha metric",
|
||||
metrics: []*kubeCounter{alphaCounter},
|
||||
metrics: []*Counter{alphaCounter},
|
||||
registryVersion: &v115,
|
||||
expectedErrors: []error{nil},
|
||||
expectedIsCreatedValues: []bool{true},
|
||||
@ -87,7 +87,7 @@ func TestRegister(t *testing.T) {
|
||||
},
|
||||
{
|
||||
desc: "test registering same metric multiple times",
|
||||
metrics: []*kubeCounter{alphaCounter, alphaCounter},
|
||||
metrics: []*Counter{alphaCounter, alphaCounter},
|
||||
registryVersion: &v115,
|
||||
expectedErrors: []error{nil, prometheus.AlreadyRegisteredError{}},
|
||||
expectedIsCreatedValues: []bool{true, true},
|
||||
@ -96,7 +96,7 @@ func TestRegister(t *testing.T) {
|
||||
},
|
||||
{
|
||||
desc: "test alpha deprecated metric",
|
||||
metrics: []*kubeCounter{alphaDeprecatedCounter},
|
||||
metrics: []*Counter{alphaDeprecatedCounter},
|
||||
registryVersion: &v115,
|
||||
expectedErrors: []error{nil, prometheus.AlreadyRegisteredError{}},
|
||||
expectedIsCreatedValues: []bool{true},
|
||||
@ -105,7 +105,7 @@ func TestRegister(t *testing.T) {
|
||||
},
|
||||
{
|
||||
desc: "test alpha hidden metric",
|
||||
metrics: []*kubeCounter{alphaHiddenCounter},
|
||||
metrics: []*Counter{alphaHiddenCounter},
|
||||
registryVersion: &v115,
|
||||
expectedErrors: []error{nil, prometheus.AlreadyRegisteredError{}},
|
||||
expectedIsCreatedValues: []bool{false},
|
||||
@ -139,43 +139,43 @@ func TestRegister(t *testing.T) {
|
||||
func TestMustRegister(t *testing.T) {
|
||||
var tests = []struct {
|
||||
desc string
|
||||
metrics []*kubeCounter
|
||||
metrics []*Counter
|
||||
registryVersion *semver.Version
|
||||
expectedPanics []bool
|
||||
}{
|
||||
{
|
||||
desc: "test alpha metric",
|
||||
metrics: []*kubeCounter{alphaCounter},
|
||||
metrics: []*Counter{alphaCounter},
|
||||
registryVersion: &v115,
|
||||
expectedPanics: []bool{false},
|
||||
},
|
||||
{
|
||||
desc: "test registering same metric multiple times",
|
||||
metrics: []*kubeCounter{alphaCounter, alphaCounter},
|
||||
metrics: []*Counter{alphaCounter, alphaCounter},
|
||||
registryVersion: &v115,
|
||||
expectedPanics: []bool{false, true},
|
||||
},
|
||||
{
|
||||
desc: "test alpha deprecated metric",
|
||||
metrics: []*kubeCounter{alphaDeprecatedCounter},
|
||||
metrics: []*Counter{alphaDeprecatedCounter},
|
||||
registryVersion: &v115,
|
||||
expectedPanics: []bool{false},
|
||||
},
|
||||
{
|
||||
desc: "test must registering same deprecated metric",
|
||||
metrics: []*kubeCounter{alphaDeprecatedCounter, alphaDeprecatedCounter},
|
||||
metrics: []*Counter{alphaDeprecatedCounter, alphaDeprecatedCounter},
|
||||
registryVersion: &v115,
|
||||
expectedPanics: []bool{false, true},
|
||||
},
|
||||
{
|
||||
desc: "test alpha hidden metric",
|
||||
metrics: []*kubeCounter{alphaHiddenCounter},
|
||||
metrics: []*Counter{alphaHiddenCounter},
|
||||
registryVersion: &v115,
|
||||
expectedPanics: []bool{false},
|
||||
},
|
||||
{
|
||||
desc: "test must registering same hidden metric",
|
||||
metrics: []*kubeCounter{alphaHiddenCounter, alphaHiddenCounter},
|
||||
metrics: []*Counter{alphaHiddenCounter, alphaHiddenCounter},
|
||||
registryVersion: &v115,
|
||||
expectedPanics: []bool{false, false}, // hidden metrics no-opt
|
||||
},
|
||||
|
@ -27,38 +27,37 @@ import (
|
||||
// so that we can prevent breakage if methods are ever added to prometheus
|
||||
// variants of them.
|
||||
|
||||
/**
|
||||
* Collector defines a subset of prometheus.Collector interface methods
|
||||
*/
|
||||
// Collector defines a subset of prometheus.Collector interface methods
|
||||
type Collector interface {
|
||||
Describe(chan<- *prometheus.Desc)
|
||||
Collect(chan<- prometheus.Metric)
|
||||
}
|
||||
|
||||
/**
|
||||
* Metric defines a subset of prometheus.Metric interface methods
|
||||
*/
|
||||
// Metric defines a subset of prometheus.Metric interface methods
|
||||
type Metric interface {
|
||||
Desc() *prometheus.Desc
|
||||
Write(*dto.Metric) error
|
||||
}
|
||||
|
||||
// Counter is a Metric that represents a single numerical value that only ever
|
||||
// CounterMetric is a Metric that represents a single numerical value that only ever
|
||||
// goes up. That implies that it cannot be used to count items whose number can
|
||||
// also go down, e.g. the number of currently running goroutines. Those
|
||||
// "counters" are represented by Gauges.
|
||||
//
|
||||
// This interface defines a subset of the interface provided by prometheus.Counter
|
||||
type KubeCounter interface {
|
||||
|
||||
// CounterMetric is an interface which defines a subset of the interface provided by prometheus.Counter
|
||||
type CounterMetric interface {
|
||||
Inc()
|
||||
Add(float64)
|
||||
}
|
||||
|
||||
type KubeCounterVec interface {
|
||||
WithLabelValues(...string) KubeCounter
|
||||
With(prometheus.Labels) KubeCounter
|
||||
// CounterVecMetric is an interface which prometheus.CounterVec satisfies.
|
||||
type CounterVecMetric interface {
|
||||
WithLabelValues(...string) CounterMetric
|
||||
With(prometheus.Labels) CounterMetric
|
||||
}
|
||||
|
||||
// PromRegistry is an interface which implements a subset of prometheus.Registerer and
|
||||
// prometheus.Gatherer interfaces
|
||||
type PromRegistry interface {
|
||||
Register(prometheus.Collector) error
|
||||
MustRegister(...prometheus.Collector)
|
||||
|
Loading…
Reference in New Issue
Block a user