mirror of
https://github.com/kubernetes/client-go.git
synced 2025-08-11 12:11:52 +00:00
client-go: add DNS resolver latency metrics (#115357)
* client-go: add DNS resolver latency metrics * client-go: add locking to DNS latency metrics * client-go: add locking for whole DNSStart and DNSDone Signed-off-by: Vu Dinh <vudinh@outlook.com> * Fix a mismatched ctx on the request Signed-off-by: Vu Dinh <vudinh@outlook.com> * Clean up request code and fix comments Signed-off-by: Vu Dinh <vudinh@outlook.com> --------- Signed-off-by: Vu Dinh <vudinh@outlook.com> Co-authored-by: Vu Dinh <vudinh@outlook.com> Kubernetes-commit: 1c7e87cff27aa009488a9d55342220e223d5c146
This commit is contained in:
parent
bb755c8cba
commit
0cde78477a
@ -24,6 +24,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"mime"
|
"mime"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/http/httptrace"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
@ -925,15 +926,38 @@ func (r *Request) newHTTPRequest(ctx context.Context) (*http.Request, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
url := r.URL().String()
|
url := r.URL().String()
|
||||||
req, err := http.NewRequest(r.verb, url, body)
|
req, err := http.NewRequestWithContext(httptrace.WithClientTrace(ctx, newDNSMetricsTrace(ctx)), r.verb, url, body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
req = req.WithContext(ctx)
|
|
||||||
req.Header = r.headers
|
req.Header = r.headers
|
||||||
return req, nil
|
return req, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// newDNSMetricsTrace returns an HTTP trace that tracks time spent on DNS lookups per host.
|
||||||
|
// This metric is available in client as "rest_client_dns_resolution_duration_seconds".
|
||||||
|
func newDNSMetricsTrace(ctx context.Context) *httptrace.ClientTrace {
|
||||||
|
type dnsMetric struct {
|
||||||
|
start time.Time
|
||||||
|
host string
|
||||||
|
sync.Mutex
|
||||||
|
}
|
||||||
|
dns := &dnsMetric{}
|
||||||
|
return &httptrace.ClientTrace{
|
||||||
|
DNSStart: func(info httptrace.DNSStartInfo) {
|
||||||
|
dns.Lock()
|
||||||
|
defer dns.Unlock()
|
||||||
|
dns.start = time.Now()
|
||||||
|
dns.host = info.Host
|
||||||
|
},
|
||||||
|
DNSDone: func(info httptrace.DNSDoneInfo) {
|
||||||
|
dns.Lock()
|
||||||
|
defer dns.Unlock()
|
||||||
|
metrics.ResolverLatency.Observe(ctx, dns.host, time.Since(dns.start))
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// request connects to the server and invokes the provided function when a server response is
|
// request connects to the server and invokes the provided function when a server response is
|
||||||
// received. It handles retry behavior and up front validation of requests. It will invoke
|
// received. It handles retry behavior and up front validation of requests. It will invoke
|
||||||
// fn at most once. It will return an error if a problem occurred prior to connecting to the
|
// fn at most once. It will return an error if a problem occurred prior to connecting to the
|
||||||
|
@ -42,6 +42,10 @@ type LatencyMetric interface {
|
|||||||
Observe(ctx context.Context, verb string, u url.URL, latency time.Duration)
|
Observe(ctx context.Context, verb string, u url.URL, latency time.Duration)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ResolverLatencyMetric interface {
|
||||||
|
Observe(ctx context.Context, host string, latency time.Duration)
|
||||||
|
}
|
||||||
|
|
||||||
// SizeMetric observes client response size partitioned by verb and host.
|
// SizeMetric observes client response size partitioned by verb and host.
|
||||||
type SizeMetric interface {
|
type SizeMetric interface {
|
||||||
Observe(ctx context.Context, verb string, host string, size float64)
|
Observe(ctx context.Context, verb string, host string, size float64)
|
||||||
@ -82,6 +86,8 @@ var (
|
|||||||
ClientCertRotationAge DurationMetric = noopDuration{}
|
ClientCertRotationAge DurationMetric = noopDuration{}
|
||||||
// RequestLatency is the latency metric that rest clients will update.
|
// RequestLatency is the latency metric that rest clients will update.
|
||||||
RequestLatency LatencyMetric = noopLatency{}
|
RequestLatency LatencyMetric = noopLatency{}
|
||||||
|
// ResolverLatency is the latency metric that DNS resolver will update
|
||||||
|
ResolverLatency ResolverLatencyMetric = noopResolverLatency{}
|
||||||
// RequestSize is the request size metric that rest clients will update.
|
// RequestSize is the request size metric that rest clients will update.
|
||||||
RequestSize SizeMetric = noopSize{}
|
RequestSize SizeMetric = noopSize{}
|
||||||
// ResponseSize is the response size metric that rest clients will update.
|
// ResponseSize is the response size metric that rest clients will update.
|
||||||
@ -109,6 +115,7 @@ type RegisterOpts struct {
|
|||||||
ClientCertExpiry ExpiryMetric
|
ClientCertExpiry ExpiryMetric
|
||||||
ClientCertRotationAge DurationMetric
|
ClientCertRotationAge DurationMetric
|
||||||
RequestLatency LatencyMetric
|
RequestLatency LatencyMetric
|
||||||
|
ResolverLatency ResolverLatencyMetric
|
||||||
RequestSize SizeMetric
|
RequestSize SizeMetric
|
||||||
ResponseSize SizeMetric
|
ResponseSize SizeMetric
|
||||||
RateLimiterLatency LatencyMetric
|
RateLimiterLatency LatencyMetric
|
||||||
@ -132,6 +139,9 @@ func Register(opts RegisterOpts) {
|
|||||||
if opts.RequestLatency != nil {
|
if opts.RequestLatency != nil {
|
||||||
RequestLatency = opts.RequestLatency
|
RequestLatency = opts.RequestLatency
|
||||||
}
|
}
|
||||||
|
if opts.ResolverLatency != nil {
|
||||||
|
ResolverLatency = opts.ResolverLatency
|
||||||
|
}
|
||||||
if opts.RequestSize != nil {
|
if opts.RequestSize != nil {
|
||||||
RequestSize = opts.RequestSize
|
RequestSize = opts.RequestSize
|
||||||
}
|
}
|
||||||
@ -171,6 +181,11 @@ type noopLatency struct{}
|
|||||||
|
|
||||||
func (noopLatency) Observe(context.Context, string, url.URL, time.Duration) {}
|
func (noopLatency) Observe(context.Context, string, url.URL, time.Duration) {}
|
||||||
|
|
||||||
|
type noopResolverLatency struct{}
|
||||||
|
|
||||||
|
func (n noopResolverLatency) Observe(ctx context.Context, host string, latency time.Duration) {
|
||||||
|
}
|
||||||
|
|
||||||
type noopSize struct{}
|
type noopSize struct{}
|
||||||
|
|
||||||
func (noopSize) Observe(context.Context, string, string, float64) {}
|
func (noopSize) Observe(context.Context, string, string, float64) {}
|
||||||
|
Loading…
Reference in New Issue
Block a user