Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add prometheus metric #19452

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions pkg/featuregate/feature_gate.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"sync"
"sync/atomic"

"github.com/prometheus/client_golang/prometheus"
"github.com/spf13/pflag"
"go.uber.org/zap"
)
Expand Down Expand Up @@ -94,6 +95,8 @@ type FeatureGate interface {
DeepCopy() MutableFeatureGate
// String returns a string containing all enabled feature gates, formatted as "key1=value1,key2=value2,...".
String() string
// AddMetrics adds feature enablement metrics
AddMetrics(gaugeVec *prometheus.GaugeVec)
}

// MutableFeatureGate parses and stores flag gates for known features from
Expand All @@ -112,8 +115,6 @@ type MutableFeatureGate interface {
Add(features map[Feature]FeatureSpec) error
// GetAll returns a copy of the map of known feature names to feature specs.
GetAll() map[Feature]FeatureSpec
// AddMetrics adds feature enablement metrics
AddMetrics()
// OverrideDefault sets a local override for the registered default value of a named
// feature. If the feature has not been previously registered (e.g. by a call to Add), has a
// locked default, or if the gate has already registered itself with a FlagSet, a non-nil
Expand Down Expand Up @@ -363,8 +364,16 @@ func (f *featureGate) AddFlag(fs *flag.FlagSet, flagName string) {
"Options are:\n"+strings.Join(known, "\n"))
}

func (f *featureGate) AddMetrics() {
// TODO(henrybear327): implement this.
func (f *featureGate) AddMetrics(gaugeVec *prometheus.GaugeVec) {
for feature, featureSpec := range f.GetAll() {
var metricVal float64
if f.Enabled(feature) {
metricVal = 1
} else {
metricVal = 0
}
gaugeVec.With(prometheus.Labels{"name": string(feature), "stage": string(featureSpec.PreRelease)}).Set(metricVal)
}
}

// KnownFeatures returns a slice of strings describing the FeatureGate's known features.
Expand Down
42 changes: 42 additions & 0 deletions pkg/featuregate/feature_gate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import (
"strings"
"testing"

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/testutil"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.uber.org/zap/zaptest"
Expand Down Expand Up @@ -555,3 +557,43 @@ func TestFeatureGateOverrideDefault(t *testing.T) {
assert.Errorf(t, err, "expected a non-nil error to be returned")
})
}

func TestAddMetric(t *testing.T) {

etcdServerFeatureEnabled := prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "test_metric",
Help: "Whether or not a feature is enabled. 1 is enabled, 0 is not.",
},
[]string{"name", "stage"},
)
prometheus.MustRegister(etcdServerFeatureEnabled)

const testAlphaGate Feature = "TestAlpha"
const testBetaGate Feature = "TestBeta"
const testGAGate Feature = "TestGA"

featuremap := map[Feature]FeatureSpec{
testGAGate: {Default: true, PreRelease: GA},
testAlphaGate: {Default: false, PreRelease: Alpha},
testBetaGate: {Default: false, PreRelease: Beta},
}

f := New("test", zaptest.NewLogger(t))
f.Add(featuremap)
err := f.SetFromMap(map[string]bool{"TestAlpha": true})
require.NoError(t, err)

f.AddMetrics(etcdServerFeatureEnabled)

expected := `# HELP test_metric Whether or not a feature is enabled. 1 is enabled, 0 is not.
# TYPE test_metric gauge
test_metric{name="AllAlpha",stage="ALPHA"} 0
test_metric{name="AllBeta",stage="BETA"} 0
test_metric{name="TestAlpha",stage="ALPHA"} 1
test_metric{name="TestBeta",stage="BETA"} 0
test_metric{name="TestGA",stage=""} 1
`
err = testutil.GatherAndCompare(prometheus.DefaultGatherer, strings.NewReader(expected), "test_metric")
require.NoErrorf(t, err, "unexpected metric collection result: \n%s", err)
}
8 changes: 8 additions & 0 deletions pkg/go.mod
Copy link
Contributor Author

@gangli113 gangli113 Feb 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because I added prometheus and prometheus/testutil to feature_gate.go. it requires me to run go mod tidy, otherwise build failed. The command modified go.mod and go.sum, do I need to submit these change in PR?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, you should include the dependency changes in the PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems you need to run go mod tidy in some other places as well.

Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,18 @@ require (
)

require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_golang v1.21.0 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.62.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
go.opentelemetry.io/otel v1.34.0 // indirect
go.opentelemetry.io/otel/sdk v1.34.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
Expand Down
16 changes: 16 additions & 0 deletions pkg/go.sum
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
Expand All @@ -24,8 +28,20 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v1.21.0 h1:DIsaGmiaBkSangBgMtWdNfxbMNdku5IK6iNhrEqWvdA=
github.com/prometheus/client_golang v1.21.0/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg=
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=
github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
Expand Down
8 changes: 8 additions & 0 deletions server/etcdserver/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,13 @@ var (
},
[]string{"server_id"},
)
etcdServerFeatureEnabled = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "etcd_server_feature_enabled",
Help: "Whether or not a feature is enabled. 1 is enabled, 0 is not.",
},
[]string{"name", "stage"},
)
fdUsed = prometheus.NewGauge(prometheus.GaugeOpts{
Namespace: "os",
Subsystem: "fd",
Expand Down Expand Up @@ -170,6 +177,7 @@ func init() {
prometheus.MustRegister(currentVersion)
prometheus.MustRegister(currentGoVersion)
prometheus.MustRegister(serverID)
prometheus.MustRegister(etcdServerFeatureEnabled)
prometheus.MustRegister(learnerPromoteSucceed)
prometheus.MustRegister(learnerPromoteFailed)
prometheus.MustRegister(fdUsed)
Expand Down
2 changes: 2 additions & 0 deletions server/etcdserver/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,8 @@ func NewServer(cfg config.ServerConfig) (srv *EtcdServer, err error) {
firstCommitInTerm: notify.NewNotifier(),
clusterVersionChanged: notify.NewNotifier(),
}

cfg.ServerFeatureGate.(featuregate.MutableFeatureGate).AddMetrics(etcdServerFeatureEnabled)
serverID.With(prometheus.Labels{"server_id": b.cluster.nodeID.String()}).Set(1)
srv.cluster.SetVersionChangedNotifier(srv.clusterVersionChanged)

Expand Down
Loading