Skip to content

Commit

Permalink
Add wrapper for TimingHistogram
Browse files Browse the repository at this point in the history
Do not bother wrapping WeightedHistogram because it is not used
in k/k.

Kubernetes-commit: 68d92494907ae1d8a87b2e29cc9cc2a2709ca3a9
  • Loading branch information
MikeSpreitzer authored and k8s-publishing-bot committed Apr 29, 2022
1 parent ee36a6a commit 56886e5
Show file tree
Hide file tree
Showing 7 changed files with 810 additions and 16 deletions.
1 change: 1 addition & 0 deletions metrics/histogram.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package metrics

import (
"context"

"github.com/blang/semver/v4"
"github.com/prometheus/client_golang/prometheus"
)
Expand Down
40 changes: 35 additions & 5 deletions metrics/histogram_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,19 @@ func TestHistogram(t *testing.T) {
})
c := NewHistogram(test.HistogramOpts)
registry.MustRegister(c)
cm := c.ObserverMetric.(prometheus.Metric)

metricChan := make(chan prometheus.Metric, 2)
c.Collect(metricChan)
close(metricChan)
m1 := <-metricChan
if m1 != cm {
t.Error("Unexpected metric", m1, cm)
}
m2, ok := <-metricChan
if ok {
t.Error("Unexpected second metric", m2)
}

ms, err := registry.Gather()
assert.Equalf(t, test.expectedMetricCount, len(ms), "Got %v metrics, Want: %v metrics", len(ms), test.expectedMetricCount)
Expand Down Expand Up @@ -179,7 +192,24 @@ func TestHistogramVec(t *testing.T) {
})
c := NewHistogramVec(test.HistogramOpts, test.labels)
registry.MustRegister(c)
c.WithLabelValues("1", "2").Observe(1.0)
ov12 := c.WithLabelValues("1", "2")
cm1 := ov12.(prometheus.Metric)
ov12.Observe(1.0)

if test.expectedMetricCount > 0 {
metricChan := make(chan prometheus.Metric, 2)
c.Collect(metricChan)
close(metricChan)
m1 := <-metricChan
if m1 != cm1 {
t.Error("Unexpected metric", m1, cm1)
}
m2, ok := <-metricChan
if ok {
t.Error("Unexpected second metric", m2)
}
}

ms, err := registry.Gather()
assert.Equalf(t, test.expectedMetricCount, len(ms), "Got %v metrics, Want: %v metrics", len(ms), test.expectedMetricCount)
assert.Nil(t, err, "Gather failed %v", err)
Expand Down Expand Up @@ -218,20 +248,20 @@ func TestHistogramWithLabelValueAllowList(t *testing.T) {
var tests = []struct {
desc string
labelValues [][]string
expectMetricValues map[string]int
expectMetricValues map[string]uint64
}{
{
desc: "Test no unexpected input",
labelValues: [][]string{{"allowed", "b1"}, {"allowed", "b2"}},
expectMetricValues: map[string]int{
expectMetricValues: map[string]uint64{
"allowed b1": 1.0,
"allowed b2": 1.0,
},
},
{
desc: "Test unexpected input",
labelValues: [][]string{{"allowed", "b1"}, {"not_allowed", "b1"}},
expectMetricValues: map[string]int{
expectMetricValues: map[string]uint64{
"allowed b1": 1.0,
"unexpected b1": 1.0,
},
Expand Down Expand Up @@ -274,7 +304,7 @@ func TestHistogramWithLabelValueAllowList(t *testing.T) {
labelValuePair := aValue + " " + bValue
expectedValue, ok := test.expectMetricValues[labelValuePair]
assert.True(t, ok, "Got unexpected label values, lable_a is %v, label_b is %v", aValue, bValue)
actualValue := int(m.GetHistogram().GetSampleCount())
actualValue := m.GetHistogram().GetSampleCount()
assert.Equalf(t, expectedValue, actualValue, "Got %v, wanted %v as the count while setting label_a to %v and label b to %v", actualValue, expectedValue, aValue, bValue)
}
}
Expand Down
25 changes: 14 additions & 11 deletions metrics/metric.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/blang/semver/v4"
"github.com/prometheus/client_golang/prometheus"
dto "github.com/prometheus/client_model/go"
promext "k8s.io/component-base/metrics/prometheusextension"

"k8s.io/klog/v2"
)
Expand Down Expand Up @@ -203,6 +204,7 @@ func (c *selfCollector) Collect(ch chan<- prometheus.Metric) {
// no-op vecs for convenience
var noopCounterVec = &prometheus.CounterVec{}
var noopHistogramVec = &prometheus.HistogramVec{}
var noopTimingHistogramVec = &promext.TimingHistogramVec{}
var noopGaugeVec = &prometheus.GaugeVec{}
var noopObserverVec = &noopObserverVector{}

Expand All @@ -211,17 +213,18 @@ var noop = &noopMetric{}

type noopMetric struct{}

func (noopMetric) Inc() {}
func (noopMetric) Add(float64) {}
func (noopMetric) Dec() {}
func (noopMetric) Set(float64) {}
func (noopMetric) Sub(float64) {}
func (noopMetric) Observe(float64) {}
func (noopMetric) SetToCurrentTime() {}
func (noopMetric) Desc() *prometheus.Desc { return nil }
func (noopMetric) Write(*dto.Metric) error { return nil }
func (noopMetric) Describe(chan<- *prometheus.Desc) {}
func (noopMetric) Collect(chan<- prometheus.Metric) {}
func (noopMetric) Inc() {}
func (noopMetric) Add(float64) {}
func (noopMetric) Dec() {}
func (noopMetric) Set(float64) {}
func (noopMetric) Sub(float64) {}
func (noopMetric) Observe(float64) {}
func (noopMetric) ObserveWithWeight(float64, uint64) {}
func (noopMetric) SetToCurrentTime() {}
func (noopMetric) Desc() *prometheus.Desc { return nil }
func (noopMetric) Write(*dto.Metric) error { return nil }
func (noopMetric) Describe(chan<- *prometheus.Desc) {}
func (noopMetric) Collect(chan<- prometheus.Metric) {}

type noopObserverVector struct{}

Expand Down
49 changes: 49 additions & 0 deletions metrics/opts.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (

"github.com/prometheus/client_golang/prometheus"
"k8s.io/apimachinery/pkg/util/sets"
promext "k8s.io/component-base/metrics/prometheusextension"
)

var (
Expand Down Expand Up @@ -189,6 +190,54 @@ func (o *HistogramOpts) toPromHistogramOpts() prometheus.HistogramOpts {
}
}

// TimingHistogramOpts bundles the options for creating a TimingHistogram metric. It is
// mandatory to set Name to a non-empty string. All other fields are optional
// and can safely be left at their zero value, although it is strongly
// encouraged to set a Help string.
type TimingHistogramOpts struct {
Namespace string
Subsystem string
Name string
Help string
ConstLabels map[string]string
Buckets []float64
InitialValue float64
DeprecatedVersion string
deprecateOnce sync.Once
annotateOnce sync.Once
StabilityLevel StabilityLevel
LabelValueAllowLists *MetricLabelAllowList
}

// Modify help description on the metric description.
func (o *TimingHistogramOpts) markDeprecated() {
o.deprecateOnce.Do(func() {
o.Help = fmt.Sprintf("(Deprecated since %v) %v", o.DeprecatedVersion, o.Help)
})
}

// annotateStabilityLevel annotates help description on the metric description with the stability level
// of the metric
func (o *TimingHistogramOpts) annotateStabilityLevel() {
o.annotateOnce.Do(func() {
o.Help = fmt.Sprintf("[%v] %v", o.StabilityLevel, o.Help)
})
}

// convenience function to allow easy transformation to the prometheus
// counterpart. This will do more once we have a proper label abstraction
func (o *TimingHistogramOpts) toPromHistogramOpts() promext.TimingHistogramOpts {
return promext.TimingHistogramOpts{
Namespace: o.Namespace,
Subsystem: o.Subsystem,
Name: o.Name,
Help: o.Help,
ConstLabels: o.ConstLabels,
Buckets: o.Buckets,
InitialValue: o.InitialValue,
}
}

// SummaryOpts bundles the options for creating a Summary metric. It is
// mandatory to set Name to a non-empty string. While all other fields are
// optional and can safely be left at their zero value, it is recommended to set
Expand Down
Loading

0 comments on commit 56886e5

Please sign in to comment.