Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
634ab0be
Commit
634ab0be
authored
May 01, 2019
by
Han Kang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add additional documentation around exposed functionality
parent
e6fbb593
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
93 additions
and
54 deletions
+93
-54
counter.go
pkg/util/metrics/framework/counter.go
+33
-27
metric.go
pkg/util/metrics/framework/metric.go
+1
-1
opts.go
pkg/util/metrics/framework/opts.go
+7
-1
registry.go
pkg/util/metrics/framework/registry.go
+28
-0
registry_test.go
pkg/util/metrics/framework/registry_test.go
+12
-12
wrappers.go
pkg/util/metrics/framework/wrappers.go
+12
-13
No files found.
pkg/util/metrics/framework/counter.go
View file @
634ab0be
...
...
@@ -21,24 +21,24 @@ import (
"github.com/prometheus/client_golang/prometheus"
)
//
kube
Counter is our internal representation for our wrapping struct around prometheus
// counters.
kubeCounter implements both KubeCollector and KubeCounter
.
type
kube
Counter
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
)
*
kube
Counter
{
func
NewCounter
(
opts
*
CounterOpts
)
*
Counter
{
// todo: handle defaulting better
if
opts
.
StabilityLevel
==
""
{
opts
.
StabilityLevel
=
ALPHA
}
kc
:=
&
kube
Counter
{
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
*
kube
Counter
)
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
*
kube
Counter
)
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
*
kube
Counter
)
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
*
kube
Counter
)
initializeDeprecatedMetric
()
{
func
(
c
*
Counter
)
initializeDeprecatedMetric
()
{
c
.
CounterOpts
.
markDeprecated
()
c
.
initializeMetric
()
}
//
kube
CounterVec is the internal representation of our wrapping struct around prometheus
// counterVecs.
kubeCounterVec implements both KubeCollector and KubeCounterVe
c.
type
kube
CounterVec
struct
{
// CounterVec is the internal representation of our wrapping struct around prometheus
// counterVecs.
CounterVec implements both KubeCollector and CounterVecMetri
c.
type
CounterVec
struct
{
*
prometheus
.
CounterVec
*
CounterOpts
lazyMetric
originalLabels
[]
string
}
// NewCounterVec returns an object which satisfies the KubeCollector and
KubeCounterVe
c interfaces.
// NewCounterVec returns an object which satisfies the KubeCollector and
CounterVecMetri
c 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
)
*
kube
CounterVec
{
cv
:=
&
kube
CounterVec
{
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
*
kube
CounterVec
)
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
*
kube
CounterVec
)
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
*
kube
CounterVec
)
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
}
...
...
pkg/util/metrics/framework/metric.go
View file @
634ab0be
...
...
@@ -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.
...
...
pkg/util/metrics/framework/opts.go
View file @
634ab0be
...
...
@@ -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.
...
...
pkg/util/metrics/framework/registry.go
View file @
634ab0be
...
...
@@ -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
{
...
...
pkg/util/metrics/framework/registry_test.go
View file @
634ab0be
...
...
@@ -69,7 +69,7 @@ var (
func
TestRegister
(
t
*
testing
.
T
)
{
var
tests
=
[]
struct
{
desc
string
metrics
[]
*
kube
Counter
metrics
[]
*
Counter
registryVersion
*
semver
.
Version
expectedErrors
[]
error
expectedIsCreatedValues
[]
bool
...
...
@@ -78,7 +78,7 @@ func TestRegister(t *testing.T) {
}{
{
desc
:
"test alpha metric"
,
metrics
:
[]
*
kube
Counter
{
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
:
[]
*
kube
Counter
{
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
:
[]
*
kube
Counter
{
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
:
[]
*
kube
Counter
{
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
[]
*
kube
Counter
metrics
[]
*
Counter
registryVersion
*
semver
.
Version
expectedPanics
[]
bool
}{
{
desc
:
"test alpha metric"
,
metrics
:
[]
*
kube
Counter
{
alphaCounter
},
metrics
:
[]
*
Counter
{
alphaCounter
},
registryVersion
:
&
v115
,
expectedPanics
:
[]
bool
{
false
},
},
{
desc
:
"test registering same metric multiple times"
,
metrics
:
[]
*
kube
Counter
{
alphaCounter
,
alphaCounter
},
metrics
:
[]
*
Counter
{
alphaCounter
,
alphaCounter
},
registryVersion
:
&
v115
,
expectedPanics
:
[]
bool
{
false
,
true
},
},
{
desc
:
"test alpha deprecated metric"
,
metrics
:
[]
*
kube
Counter
{
alphaDeprecatedCounter
},
metrics
:
[]
*
Counter
{
alphaDeprecatedCounter
},
registryVersion
:
&
v115
,
expectedPanics
:
[]
bool
{
false
},
},
{
desc
:
"test must registering same deprecated metric"
,
metrics
:
[]
*
kube
Counter
{
alphaDeprecatedCounter
,
alphaDeprecatedCounter
},
metrics
:
[]
*
Counter
{
alphaDeprecatedCounter
,
alphaDeprecatedCounter
},
registryVersion
:
&
v115
,
expectedPanics
:
[]
bool
{
false
,
true
},
},
{
desc
:
"test alpha hidden metric"
,
metrics
:
[]
*
kube
Counter
{
alphaHiddenCounter
},
metrics
:
[]
*
Counter
{
alphaHiddenCounter
},
registryVersion
:
&
v115
,
expectedPanics
:
[]
bool
{
false
},
},
{
desc
:
"test must registering same hidden metric"
,
metrics
:
[]
*
kube
Counter
{
alphaHiddenCounter
,
alphaHiddenCounter
},
metrics
:
[]
*
Counter
{
alphaHiddenCounter
,
alphaHiddenCounter
},
registryVersion
:
&
v115
,
expectedPanics
:
[]
bool
{
false
,
false
},
// hidden metrics no-opt
},
...
...
pkg/util/metrics/framework/wrappers.go
View file @
634ab0be
...
...
@@ -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
// Counter
Metric
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
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment