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
cebad0da
Commit
cebad0da
authored
Apr 25, 2019
by
Han Kang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
make method names more succinct, improve documentation for posterity
parent
cf181cdd
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
58 additions
and
53 deletions
+58
-53
counter.go
pkg/util/metrics/counter.go
+18
-14
counter_test.go
pkg/util/metrics/counter_test.go
+3
-3
metric.go
pkg/util/metrics/metric.go
+32
-31
opts.go
pkg/util/metrics/opts.go
+3
-3
registry.go
pkg/util/metrics/registry.go
+2
-2
No files found.
pkg/util/metrics/counter.go
View file @
cebad0da
...
@@ -53,13 +53,13 @@ func (c *kubeCounter) setPrometheusCounter(counter prometheus.Counter) {
...
@@ -53,13 +53,13 @@ func (c *kubeCounter) setPrometheusCounter(counter prometheus.Counter) {
c
.
initSelfCollection
(
counter
)
c
.
initSelfCollection
(
counter
)
}
}
//
Get
DeprecatedVersion returns a pointer to the Version or nil
// DeprecatedVersion returns a pointer to the Version or nil
func
(
c
*
kubeCounter
)
Get
DeprecatedVersion
()
*
semver
.
Version
{
func
(
c
*
kubeCounter
)
DeprecatedVersion
()
*
semver
.
Version
{
return
c
.
CounterOpts
.
DeprecatedVersion
return
c
.
CounterOpts
.
DeprecatedVersion
}
}
// initializeMetric invocation creates the actual underlying Counter. Until this method is called
// initializeMetric invocation creates the actual underlying Counter. Until this method is called
//
our
underlying counter is a no-op.
//
the
underlying counter is a no-op.
func
(
c
*
kubeCounter
)
initializeMetric
()
{
func
(
c
*
kubeCounter
)
initializeMetric
()
{
c
.
CounterOpts
.
annotateStabilityLevel
()
c
.
CounterOpts
.
annotateStabilityLevel
()
// this actually creates the underlying prometheus counter.
// this actually creates the underlying prometheus counter.
...
@@ -67,13 +67,13 @@ func (c *kubeCounter) initializeMetric() {
...
@@ -67,13 +67,13 @@ func (c *kubeCounter) initializeMetric() {
}
}
// initializeDeprecatedMetric invocation creates the actual (but deprecated) Counter. Until this method
// initializeDeprecatedMetric invocation creates the actual (but deprecated) Counter. Until this method
// is called
our
underlying counter is a no-op.
// is called
the
underlying counter is a no-op.
func
(
c
*
kubeCounter
)
initializeDeprecatedMetric
()
{
func
(
c
*
kubeCounter
)
initializeDeprecatedMetric
()
{
c
.
CounterOpts
.
markDeprecated
()
c
.
CounterOpts
.
markDeprecated
()
c
.
initializeMetric
()
c
.
initializeMetric
()
}
}
// kubeCounterVec is
our
internal representation of our wrapping struct around prometheus
// kubeCounterVec is
the
internal representation of our wrapping struct around prometheus
// counterVecs. kubeCounterVec implements both KubeCollector and KubeCounterVec.
// counterVecs. kubeCounterVec implements both KubeCollector and KubeCounterVec.
type
kubeCounterVec
struct
{
type
kubeCounterVec
struct
{
*
prometheus
.
CounterVec
*
prometheus
.
CounterVec
...
@@ -96,30 +96,34 @@ func NewCounterVec(opts CounterOpts, labels []string) *kubeCounterVec {
...
@@ -96,30 +96,34 @@ func NewCounterVec(opts CounterOpts, labels []string) *kubeCounterVec {
return
cv
return
cv
}
}
//
Get
DeprecatedVersion returns a pointer to the Version or nil
// DeprecatedVersion returns a pointer to the Version or nil
func
(
v
*
kubeCounterVec
)
Get
DeprecatedVersion
()
*
semver
.
Version
{
func
(
v
*
kubeCounterVec
)
DeprecatedVersion
()
*
semver
.
Version
{
return
v
.
CounterOpts
.
DeprecatedVersion
return
v
.
CounterOpts
.
DeprecatedVersion
}
}
// initializeMetric invocation creates the actual underlying CounterVec. Until this method is called
// initializeMetric invocation creates the actual underlying CounterVec. Until this method is called
//
our
underlying counterVec is a no-op.
//
the
underlying counterVec is a no-op.
func
(
v
*
kubeCounterVec
)
initializeMetric
()
{
func
(
v
*
kubeCounterVec
)
initializeMetric
()
{
v
.
CounterVec
=
prometheus
.
NewCounterVec
(
v
.
CounterOpts
.
toPromCounterOpts
(),
v
.
originalLabels
)
v
.
CounterVec
=
prometheus
.
NewCounterVec
(
v
.
CounterOpts
.
toPromCounterOpts
(),
v
.
originalLabels
)
}
}
// initializeMetric invocation creates the actual (but deprecated) CounterVec. Until this method is called
// initialize
Deprecated
Metric invocation creates the actual (but deprecated) CounterVec. Until this method is called
//
our
underlying counterVec is a no-op.
//
the
underlying counterVec is a no-op.
func
(
v
*
kubeCounterVec
)
initializeDeprecatedMetric
()
{
func
(
v
*
kubeCounterVec
)
initializeDeprecatedMetric
()
{
v
.
CounterOpts
.
markDeprecated
()
v
.
CounterOpts
.
markDeprecated
()
v
.
initializeMetric
()
v
.
initializeMetric
()
}
}
// Default Prometheus behavior actually results in the creation of a new metric
// Default Prometheus behavior actually results in the creation of a new metric
// if a metric with the unique label values is not found in the underlying stored metricMap. This
// if a metric with the unique label values is not found in the underlying stored metricMap.
// is undesirable for us, since we want a way to turn OFF metrics which end up turning into memory
// This means that if this function is called but the underlying metric is not registered
// leaks.
// (which means it will never be exposed externally nor consumed), the metric will exist in memory
// for perpetuity (i.e. throughout application lifecycle).
//
//
// For reference: https://github.com/prometheus/client_golang/blob/master/prometheus/counter.go#L148-L177
// 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
{
func
(
v
*
kubeCounterVec
)
WithLabelValues
(
lvs
...
string
)
KubeCounter
{
if
!
v
.
IsCreated
()
{
if
!
v
.
IsCreated
()
{
return
noop
// return no-op counter
return
noop
// return no-op counter
...
...
pkg/util/metrics/counter_test.go
View file @
cebad0da
...
@@ -101,7 +101,7 @@ func TestCounter(t *testing.T) {
...
@@ -101,7 +101,7 @@ func TestCounter(t *testing.T) {
}
}
}
}
//
let's
increment the counter N number of times and verify that the metric retains the count correctly
// increment the counter N number of times and verify that the metric retains the count correctly
numberOfTimesToIncrement
:=
3
numberOfTimesToIncrement
:=
3
for
i
:=
0
;
i
<
numberOfTimesToIncrement
;
i
++
{
for
i
:=
0
;
i
<
numberOfTimesToIncrement
;
i
++
{
c
.
Inc
()
c
.
Inc
()
...
@@ -188,7 +188,7 @@ func TestCounterVec(t *testing.T) {
...
@@ -188,7 +188,7 @@ func TestCounterVec(t *testing.T) {
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Fatalf
(
"Gather failed %v"
,
err
)
t
.
Fatalf
(
"Gather failed %v"
,
err
)
}
}
//
we no-opt here when we don't have any
metric families (i.e. when the metric is hidden)
//
this no-opts here when there are no
metric families (i.e. when the metric is hidden)
for
_
,
mf
:=
range
mfs
{
for
_
,
mf
:=
range
mfs
{
if
len
(
mf
.
GetMetric
())
!=
1
{
if
len
(
mf
.
GetMetric
())
!=
1
{
t
.
Errorf
(
"Got %v metrics, wanted 1 as the count"
,
len
(
mf
.
GetMetric
()))
t
.
Errorf
(
"Got %v metrics, wanted 1 as the count"
,
len
(
mf
.
GetMetric
()))
...
@@ -206,7 +206,7 @@ func TestCounterVec(t *testing.T) {
...
@@ -206,7 +206,7 @@ func TestCounterVec(t *testing.T) {
t
.
Fatalf
(
"Gather failed %v"
,
err
)
t
.
Fatalf
(
"Gather failed %v"
,
err
)
}
}
//
we no-opt here when we don't have any
metric families (i.e. when the metric is hidden)
//
this no-opts here when there are no
metric families (i.e. when the metric is hidden)
for
_
,
mf
:=
range
mfs
{
for
_
,
mf
:=
range
mfs
{
if
len
(
mf
.
GetMetric
())
!=
3
{
if
len
(
mf
.
GetMetric
())
!=
3
{
t
.
Errorf
(
"Got %v metrics, wanted 3 as the count"
,
len
(
mf
.
GetMetric
()))
t
.
Errorf
(
"Got %v metrics, wanted 3 as the count"
,
len
(
mf
.
GetMetric
()))
...
...
pkg/util/metrics/metric.go
View file @
cebad0da
...
@@ -24,39 +24,41 @@ import (
...
@@ -24,39 +24,41 @@ import (
"sync"
"sync"
)
)
/*
*
/*
* This extends the prometheus.Collector interface so that we can customize
the metric
This extends the prometheus.Collector interface to allow customization of
the metric
* registration process. Specifically, we defer metric initialization until ActuallyCreate
registration process. Defer metric initialization until Create() is called, which then
* is called, which then delegates to the underlying metric's initializeMetric or
delegates to the underlying metric's initializeMetric or initializeDeprecatedMetric
* initializeDeprecatedMetric
method call depending on whether the metric is deprecated or not.
method call depending on whether the metric is deprecated or not.
*/
*/
type
KubeCollector
interface
{
type
KubeCollector
interface
{
Collector
Collector
LazyMetric
LazyMetric
Get
DeprecatedVersion
()
*
semver
.
Version
DeprecatedVersion
()
*
semver
.
Version
// Each collector metric should provide an initialization function
// Each collector metric should provide an initialization function
// for both deprecated and non-deprecated variants of a metric. This
// for both deprecated and non-deprecated variants of a metric. This
// is necessary since
we are now deferring metric instantiation
// is necessary since
metric instantiation will be deferred
// until the metric is actually registered somewhere.
// until the metric is actually registered somewhere.
initializeMetric
()
initializeMetric
()
initializeDeprecatedMetric
()
initializeDeprecatedMetric
()
}
}
// LazyMetric defines our registration functionality. We expect LazyMetric
/*
// objects to lazily instantiate metrics (i.e defer metric instantiation until when
LazyMetric defines our registration functionality. LazyMetric objects are expected
// ActuallyCreate is explicitly called).
to lazily instantiate metrics (i.e defer metric instantiation until when
the Create() function is explicitly called).
*/
type
LazyMetric
interface
{
type
LazyMetric
interface
{
Actually
Create
(
*
semver
.
Version
)
bool
Create
(
*
semver
.
Version
)
bool
IsCreated
()
bool
IsCreated
()
bool
IsHidden
()
bool
IsHidden
()
bool
IsDeprecated
()
bool
IsDeprecated
()
bool
}
}
/*
/*
*
lazyMetric implements LazyMetric. A lazy metric is lazy because it waits until metric
lazyMetric implements LazyMetric. A lazy metric is lazy because it waits until metric
*
registration time before instantiation. Add it as an anonymous field to a struct that
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
implements KubeCollector to get deferred registration behavior. You must call lazyInit
*
with the KubeCollector itself as an argument.
with the KubeCollector itself as an argument.
*/
*/
type
lazyMetric
struct
{
type
lazyMetric
struct
{
isDeprecated
bool
isDeprecated
bool
...
@@ -78,11 +80,11 @@ func (r *lazyMetric) lazyInit(self KubeCollector) {
...
@@ -78,11 +80,11 @@ func (r *lazyMetric) lazyInit(self KubeCollector) {
r
.
self
=
self
r
.
self
=
self
}
}
// determineDeprecationStatus figures out whether
our lazy metric should be deprecated or not. It takes
// determineDeprecationStatus figures out whether
the lazy metric should be deprecated or not.
//
a Version argument which should be the version of the binary in which this code is currently being
//
This method takes a Version argument which should be the version of the binary in which
// executed.
//
this code is currently being
executed.
func
(
r
*
lazyMetric
)
determineDeprecationStatus
(
version
semver
.
Version
)
{
func
(
r
*
lazyMetric
)
determineDeprecationStatus
(
version
semver
.
Version
)
{
selfVersion
:=
r
.
self
.
Get
DeprecatedVersion
()
selfVersion
:=
r
.
self
.
DeprecatedVersion
()
if
selfVersion
==
nil
{
if
selfVersion
==
nil
{
return
return
}
}
...
@@ -105,13 +107,12 @@ func (r *lazyMetric) IsDeprecated() bool {
...
@@ -105,13 +107,12 @@ func (r *lazyMetric) IsDeprecated() bool {
return
r
.
isDeprecated
return
r
.
isDeprecated
}
}
// Defer initialization of metric until we know if we actually need to
// Create forces the initialization of metric which has been deferred until
// register the thing. This wrapper just allows us to consolidate the
// the point at which this method is invoked. This method will determine whether
// syncOnce logic in a single spot and toggle the flag, since this
// the metric is deprecated or hidden, no-opting if the metric should be considered
// behavior will be consistent across metrics.
// hidden. Furthermore, this function no-opts and returns true if metric is already
//
// created.
// This no-opts and returns true if metric is already created.
func
(
r
*
lazyMetric
)
Create
(
version
*
semver
.
Version
)
bool
{
func
(
r
*
lazyMetric
)
ActuallyCreate
(
version
*
semver
.
Version
)
bool
{
if
version
!=
nil
{
if
version
!=
nil
{
r
.
determineDeprecationStatus
(
*
version
)
r
.
determineDeprecationStatus
(
*
version
)
}
}
...
@@ -130,11 +131,11 @@ func (r *lazyMetric) ActuallyCreate(version *semver.Version) bool {
...
@@ -130,11 +131,11 @@ func (r *lazyMetric) ActuallyCreate(version *semver.Version) bool {
return
r
.
IsCreated
()
return
r
.
IsCreated
()
}
}
/*
*
/*
*
This code is directly lifted from the prometheus codebase. It's a convenience struct which
This code is directly lifted from the prometheus codebase. It's a convenience struct which
*
allows you satisfy the Collector interface automatically if you already satisfy the Metric interface.
allows you satisfy the Collector interface automatically if you already satisfy the Metric interface.
*
* For reference: https://github.com/prometheus/client_golang/blob/65d3a96fbaa7c8c9535d7133d6d98cd50eed4db8
/prometheus/collector.go#L98-L120
For reference: https://github.com/prometheus/client_golang/blob/v0.9.2
/prometheus/collector.go#L98-L120
*/
*/
type
selfCollector
struct
{
type
selfCollector
struct
{
metric
prometheus
.
Metric
metric
prometheus
.
Metric
...
...
pkg/util/metrics/opts.go
View file @
cebad0da
...
@@ -23,9 +23,9 @@ import (
...
@@ -23,9 +23,9 @@ import (
"sync"
"sync"
)
)
// KubeOpts is superset struct for prometheus.Opts.
We choose not to embed
// KubeOpts is superset struct for prometheus.Opts.
The prometheus Opts structure
//
the prometheus Opts structure
here because that would change struct initialization
//
is purposefully not embedded
here because that would change struct initialization
// in the manner
to
which people are currently accustomed.
// in the manner which people are currently accustomed.
//
//
// Name must be set to a non-empty string. DeprecatedVersion is defined only
// Name must be set to a non-empty string. DeprecatedVersion is defined only
// if the metric for which this options applies is, in fact, deprecated.
// if the metric for which this options applies is, in fact, deprecated.
...
...
pkg/util/metrics/registry.go
View file @
cebad0da
...
@@ -45,7 +45,7 @@ func MustRegister(cs ...KubeCollector) {
...
@@ -45,7 +45,7 @@ func MustRegister(cs ...KubeCollector) {
}
}
func
(
kr
*
KubeRegistry
)
Register
(
c
KubeCollector
)
error
{
func
(
kr
*
KubeRegistry
)
Register
(
c
KubeCollector
)
error
{
if
c
.
Actually
Create
(
&
kr
.
version
)
{
if
c
.
Create
(
&
kr
.
version
)
{
return
kr
.
PromRegistry
.
Register
(
c
)
return
kr
.
PromRegistry
.
Register
(
c
)
}
}
return
nil
return
nil
...
@@ -54,7 +54,7 @@ func (kr *KubeRegistry) Register(c KubeCollector) error {
...
@@ -54,7 +54,7 @@ func (kr *KubeRegistry) Register(c KubeCollector) 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
.
Actually
Create
(
&
kr
.
version
)
{
if
c
.
Create
(
&
kr
.
version
)
{
metrics
=
append
(
metrics
,
c
)
metrics
=
append
(
metrics
,
c
)
}
}
}
}
...
...
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