From 80024aefcb0d92db7bbb620e71d45b3bae6a3685 Mon Sep 17 00:00:00 2001 From: Han Kang Date: Wed, 21 Sep 2022 13:07:18 -0700 Subject: [PATCH] add a feature enabled metric Change-Id: Id872651c4219d4749fc4227da7d944e883e4e355 --- .../metrics/prometheus/feature/metrics.go | 51 ++++++++++++ .../prometheus/feature/metrics_test.go | 77 +++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 staging/src/k8s.io/component-base/metrics/prometheus/feature/metrics.go create mode 100644 staging/src/k8s.io/component-base/metrics/prometheus/feature/metrics_test.go diff --git a/staging/src/k8s.io/component-base/metrics/prometheus/feature/metrics.go b/staging/src/k8s.io/component-base/metrics/prometheus/feature/metrics.go new file mode 100644 index 00000000000..ab3014cf138 --- /dev/null +++ b/staging/src/k8s.io/component-base/metrics/prometheus/feature/metrics.go @@ -0,0 +1,51 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package feature + +import ( + "context" + "fmt" + + k8smetrics "k8s.io/component-base/metrics" + "k8s.io/component-base/metrics/legacyregistry" +) + +var ( + // featureEnabled is a Prometheus Gauge metrics used for recording the enablement of a k8s feature. + featureEnabled = k8smetrics.NewGaugeVec( + &k8smetrics.GaugeOpts{ + Namespace: "k8s", + Name: "feature_enabled", + Help: "This metric records the result of whether a feature is enabled.", + StabilityLevel: k8smetrics.ALPHA, + }, + []string{"name", "enabled"}, + ) +) + +func init() { + legacyregistry.MustRegister(featureEnabled) +} + +func ResetFeatureEnabledMetric() { + featureEnabled.Reset() +} + +func RecordFeatureEnabled(ctx context.Context, name string, enabled bool) error { + featureEnabled.WithContext(ctx).WithLabelValues(name, fmt.Sprintf("%v", enabled)).Set(1) + return nil +} diff --git a/staging/src/k8s.io/component-base/metrics/prometheus/feature/metrics_test.go b/staging/src/k8s.io/component-base/metrics/prometheus/feature/metrics_test.go new file mode 100644 index 00000000000..b32a53460c5 --- /dev/null +++ b/staging/src/k8s.io/component-base/metrics/prometheus/feature/metrics_test.go @@ -0,0 +1,77 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package feature + +import ( + "context" + "strings" + "testing" + + "k8s.io/component-base/metrics/legacyregistry" + "k8s.io/component-base/metrics/testutil" +) + +var ( + testedMetrics = []string{"k8s_feature_enabled"} +) + +func TestObserveHealthcheck(t *testing.T) { + defer legacyregistry.Reset() + defer ResetFeatureEnabledMetric() + + testCases := []struct { + desc string + name string + enabled bool + want string + }{ + { + desc: "test enabled", + name: "feature-a", + enabled: true, + want: ` + # HELP k8s_feature_enabled [ALPHA] This metric records the result of whether a feature is enabled. + # TYPE k8s_feature_enabled gauge + k8s_feature_enabled{enabled="true",name="feature-a"} 1 +`, + }, + { + desc: "test disabled", + name: "feature-b", + enabled: false, + want: ` + # HELP k8s_feature_enabled [ALPHA] This metric records the result of whether a feature is enabled. + # TYPE k8s_feature_enabled gauge + k8s_feature_enabled{enabled="false",name="feature-b"} 1 +`, + }, + } + + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + defer ResetFeatureEnabledMetric() + err := RecordFeatureEnabled(context.Background(), test.name, test.enabled) + if err != nil { + t.Errorf("unexpected err: %v", err) + } + + if err := testutil.GatherAndCompare(legacyregistry.DefaultGatherer, strings.NewReader(test.want), testedMetrics...); err != nil { + t.Fatal(err) + } + }) + } +}