mirror of
https://github.com/hanzoai/dns.git
synced 2026-10-30 18:40:55 +00:00
The mechanical migration (9b8e9a14b) left the tree uncompilable: it used
luxfi/metric as a prometheus drop-in, but several symbols were missing and a
few types were misused. Finish it against luxfi/metric v1.8.2 (which adds the
prometheus-compat surface):
- pin luxfi/metric v1.8.2 (native-histogram HistogramOpts fields, package
MustRegister/Unregister, AlreadyRegisteredError, With/AutoFactory,
GoCollectorOption/MetricsAll, Vec.Delete, no-op collector registration)
- use metric.Registry / metric.{Histogram,Counter}Vec as INTERFACES, not
concrete pointers (plugin/metrics, plugin/kubernetes)
- build with -tags metrics so luxfi/metric's collecting registry is active
(the default is a //go:build metrics no-op stub); wire it into Makefile
GOTAGS, the GHCR image build, and the CI test matrix
- test harness: select a metric-name validation scheme for the exposition
parser (client_golang used to set the global default; CoreDNS no longer
imports it)
go build ./... + go test -tags metrics ./plugin/metrics/... /kubernetes /reload
are green.
87 lines
2.7 KiB
Go
87 lines
2.7 KiB
Go
package kubernetes
|
|
|
|
import (
|
|
"context"
|
|
"net/url"
|
|
"strings"
|
|
"time"
|
|
"unicode/utf8"
|
|
|
|
"github.com/coredns/coredns/plugin"
|
|
|
|
metric "github.com/luxfi/metric"
|
|
"k8s.io/client-go/tools/metrics"
|
|
)
|
|
|
|
var (
|
|
// requestLatency measures K8s rest client requests latency grouped by verb and host.
|
|
requestLatency = metric.NewHistogramVec(
|
|
metric.HistogramOpts{
|
|
Namespace: plugin.Namespace,
|
|
Subsystem: "kubernetes",
|
|
Name: "rest_client_request_duration_seconds",
|
|
Help: "Request latency in seconds. Broken down by verb and host.",
|
|
Buckets: metric.DefBuckets,
|
|
NativeHistogramBucketFactor: plugin.NativeHistogramBucketFactor,
|
|
},
|
|
[]string{"verb", "host"},
|
|
)
|
|
|
|
// rateLimiterLatency measures K8s rest client rate limiter latency grouped by verb and host.
|
|
rateLimiterLatency = metric.NewHistogramVec(
|
|
metric.HistogramOpts{
|
|
Namespace: plugin.Namespace,
|
|
Subsystem: "kubernetes",
|
|
Name: "rest_client_rate_limiter_duration_seconds",
|
|
Help: "Client side rate limiter latency in seconds. Broken down by verb and host.",
|
|
Buckets: metric.DefBuckets,
|
|
NativeHistogramBucketFactor: plugin.NativeHistogramBucketFactor,
|
|
},
|
|
[]string{"verb", "host"},
|
|
)
|
|
|
|
// requestResult measures K8s rest client request metrics grouped by status code, method & host.
|
|
requestResult = metric.NewCounterVec(
|
|
metric.CounterOpts{
|
|
Namespace: plugin.Namespace,
|
|
Subsystem: "kubernetes",
|
|
Name: "rest_client_requests_total",
|
|
Help: "Number of HTTP requests, partitioned by status code, method, and host.",
|
|
},
|
|
[]string{"code", "method", "host"},
|
|
)
|
|
)
|
|
|
|
func init() {
|
|
metrics.Register(metrics.RegisterOpts{
|
|
RequestLatency: &latencyAdapter{m: requestLatency},
|
|
RateLimiterLatency: &latencyAdapter{m: rateLimiterLatency},
|
|
RequestResult: &resultAdapter{requestResult},
|
|
})
|
|
}
|
|
|
|
type latencyAdapter struct {
|
|
m metric.HistogramVec
|
|
}
|
|
|
|
func (l *latencyAdapter) Observe(_ context.Context, verb string, u url.URL, latency time.Duration) {
|
|
l.m.WithLabelValues(verb, sanitizeLabelValue(u.Host)).Observe(latency.Seconds())
|
|
}
|
|
|
|
type resultAdapter struct {
|
|
m metric.CounterVec
|
|
}
|
|
|
|
func (r *resultAdapter) Increment(_ context.Context, code, method, host string) {
|
|
r.m.WithLabelValues(code, method, sanitizeLabelValue(host)).Inc()
|
|
}
|
|
|
|
// sanitizeLabelValue ensures the string is valid UTF-8, which is required by
|
|
// Prometheus for label values. Invalid bytes are replaced with U+FFFD.
|
|
func sanitizeLabelValue(s string) string {
|
|
if utf8.ValidString(s) {
|
|
return s
|
|
}
|
|
return strings.ToValidUTF8(s, "\uFFFD")
|
|
}
|