mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-26 05:03:09 +00:00
Merge pull request #83830 from RainbowMango/pr_introduce_gaugefunc_to_stability_framework
Provide a mechanism for GaugeFunc to use the metrics stability framework
This commit is contained in:
commit
d56aaf77b9
@ -48,6 +48,7 @@ go_test(
|
|||||||
"//staging/src/k8s.io/apimachinery/pkg/version:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/version:go_default_library",
|
||||||
"//vendor/github.com/blang/semver:go_default_library",
|
"//vendor/github.com/blang/semver:go_default_library",
|
||||||
"//vendor/github.com/prometheus/client_golang/prometheus:go_default_library",
|
"//vendor/github.com/prometheus/client_golang/prometheus:go_default_library",
|
||||||
|
"//vendor/github.com/prometheus/client_golang/prometheus/testutil:go_default_library",
|
||||||
"//vendor/github.com/prometheus/common/expfmt:go_default_library",
|
"//vendor/github.com/prometheus/common/expfmt:go_default_library",
|
||||||
"//vendor/github.com/stretchr/testify/assert:go_default_library",
|
"//vendor/github.com/stretchr/testify/assert:go_default_library",
|
||||||
],
|
],
|
||||||
|
@ -19,6 +19,8 @@ package metrics
|
|||||||
import (
|
import (
|
||||||
"github.com/blang/semver"
|
"github.com/blang/semver"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
|
||||||
|
"k8s.io/component-base/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Gauge is our internal representation for our wrapping struct around prometheus
|
// Gauge is our internal representation for our wrapping struct around prometheus
|
||||||
@ -158,3 +160,25 @@ func (v *GaugeVec) Delete(labels map[string]string) bool {
|
|||||||
}
|
}
|
||||||
return v.GaugeVec.Delete(labels)
|
return v.GaugeVec.Delete(labels)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newGaugeFunc(opts GaugeOpts, function func() float64, v semver.Version) GaugeFunc {
|
||||||
|
g := NewGauge(&opts)
|
||||||
|
|
||||||
|
if !g.Create(&v) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return prometheus.NewGaugeFunc(g.GaugeOpts.toPromGaugeOpts(), function)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewGaugeFunc creates a new GaugeFunc based on the provided GaugeOpts. The
|
||||||
|
// value reported is determined by calling the given function from within the
|
||||||
|
// Write method. Take into account that metric collection may happen
|
||||||
|
// concurrently. If that results in concurrent calls to Write, like in the case
|
||||||
|
// where a GaugeFunc is directly registered with Prometheus, the provided
|
||||||
|
// function must be concurrency-safe.
|
||||||
|
func NewGaugeFunc(opts GaugeOpts, function func() float64) GaugeFunc {
|
||||||
|
v := parseVersion(version.Get())
|
||||||
|
|
||||||
|
return newGaugeFunc(opts, function, v)
|
||||||
|
}
|
||||||
|
@ -17,9 +17,11 @@ limitations under the License.
|
|||||||
package metrics
|
package metrics
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/blang/semver"
|
"github.com/blang/semver"
|
||||||
|
"github.com/prometheus/client_golang/prometheus/testutil"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
apimachineryversion "k8s.io/apimachinery/pkg/version"
|
apimachineryversion "k8s.io/apimachinery/pkg/version"
|
||||||
@ -191,3 +193,78 @@ func TestGaugeVec(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGaugeFunc(t *testing.T) {
|
||||||
|
currentVersion := apimachineryversion.Info{
|
||||||
|
Major: "1",
|
||||||
|
Minor: "17",
|
||||||
|
GitVersion: "v1.17.0-alpha-1.12345",
|
||||||
|
}
|
||||||
|
|
||||||
|
var function = func() float64 {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
var tests = []struct {
|
||||||
|
desc string
|
||||||
|
GaugeOpts
|
||||||
|
expectedMetrics string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
desc: "Test non deprecated",
|
||||||
|
GaugeOpts: GaugeOpts{
|
||||||
|
Namespace: "namespace",
|
||||||
|
Subsystem: "subsystem",
|
||||||
|
Name: "metric_non_deprecated",
|
||||||
|
Help: "gauge help",
|
||||||
|
},
|
||||||
|
expectedMetrics: `
|
||||||
|
# HELP namespace_subsystem_metric_non_deprecated [ALPHA] gauge help
|
||||||
|
# TYPE namespace_subsystem_metric_non_deprecated gauge
|
||||||
|
namespace_subsystem_metric_non_deprecated 1
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "Test deprecated",
|
||||||
|
GaugeOpts: GaugeOpts{
|
||||||
|
Namespace: "namespace",
|
||||||
|
Subsystem: "subsystem",
|
||||||
|
Name: "metric_deprecated",
|
||||||
|
Help: "gauge help",
|
||||||
|
DeprecatedVersion: "1.17.0",
|
||||||
|
},
|
||||||
|
expectedMetrics: `
|
||||||
|
# HELP namespace_subsystem_metric_deprecated [ALPHA] (Deprecated since 1.17.0) gauge help
|
||||||
|
# TYPE namespace_subsystem_metric_deprecated gauge
|
||||||
|
namespace_subsystem_metric_deprecated 1
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "Test hidden",
|
||||||
|
GaugeOpts: GaugeOpts{
|
||||||
|
Namespace: "namespace",
|
||||||
|
Subsystem: "subsystem",
|
||||||
|
Name: "metric_hidden",
|
||||||
|
Help: "gauge help",
|
||||||
|
DeprecatedVersion: "1.16.0",
|
||||||
|
},
|
||||||
|
expectedMetrics: "",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
tc := test
|
||||||
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
|
registry := newKubeRegistry(currentVersion)
|
||||||
|
gauge := newGaugeFunc(tc.GaugeOpts, function, parseVersion(currentVersion))
|
||||||
|
if gauge != nil { // hidden metrics will not be initialize, register is not allowed
|
||||||
|
registry.RawMustRegister(gauge)
|
||||||
|
}
|
||||||
|
|
||||||
|
metricName := BuildFQName(tc.GaugeOpts.Namespace, tc.GaugeOpts.Subsystem, tc.GaugeOpts.Name)
|
||||||
|
if err := testutil.GatherAndCompare(registry, strings.NewReader(tc.expectedMetrics), metricName); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -42,6 +42,17 @@ type KubeOpts struct {
|
|||||||
StabilityLevel StabilityLevel
|
StabilityLevel StabilityLevel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BuildFQName joins the given three name components by "_". Empty name
|
||||||
|
// components are ignored. If the name parameter itself is empty, an empty
|
||||||
|
// string is returned, no matter what. Metric implementations included in this
|
||||||
|
// library use this function internally to generate the fully-qualified metric
|
||||||
|
// name from the name component in their Opts. Users of the library will only
|
||||||
|
// need this function if they implement their own Metric or instantiate a Desc
|
||||||
|
// (with NewDesc) directly.
|
||||||
|
func BuildFQName(namespace, subsystem, name string) string {
|
||||||
|
return prometheus.BuildFQName(namespace, subsystem, name)
|
||||||
|
}
|
||||||
|
|
||||||
// StabilityLevel represents the API guarantees for a given defined metric.
|
// StabilityLevel represents the API guarantees for a given defined metric.
|
||||||
type StabilityLevel string
|
type StabilityLevel string
|
||||||
|
|
||||||
|
@ -84,3 +84,12 @@ type PromRegistry interface {
|
|||||||
type Gatherer interface {
|
type Gatherer interface {
|
||||||
prometheus.Gatherer
|
prometheus.Gatherer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GaugeFunc is a Gauge whose value is determined at collect time by calling a
|
||||||
|
// provided function.
|
||||||
|
//
|
||||||
|
// To create GaugeFunc instances, use NewGaugeFunc.
|
||||||
|
type GaugeFunc interface {
|
||||||
|
Metric
|
||||||
|
Collector
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user