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 (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
_ "k8s.io/kubernetes/pkg/client/metrics/prometheus" // for client metric registration
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
|
@ -26,6 +26,7 @@ import (
|
||||||
|
|
||||||
"k8s.io/kubernetes/cmd/kube-apiserver/app"
|
"k8s.io/kubernetes/cmd/kube-apiserver/app"
|
||||||
"k8s.io/kubernetes/cmd/kube-apiserver/app/options"
|
"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/flag"
|
||||||
"k8s.io/kubernetes/pkg/util/logs"
|
"k8s.io/kubernetes/pkg/util/logs"
|
||||||
"k8s.io/kubernetes/pkg/version/verflag"
|
"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"
|
||||||
"k8s.io/kubernetes/cmd/kube-controller-manager/app/options"
|
"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/healthz"
|
||||||
"k8s.io/kubernetes/pkg/util/flag"
|
"k8s.io/kubernetes/pkg/util/flag"
|
||||||
"k8s.io/kubernetes/pkg/util/logs"
|
"k8s.io/kubernetes/pkg/util/logs"
|
||||||
|
|
|
@ -20,6 +20,7 @@ import (
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
"k8s.io/kubernetes/cmd/kube-dns/app"
|
"k8s.io/kubernetes/cmd/kube-dns/app"
|
||||||
"k8s.io/kubernetes/cmd/kube-dns/app/options"
|
"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/flag"
|
||||||
"k8s.io/kubernetes/pkg/util/logs"
|
"k8s.io/kubernetes/pkg/util/logs"
|
||||||
"k8s.io/kubernetes/pkg/version/verflag"
|
"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"
|
||||||
"k8s.io/kubernetes/cmd/kube-proxy/app/options"
|
"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/healthz"
|
||||||
"k8s.io/kubernetes/pkg/util/flag"
|
"k8s.io/kubernetes/pkg/util/flag"
|
||||||
"k8s.io/kubernetes/pkg/util/logs"
|
"k8s.io/kubernetes/pkg/util/logs"
|
||||||
|
|
|
@ -19,6 +19,7 @@ package app
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
_ "k8s.io/kubernetes/pkg/client/metrics/prometheus" // for client metric registration
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd"
|
"k8s.io/kubernetes/pkg/kubectl/cmd"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/util/logs"
|
"k8s.io/kubernetes/pkg/util/logs"
|
||||||
|
|
|
@ -26,6 +26,7 @@ import (
|
||||||
|
|
||||||
"k8s.io/kubernetes/cmd/kubelet/app"
|
"k8s.io/kubernetes/cmd/kubelet/app"
|
||||||
"k8s.io/kubernetes/cmd/kubelet/app/options"
|
"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/flag"
|
||||||
"k8s.io/kubernetes/pkg/util/logs"
|
"k8s.io/kubernetes/pkg/util/logs"
|
||||||
"k8s.io/kubernetes/pkg/version/verflag"
|
"k8s.io/kubernetes/pkg/version/verflag"
|
||||||
|
|
|
@ -20,6 +20,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
_ "k8s.io/kubernetes/pkg/client/metrics/prometheus" // for client metric registration
|
||||||
"k8s.io/kubernetes/pkg/client/record"
|
"k8s.io/kubernetes/pkg/client/record"
|
||||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||||
clientset "k8s.io/kubernetes/pkg/client/unversioned/adapters/internalclientset"
|
clientset "k8s.io/kubernetes/pkg/client/unversioned/adapters/internalclientset"
|
||||||
|
|
|
@ -19,6 +19,8 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
_ "k8s.io/kubernetes/pkg/client/metrics/prometheus" // for client metric registration
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
|
@ -74,6 +74,8 @@ pkg/apis/imagepolicy/install
|
||||||
pkg/api/v1
|
pkg/api/v1
|
||||||
pkg/auth/authenticator
|
pkg/auth/authenticator
|
||||||
pkg/auth/authorizer/union
|
pkg/auth/authorizer/union
|
||||||
|
pkg/client/metrics
|
||||||
|
pkg/client/metrics/prometheus
|
||||||
pkg/client/testing/core
|
pkg/client/testing/core
|
||||||
pkg/client/unversioned
|
pkg/client/unversioned
|
||||||
pkg/client/unversioned/adapters/internalclientset
|
pkg/client/unversioned/adapters/internalclientset
|
||||||
|
|
|
@ -14,54 +14,48 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
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
|
package metrics
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net/url"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"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
|
var registerMetrics sync.Once
|
||||||
|
|
||||||
// Register registers all metrics to Prometheus with
|
// LatencyMetric observes client latency partitioned by verb and url.
|
||||||
// respect to the RequestLatency.
|
type LatencyMetric interface {
|
||||||
func Register() {
|
Observe(verb string, u url.URL, latency time.Duration)
|
||||||
// Register the metrics.
|
}
|
||||||
|
|
||||||
|
// 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() {
|
registerMetrics.Do(func() {
|
||||||
prometheus.MustRegister(RequestLatency)
|
RequestLatency = lm
|
||||||
prometheus.MustRegister(RequestResult)
|
RequestResult = rm
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculates the time since the specified start in microseconds.
|
type noopLatency struct{}
|
||||||
func SinceInMicroseconds(start time.Time) float64 {
|
|
||||||
return float64(time.Since(start).Nanoseconds() / time.Microsecond.Nanoseconds())
|
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
|
longThrottleLatency = 50 * time.Millisecond
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
|
||||||
metrics.Register()
|
|
||||||
}
|
|
||||||
|
|
||||||
// HTTPClient is an interface for testing a request object.
|
// HTTPClient is an interface for testing a request object.
|
||||||
type HTTPClient interface {
|
type HTTPClient interface {
|
||||||
Do(req *http.Request) (*http.Response, error)
|
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
|
// underyling object. This means some useful request info (like the types of field
|
||||||
// selectors in use) will be lost.
|
// selectors in use) will be lost.
|
||||||
// TODO: preserve field selector keys
|
// TODO: preserve field selector keys
|
||||||
func (r Request) finalURLTemplate() string {
|
func (r Request) finalURLTemplate() url.URL {
|
||||||
if len(r.resourceName) != 0 {
|
if len(r.resourceName) != 0 {
|
||||||
r.resourceName = "{name}"
|
r.resourceName = "{name}"
|
||||||
}
|
}
|
||||||
|
@ -622,7 +618,8 @@ func (r Request) finalURLTemplate() string {
|
||||||
newParams[k] = v
|
newParams[k] = v
|
||||||
}
|
}
|
||||||
r.params = newParams
|
r.params = newParams
|
||||||
return r.URL().String()
|
url := r.URL()
|
||||||
|
return *url
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Request) tryThrottle() {
|
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 we have an error (i.e. apiserver down) we report that as a metric label.
|
||||||
if err != nil {
|
if err != nil {
|
||||||
metrics.RequestResult.WithLabelValues(err.Error(), req.verb, url).Inc()
|
metrics.RequestResult.Increment(err.Error(), req.verb, url)
|
||||||
} else {
|
} else {
|
||||||
//Metrics for failure codes
|
//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
|
//Metrics for total request latency
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
defer func() {
|
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 {
|
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" {
|
if full.String() != "http://localhost/pre1/namespaces/ns/r1/nm?p0=v0" {
|
||||||
t.Errorf("unexpected initial URL: %s", full)
|
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"
|
expected := "http://localhost/pre1/namespaces/%7Bnamespace%7D/r1/%7Bname%7D?p0=%7Bvalue%7D"
|
||||||
if actual != expected {
|
if actual != expected {
|
||||||
t.Errorf("unexpected URL template: %s %s", actual, expected)
|
t.Errorf("unexpected URL template: %s %s", actual, expected)
|
||||||
|
|
Loading…
Reference in New Issue