Skip to content

[POC] Add some metrics to debug at scale #1

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

Open
wants to merge 2 commits into
base: release-0.15
Choose a base branch
from
Open
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
61 changes: 55 additions & 6 deletions pkg/metrics/client_go_adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,34 @@ package metrics

import (
"context"
"math"
"net/url"
"time"

"github.com/prometheus/client_golang/prometheus"
clientmetrics "k8s.io/client-go/tools/metrics"
)

// this file contains setup logic to initialize the myriad of places
// that client-go registers metrics. We copy the names and formats
// from Kubernetes so that we match the core controllers.

var (
// client metrics.
// requestLatency is a Prometheus Histogram metric type partitioned by
// "verb", and "host" labels. It is used for the rest client latency metrics.
requestLatency = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "rest_client_request_duration_seconds",
Help: "Request latency in seconds. Broken down by verb, and host.",
Buckets: []float64{math.Inf(+1)}, // Intentionally using minimum buckets for better performance / lower cardinality.
},
[]string{"verb", "host"},
)

rateLimiterLatency = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "rest_client_rate_limiter_duration_seconds",
Help: "Client side rate limiter latency in seconds. Broken down by verb, and host.",
Buckets: []float64{math.Inf(+1)}, // Intentionally using minimum buckets for better performance / lower cardinality.
},
[]string{"verb", "host"},
)

requestResult = prometheus.NewCounterVec(
prometheus.CounterOpts{
Expand All @@ -37,6 +54,14 @@ var (
},
[]string{"code", "method", "host"},
)

requestRetry = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "rest_client_request_retries_total",
Help: "Number of request retries, partitioned by status code, verb, and host.",
},
[]string{"code", "verb", "host"},
)
)

func init() {
Expand All @@ -46,11 +71,17 @@ func init() {
// registerClientMetrics sets up the client latency metrics from client-go.
func registerClientMetrics() {
// register the metrics with our registry
Registry.MustRegister(requestLatency)
Registry.MustRegister(rateLimiterLatency)
Registry.MustRegister(requestResult)
Registry.MustRegister(requestRetry)

// register the metrics with client-go
clientmetrics.Register(clientmetrics.RegisterOpts{
RequestResult: &resultAdapter{metric: requestResult},
RequestLatency: &LatencyAdapter{metric: requestLatency},
RateLimiterLatency: &LatencyAdapter{metric: rateLimiterLatency},
RequestResult: &resultAdapter{metric: requestResult},
RequestRetry: &retryAdapter{requestRetry},
})
}

Expand All @@ -62,10 +93,28 @@ func registerClientMetrics() {
// copied (more-or-less directly) from k8s.io/kubernetes setup code
// (which isn't anywhere in an easily-importable place).

// LatencyAdapter implements LatencyMetric.
type LatencyAdapter struct {
metric *prometheus.HistogramVec
}

// Observe increments the request latency metric for the given verb/URL.
func (l *LatencyAdapter) Observe(_ context.Context, verb string, u url.URL, latency time.Duration) {
l.metric.WithLabelValues(verb, u.String()).Observe(latency.Seconds())
}

type resultAdapter struct {
metric *prometheus.CounterVec
}

func (r *resultAdapter) Increment(_ context.Context, code, method, host string) {
r.metric.WithLabelValues(code, method, host).Inc()
}

type retryAdapter struct {
metric *prometheus.CounterVec
}

func (r *retryAdapter) IncrementRetry(_ context.Context, code, method, host string) {
r.metric.WithLabelValues(code, method, host).Inc()
}