Skip to content

Commit 7dee7c8

Browse files
authored
Merge pull request kubernetes#113148 from logicalhan/merge-buckets
move MergeBuckets into component-base so we can properly support it for static-analysis
2 parents 6be327c + 3d3ac6a commit 7dee7c8

File tree

6 files changed

+133
-17
lines changed

6 files changed

+133
-17
lines changed

hack/verify-prometheus-imports.sh

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ allowed_prometheus_importers=(
4343
./staging/src/k8s.io/component-base/metrics/prometheusextension/weighted_histogram.go
4444
./staging/src/k8s.io/component-base/metrics/prometheusextension/weighted_histogram_test.go
4545
./staging/src/k8s.io/component-base/metrics/prometheusextension/weighted_histogram_vec.go
46+
./staging/src/k8s.io/component-base/metrics/buckets.go
4647
./staging/src/k8s.io/component-base/metrics/collector.go
4748
./staging/src/k8s.io/component-base/metrics/collector_test.go
4849
./staging/src/k8s.io/component-base/metrics/counter.go
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
Copyright 2022 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package metrics
18+
19+
import (
20+
"github.com/prometheus/client_golang/prometheus"
21+
)
22+
23+
// DefBuckets is a wrapper for prometheus.DefBuckets
24+
var DefBuckets = prometheus.DefBuckets
25+
26+
// LinearBuckets is a wrapper for prometheus.LinearBuckets.
27+
func LinearBuckets(start, width float64, count int) []float64 {
28+
return prometheus.LinearBuckets(start, width, count)
29+
}
30+
31+
// ExponentialBuckets is a wrapper for prometheus.ExponentialBuckets.
32+
func ExponentialBuckets(start, factor float64, count int) []float64 {
33+
return prometheus.ExponentialBuckets(start, factor, count)
34+
}
35+
36+
// MergeBuckets merges buckets together
37+
func MergeBuckets(buckets ...[]float64) []float64 {
38+
result := make([]float64, 1)
39+
for _, s := range buckets {
40+
result = append(result, s...)
41+
}
42+
return result
43+
}

staging/src/k8s.io/component-base/metrics/histogram.go

-13
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,6 @@ import (
2323
"github.com/prometheus/client_golang/prometheus"
2424
)
2525

26-
// DefBuckets is a wrapper for prometheus.DefBuckets
27-
var DefBuckets = prometheus.DefBuckets
28-
29-
// LinearBuckets is a wrapper for prometheus.LinearBuckets.
30-
func LinearBuckets(start, width float64, count int) []float64 {
31-
return prometheus.LinearBuckets(start, width, count)
32-
}
33-
34-
// ExponentialBuckets is a wrapper for prometheus.ExponentialBuckets.
35-
func ExponentialBuckets(start, factor float64, count int) []float64 {
36-
return prometheus.ExponentialBuckets(start, factor, count)
37-
}
38-
3926
// Histogram is our internal representation for our wrapping struct around prometheus
4027
// histograms. Summary implements both kubeCollector and ObserverMetric
4128
type Histogram struct {

test/instrumentation/decode_metric.go

+43-4
Original file line numberDiff line numberDiff line change
@@ -480,15 +480,54 @@ func (c *metricDecoder) decodeBucketFunctionCall(v *ast.CallExpr) ([]float64, er
480480
if functionImport.String() != c.kubeMetricsImportName {
481481
return nil, newDecodeErrorf(v, errBuckets), true
482482
}
483-
firstArg, secondArg, thirdArg, err := decodeBucketArguments(v)
484-
if err != nil {
485-
return nil, err, true
486-
}
487483
switch functionName {
488484
case "LinearBuckets":
485+
firstArg, secondArg, thirdArg, err := decodeBucketArguments(v)
486+
if err != nil {
487+
return nil, err, true
488+
}
489489
return metrics.LinearBuckets(firstArg, secondArg, thirdArg), nil, true
490490
case "ExponentialBuckets":
491+
firstArg, secondArg, thirdArg, err := decodeBucketArguments(v)
492+
if err != nil {
493+
return nil, err, true
494+
}
491495
return metrics.ExponentialBuckets(firstArg, secondArg, thirdArg), nil, true
496+
case "MergeBuckets":
497+
merged := []float64{}
498+
for _, arg := range v.Args {
499+
switch argExpr := arg.(type) {
500+
case *ast.CompositeLit:
501+
fs, err := decodeListOfFloats(argExpr, argExpr.Elts)
502+
if err != nil {
503+
return nil, err, true
504+
}
505+
merged = append(merged, fs...)
506+
case *ast.CallExpr:
507+
se, ok = argExpr.Fun.(*ast.SelectorExpr)
508+
if ok {
509+
functionName := se.Sel.String()
510+
functionImport, ok := se.X.(*ast.Ident)
511+
if !ok {
512+
return nil, newDecodeErrorf(v, errBuckets), true
513+
}
514+
if functionImport.String() != c.kubeMetricsImportName {
515+
return nil, newDecodeErrorf(v, errBuckets), true
516+
}
517+
firstArg, secondArg, thirdArg, err := decodeBucketArguments(argExpr)
518+
if err != nil {
519+
return nil, err, true
520+
}
521+
switch functionName {
522+
case "LinearBuckets":
523+
merged = append(merged, metrics.LinearBuckets(firstArg, secondArg, thirdArg)...)
524+
case "ExponentialBuckets":
525+
merged = append(merged, metrics.LinearBuckets(firstArg, secondArg, thirdArg)...)
526+
}
527+
}
528+
}
529+
}
530+
return merged, nil, true
492531
}
493532
return nil, nil, false
494533
}

test/instrumentation/testdata/pkg/kubelet/metrics/metrics.go

+15
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,21 @@ var (
488488
StabilityLevel: metrics.BETA,
489489
},
490490
)
491+
492+
NetworkProgrammingLatency2 = metrics.NewHistogram(
493+
&metrics.HistogramOpts{
494+
Subsystem: "kube_proxy",
495+
Name: "network_programming_duration_seconds2",
496+
Help: "In Cluster Network Programming Latency in seconds",
497+
Buckets: metrics.MergeBuckets(
498+
metrics.LinearBuckets(0.25, 0.25, 2), // 0.25s, 0.50s
499+
[]float64{1, 5, 10, 59}, // 1s, 2s, 3s, ... 59s
500+
metrics.LinearBuckets(60, 5, 12), // 60s, 65s, 70s, ... 115s
501+
metrics.LinearBuckets(120, 30, 7), // 2min, 2.5min, 3min, ..., 5min
502+
),
503+
StabilityLevel: metrics.BETA,
504+
},
505+
)
491506
)
492507

493508
var registerMetrics sync.Once

test/instrumentation/testdata/test-stable-metrics-list.yaml

+31
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,37 @@
8484
- 240
8585
- 270
8686
- 300
87+
- name: network_programming_duration_seconds2
88+
subsystem: kube_proxy
89+
help: In Cluster Network Programming Latency in seconds
90+
type: Histogram
91+
stabilityLevel: BETA
92+
buckets:
93+
- 0.25
94+
- 0.5
95+
- 1
96+
- 5
97+
- 10
98+
- 59
99+
- 60
100+
- 65
101+
- 70
102+
- 75
103+
- 80
104+
- 85
105+
- 90
106+
- 95
107+
- 100
108+
- 105
109+
- 110
110+
- 115
111+
- 120
112+
- 150
113+
- 180
114+
- 210
115+
- 240
116+
- 270
117+
- 300
87118
- name: certificate_manager_client_ttl_seconds
88119
subsystem: kubelet
89120
help: Gauge of the TTL (time-to-live) of the Kubelet's client certificate. The value

0 commit comments

Comments
 (0)