mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-13 05:46:16 +00:00
HTTP Client request metrics: consolidating + client->server endpoint label, cleanups
This commit is contained in:
parent
b28339a1dd
commit
072980af14
@ -38,6 +38,15 @@ var (
|
|||||||
},
|
},
|
||||||
[]string{"verb", "url"},
|
[]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
|
||||||
@ -48,6 +57,7 @@ func Register() {
|
|||||||
// Register the metrics.
|
// Register the metrics.
|
||||||
registerMetrics.Do(func() {
|
registerMetrics.Do(func() {
|
||||||
prometheus.MustRegister(RequestLatency)
|
prometheus.MustRegister(RequestLatency)
|
||||||
|
prometheus.MustRegister(RequestResult)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -570,6 +570,7 @@ func (r *Request) Watch() (watch.Interface, error) {
|
|||||||
client = http.DefaultClient
|
client = http.DefaultClient
|
||||||
}
|
}
|
||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
|
updateURLMetrics(r, resp, err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// The watch stream mechanism handles many common partial data errors, so closed
|
// The watch stream mechanism handles many common partial data errors, so closed
|
||||||
// connections can be retried in many cases.
|
// connections can be retried in many cases.
|
||||||
@ -587,6 +588,23 @@ func (r *Request) Watch() (watch.Interface, error) {
|
|||||||
return watch.NewStreamWatcher(watchjson.NewDecoder(resp.Body, r.codec)), nil
|
return watch.NewStreamWatcher(watchjson.NewDecoder(resp.Body, r.codec)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// updateURLMetrics is a convenience function for pushing metrics.
|
||||||
|
// It also handles corner cases for incomplete/invalid request data.
|
||||||
|
func updateURLMetrics(req *Request, resp *http.Response, err error) {
|
||||||
|
url := "none"
|
||||||
|
if req.baseURL != nil {
|
||||||
|
url = req.baseURL.Host
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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()
|
||||||
|
} else {
|
||||||
|
//Metrics for failure codes
|
||||||
|
metrics.RequestResult.WithLabelValues(strconv.Itoa(resp.StatusCode), req.verb, url).Inc()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Stream formats and executes the request, and offers streaming of the response.
|
// Stream formats and executes the request, and offers streaming of the response.
|
||||||
// Returns io.ReadCloser which could be used for streaming of the response, or an error
|
// Returns io.ReadCloser which could be used for streaming of the response, or an error
|
||||||
// Any non-2xx http status code causes an error. If we get a non-2xx code, we try to convert the body into an APIStatus object.
|
// Any non-2xx http status code causes an error. If we get a non-2xx code, we try to convert the body into an APIStatus object.
|
||||||
@ -605,6 +623,7 @@ func (r *Request) Stream() (io.ReadCloser, error) {
|
|||||||
client = http.DefaultClient
|
client = http.DefaultClient
|
||||||
}
|
}
|
||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
|
updateURLMetrics(r, resp, err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -641,6 +660,12 @@ func (r *Request) Stream() (io.ReadCloser, error) {
|
|||||||
// 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
|
||||||
// server - the provided function is responsible for handling server errors.
|
// server - the provided function is responsible for handling server errors.
|
||||||
func (r *Request) request(fn func(*http.Request, *http.Response)) error {
|
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))
|
||||||
|
}()
|
||||||
|
|
||||||
if r.err != nil {
|
if r.err != nil {
|
||||||
return r.err
|
return r.err
|
||||||
}
|
}
|
||||||
@ -671,6 +696,7 @@ func (r *Request) request(fn func(*http.Request, *http.Response)) error {
|
|||||||
req.Header = r.headers
|
req.Header = r.headers
|
||||||
|
|
||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
|
updateURLMetrics(r, resp, err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -704,10 +730,6 @@ func (r *Request) request(fn func(*http.Request, *http.Response)) error {
|
|||||||
// * If the server responds with a status: *errors.StatusError or *errors.UnexpectedObjectError
|
// * If the server responds with a status: *errors.StatusError or *errors.UnexpectedObjectError
|
||||||
// * http.Client.Do errors are returned directly.
|
// * http.Client.Do errors are returned directly.
|
||||||
func (r *Request) Do() Result {
|
func (r *Request) Do() Result {
|
||||||
start := time.Now()
|
|
||||||
defer func() {
|
|
||||||
metrics.RequestLatency.WithLabelValues(r.verb, r.finalURLTemplate()).Observe(metrics.SinceInMicroseconds(start))
|
|
||||||
}()
|
|
||||||
var result Result
|
var result Result
|
||||||
err := r.request(func(req *http.Request, resp *http.Response) {
|
err := r.request(func(req *http.Request, resp *http.Response) {
|
||||||
result = r.transformResponse(resp, req)
|
result = r.transformResponse(resp, req)
|
||||||
@ -720,10 +742,6 @@ func (r *Request) Do() Result {
|
|||||||
|
|
||||||
// DoRaw executes the request but does not process the response body.
|
// DoRaw executes the request but does not process the response body.
|
||||||
func (r *Request) DoRaw() ([]byte, error) {
|
func (r *Request) DoRaw() ([]byte, error) {
|
||||||
start := time.Now()
|
|
||||||
defer func() {
|
|
||||||
metrics.RequestLatency.WithLabelValues(r.verb, r.finalURLTemplate()).Observe(metrics.SinceInMicroseconds(start))
|
|
||||||
}()
|
|
||||||
var result Result
|
var result Result
|
||||||
err := r.request(func(req *http.Request, resp *http.Response) {
|
err := r.request(func(req *http.Request, resp *http.Response) {
|
||||||
result.body, result.err = ioutil.ReadAll(resp.Body)
|
result.body, result.err = ioutil.ReadAll(resp.Body)
|
||||||
|
Loading…
Reference in New Issue
Block a user