mirror of https://github.com/k3s-io/k3s
Remove implicit Prometheus metrics from client
parent
ea805efa4f
commit
8d6ce0dcc6
|
@ -23,6 +23,8 @@ package main
|
|||
|
||||
import (
|
||||
"os"
|
||||
|
||||
_ "k8s.io/kubernetes/pkg/client/metrics/prometheus" // for client metric registration
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
|
|
@ -26,6 +26,7 @@ import (
|
|||
|
||||
"k8s.io/kubernetes/cmd/kube-apiserver/app"
|
||||
"k8s.io/kubernetes/cmd/kube-apiserver/app/options"
|
||||
_ "k8s.io/kubernetes/pkg/client/metrics/prometheus" // for client metric registration
|
||||
"k8s.io/kubernetes/pkg/util/flag"
|
||||
"k8s.io/kubernetes/pkg/util/logs"
|
||||
"k8s.io/kubernetes/pkg/version/verflag"
|
||||
|
|
|
@ -26,6 +26,7 @@ import (
|
|||
|
||||
"k8s.io/kubernetes/cmd/kube-controller-manager/app"
|
||||
"k8s.io/kubernetes/cmd/kube-controller-manager/app/options"
|
||||
_ "k8s.io/kubernetes/pkg/client/metrics/prometheus" // for client metric registration
|
||||
"k8s.io/kubernetes/pkg/healthz"
|
||||
"k8s.io/kubernetes/pkg/util/flag"
|
||||
"k8s.io/kubernetes/pkg/util/logs"
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
"github.com/spf13/pflag"
|
||||
"k8s.io/kubernetes/cmd/kube-dns/app"
|
||||
"k8s.io/kubernetes/cmd/kube-dns/app/options"
|
||||
_ "k8s.io/kubernetes/pkg/client/metrics/prometheus" // for client metric registration
|
||||
"k8s.io/kubernetes/pkg/util/flag"
|
||||
"k8s.io/kubernetes/pkg/util/logs"
|
||||
"k8s.io/kubernetes/pkg/version/verflag"
|
||||
|
|
|
@ -22,6 +22,7 @@ import (
|
|||
|
||||
"k8s.io/kubernetes/cmd/kube-proxy/app"
|
||||
"k8s.io/kubernetes/cmd/kube-proxy/app/options"
|
||||
_ "k8s.io/kubernetes/pkg/client/metrics/prometheus" // for client metric registration
|
||||
"k8s.io/kubernetes/pkg/healthz"
|
||||
"k8s.io/kubernetes/pkg/util/flag"
|
||||
"k8s.io/kubernetes/pkg/util/logs"
|
||||
|
|
|
@ -19,6 +19,7 @@ package app
|
|||
import (
|
||||
"os"
|
||||
|
||||
_ "k8s.io/kubernetes/pkg/client/metrics/prometheus" // for client metric registration
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
"k8s.io/kubernetes/pkg/util/logs"
|
||||
|
|
|
@ -26,6 +26,7 @@ import (
|
|||
|
||||
"k8s.io/kubernetes/cmd/kubelet/app"
|
||||
"k8s.io/kubernetes/cmd/kubelet/app/options"
|
||||
_ "k8s.io/kubernetes/pkg/client/metrics/prometheus" // for client metric registration
|
||||
"k8s.io/kubernetes/pkg/util/flag"
|
||||
"k8s.io/kubernetes/pkg/util/logs"
|
||||
"k8s.io/kubernetes/pkg/version/verflag"
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
"fmt"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
_ "k8s.io/kubernetes/pkg/client/metrics/prometheus" // for client metric registration
|
||||
"k8s.io/kubernetes/pkg/client/record"
|
||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
clientset "k8s.io/kubernetes/pkg/client/unversioned/adapters/internalclientset"
|
||||
|
|
|
@ -19,6 +19,8 @@ package main
|
|||
|
||||
import (
|
||||
"os"
|
||||
|
||||
_ "k8s.io/kubernetes/pkg/client/metrics/prometheus" // for client metric registration
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
|
|
@ -74,6 +74,8 @@ pkg/apis/imagepolicy/install
|
|||
pkg/api/v1
|
||||
pkg/auth/authenticator
|
||||
pkg/auth/authorizer/union
|
||||
pkg/client/metrics
|
||||
pkg/client/metrics/prometheus
|
||||
pkg/client/testing/core
|
||||
pkg/client/unversioned
|
||||
pkg/client/unversioned/adapters/internalclientset
|
||||
|
|
|
@ -14,54 +14,48 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package metrics provides utilities for registering client metrics to Prometheus.
|
||||
// Package metrics provides abstractions for registering which metrics
|
||||
// to record.
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const restClientSubsystem = "rest_client"
|
||||
|
||||
var (
|
||||
// RequestLatency is a Prometheus Summary metric type partitioned by
|
||||
// "verb" and "url" labels. It is used for the rest client latency metrics.
|
||||
RequestLatency = prometheus.NewSummaryVec(
|
||||
prometheus.SummaryOpts{
|
||||
Subsystem: restClientSubsystem,
|
||||
Name: "request_latency_microseconds",
|
||||
Help: "Request latency in microseconds. Broken down by verb and URL",
|
||||
MaxAge: time.Hour,
|
||||
},
|
||||
[]string{"verb", "url"},
|
||||
)
|
||||
|
||||
RequestResult = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Subsystem: restClientSubsystem,
|
||||
Name: "request_status_codes",
|
||||
Help: "Number of http requests, partitioned by metadata",
|
||||
},
|
||||
[]string{"code", "method", "host"},
|
||||
)
|
||||
)
|
||||
|
||||
var registerMetrics sync.Once
|
||||
|
||||
// Register registers all metrics to Prometheus with
|
||||
// respect to the RequestLatency.
|
||||
func Register() {
|
||||
// Register the metrics.
|
||||
// LatencyMetric observes client latency partitioned by verb and url.
|
||||
type LatencyMetric interface {
|
||||
Observe(verb string, u url.URL, latency time.Duration)
|
||||
}
|
||||
|
||||
// ResultMetric counts response codes partitioned by method and host.
|
||||
type ResultMetric interface {
|
||||
Increment(code string, method string, host string)
|
||||
}
|
||||
|
||||
var (
|
||||
// RequestLatency is the latency metric that rest clients will update.
|
||||
RequestLatency LatencyMetric = noopLatency{}
|
||||
// RequestResult is the result metric that rest clients will update.
|
||||
RequestResult ResultMetric = noopResult{}
|
||||
)
|
||||
|
||||
// Register registers metrics for the rest client to use. This can
|
||||
// only be called once.
|
||||
func Register(lm LatencyMetric, rm ResultMetric) {
|
||||
registerMetrics.Do(func() {
|
||||
prometheus.MustRegister(RequestLatency)
|
||||
prometheus.MustRegister(RequestResult)
|
||||
RequestLatency = lm
|
||||
RequestResult = rm
|
||||
})
|
||||
}
|
||||
|
||||
// Calculates the time since the specified start in microseconds.
|
||||
func SinceInMicroseconds(start time.Time) float64 {
|
||||
return float64(time.Since(start).Nanoseconds() / time.Microsecond.Nanoseconds())
|
||||
}
|
||||
type noopLatency struct{}
|
||||
|
||||
func (noopLatency) Observe(string, url.URL, time.Duration) {}
|
||||
|
||||
type noopResult struct{}
|
||||
|
||||
func (noopResult) Increment(string, string, string) {}
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package prometheus creates and registers prometheus metrics with
|
||||
// rest clients. To use this package, you just have to import it.
|
||||
package prometheus
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"k8s.io/kubernetes/pkg/client/metrics"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const restClientSubsystem = "rest_client"
|
||||
|
||||
var (
|
||||
// requestLatency is a Prometheus Summary metric type partitioned by
|
||||
// "verb" and "url" labels. It is used for the rest client latency metrics.
|
||||
requestLatency = prometheus.NewSummaryVec(
|
||||
prometheus.SummaryOpts{
|
||||
Subsystem: restClientSubsystem,
|
||||
Name: "request_latency_microseconds",
|
||||
Help: "Request latency in microseconds. Broken down by verb and URL",
|
||||
MaxAge: time.Hour,
|
||||
},
|
||||
[]string{"verb", "url"},
|
||||
)
|
||||
|
||||
requestResult = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Subsystem: restClientSubsystem,
|
||||
Name: "request_status_codes",
|
||||
Help: "Number of http requests, partitioned by metadata",
|
||||
},
|
||||
[]string{"code", "method", "host"},
|
||||
)
|
||||
)
|
||||
|
||||
func init() {
|
||||
prometheus.MustRegister(requestLatency)
|
||||
prometheus.MustRegister(requestResult)
|
||||
metrics.Register(&latencyAdapter{requestLatency}, &resultAdapter{requestResult})
|
||||
}
|
||||
|
||||
type latencyAdapter struct {
|
||||
m *prometheus.SummaryVec
|
||||
}
|
||||
|
||||
func (l *latencyAdapter) Observe(verb string, u url.URL, latency time.Duration) {
|
||||
microseconds := float64(latency) / float64(time.Microsecond)
|
||||
l.m.WithLabelValues(verb, u.String()).Observe(microseconds)
|
||||
}
|
||||
|
||||
type resultAdapter struct {
|
||||
m *prometheus.CounterVec
|
||||
}
|
||||
|
||||
func (r *resultAdapter) Increment(code, method, host string) {
|
||||
r.m.WithLabelValues(code, method, host).Inc()
|
||||
}
|
|
@ -58,10 +58,6 @@ var (
|
|||
longThrottleLatency = 50 * time.Millisecond
|
||||
)
|
||||
|
||||
func init() {
|
||||
metrics.Register()
|
||||
}
|
||||
|
||||
// HTTPClient is an interface for testing a request object.
|
||||
type HTTPClient interface {
|
||||
Do(req *http.Request) (*http.Response, error)
|
||||
|
@ -609,7 +605,7 @@ func (r *Request) URL() *url.URL {
|
|||
// underyling object. This means some useful request info (like the types of field
|
||||
// selectors in use) will be lost.
|
||||
// TODO: preserve field selector keys
|
||||
func (r Request) finalURLTemplate() string {
|
||||
func (r Request) finalURLTemplate() url.URL {
|
||||
if len(r.resourceName) != 0 {
|
||||
r.resourceName = "{name}"
|
||||
}
|
||||
|
@ -622,7 +618,8 @@ func (r Request) finalURLTemplate() string {
|
|||
newParams[k] = v
|
||||
}
|
||||
r.params = newParams
|
||||
return r.URL().String()
|
||||
url := r.URL()
|
||||
return *url
|
||||
}
|
||||
|
||||
func (r *Request) tryThrottle() {
|
||||
|
@ -697,10 +694,10 @@ func updateURLMetrics(req *Request, resp *http.Response, err error) {
|
|||
|
||||
// If we have an error (i.e. apiserver down) we report that as a metric label.
|
||||
if err != nil {
|
||||
metrics.RequestResult.WithLabelValues(err.Error(), req.verb, url).Inc()
|
||||
metrics.RequestResult.Increment(err.Error(), req.verb, url)
|
||||
} else {
|
||||
//Metrics for failure codes
|
||||
metrics.RequestResult.WithLabelValues(strconv.Itoa(resp.StatusCode), req.verb, url).Inc()
|
||||
metrics.RequestResult.Increment(strconv.Itoa(resp.StatusCode), req.verb, url)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -775,7 +772,7 @@ func (r *Request) request(fn func(*http.Request, *http.Response)) error {
|
|||
//Metrics for total request latency
|
||||
start := time.Now()
|
||||
defer func() {
|
||||
metrics.RequestLatency.WithLabelValues(r.verb, r.finalURLTemplate()).Observe(metrics.SinceInMicroseconds(start))
|
||||
metrics.RequestLatency.Observe(r.verb, r.finalURLTemplate(), time.Since(start))
|
||||
}()
|
||||
|
||||
if r.err != nil {
|
||||
|
|
|
@ -331,7 +331,8 @@ func TestURLTemplate(t *testing.T) {
|
|||
if full.String() != "http://localhost/pre1/namespaces/ns/r1/nm?p0=v0" {
|
||||
t.Errorf("unexpected initial URL: %s", full)
|
||||
}
|
||||
actual := r.finalURLTemplate()
|
||||
actualURL := r.finalURLTemplate()
|
||||
actual := actualURL.String()
|
||||
expected := "http://localhost/pre1/namespaces/%7Bnamespace%7D/r1/%7Bname%7D?p0=%7Bvalue%7D"
|
||||
if actual != expected {
|
||||
t.Errorf("unexpected URL template: %s %s", actual, expected)
|
||||
|
|
Loading…
Reference in New Issue