Skip to content

✨Expose RegisterClientMetrics to register other clien… #2936

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

Closed
wants to merge 2 commits into from
Closed
Changes from 1 commit
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
36 changes: 26 additions & 10 deletions pkg/metrics/client_go_adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ package metrics

import (
"context"
"sync"
"time"

"github.com/prometheus/client_golang/prometheus"
clientmetrics "k8s.io/client-go/tools/metrics"
Expand All @@ -37,20 +39,30 @@ var (
},
[]string{"code", "method", "host"},
)

clientMetricsRegisterOnce = sync.Once{}
)

func init() {
registerClientMetrics()
}

// registerClientMetrics sets up the client latency metrics from client-go.
func registerClientMetrics() {
// register the metrics with our registry
Registry.MustRegister(requestResult)

// register the metrics with client-go
clientmetrics.Register(clientmetrics.RegisterOpts{
RequestResult: &resultAdapter{metric: requestResult},
time.AfterFunc(30*time.Second, func() {
Copy link
Member

Choose a reason for hiding this comment

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

I am not a fan of this because it means you might not get metrics for the first thirty seconds of the binary. Another way I can think of is to maybe call this before first use in the controller or so, that would still allow to register them yourselves by doing it before you build your controllers and avoid this issue?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed, I moved this call into the NewServer function of metric server in 639312c

RegisterClientMetrics(clientmetrics.RegisterOpts{})
})
}

// RegisterClientMetrics sets up the client latency metrics from client-go. Since clientmetrics.Register can only be
// called once, you MUST call this method if you want to register other client-go metrics within the first 30 seconds
// of a binaries lifetime, or it will get called without other metrics.
func RegisterClientMetrics(opts clientmetrics.RegisterOpts) {
clientMetricsRegisterOnce.Do(func() {
opts.RequestResult = &resultAdapter{
metric: requestResult,
customMetric: opts.RequestResult,
}
// register the metrics with client-go
clientmetrics.Register(opts)
})
}

Expand All @@ -63,9 +75,13 @@ func registerClientMetrics() {
// (which isn't anywhere in an easily-importable place).

type resultAdapter struct {
metric *prometheus.CounterVec
metric *prometheus.CounterVec
customMetric clientmetrics.ResultMetric
}

func (r *resultAdapter) Increment(_ context.Context, code, method, host string) {
func (r *resultAdapter) Increment(ctx context.Context, code, method, host string) {
r.metric.WithLabelValues(code, method, host).Inc()
if r.customMetric != nil {
r.customMetric.Increment(ctx, code, method, host)
Copy link
Member

Choose a reason for hiding this comment

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

Sorry, I do not understand this. You both want to register them yourself and plug your own functionality into the existing adapter? Why isn't one of the two enough?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Initially, the goal was to support custom requestResult metrics and keep the original rest_client_requests_total metrics. I changed the resultAdapter to the default value of RegisterOpts.RequestResult in 639312c

}
}