[VOL-4291] Rw-core updates for gRPC migration
Change-Id: I8d5a554409115b29318089671ca4e1ab3fa98810
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator.go
index fa53568..e7c0d05 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator.go
@@ -53,15 +53,21 @@
}
func (r *responseWriterDelegator) WriteHeader(code int) {
+ if r.observeWriteHeader != nil && !r.wroteHeader {
+ // Only call observeWriteHeader for the 1st time. It's a bug if
+ // WriteHeader is called more than once, but we want to protect
+ // against it here. Note that we still delegate the WriteHeader
+ // to the original ResponseWriter to not mask the bug from it.
+ r.observeWriteHeader(code)
+ }
r.status = code
r.wroteHeader = true
r.ResponseWriter.WriteHeader(code)
- if r.observeWriteHeader != nil {
- r.observeWriteHeader(code)
- }
}
func (r *responseWriterDelegator) Write(b []byte) (int, error) {
+ // If applicable, call WriteHeader here so that observeWriteHeader is
+ // handled appropriately.
if !r.wroteHeader {
r.WriteHeader(http.StatusOK)
}
@@ -77,17 +83,23 @@
type pusherDelegator struct{ *responseWriterDelegator }
func (d closeNotifierDelegator) CloseNotify() <-chan bool {
- //lint:ignore SA1019 http.CloseNotifier is deprecated but we don't want to
- //remove support from client_golang yet.
+ //nolint:staticcheck // Ignore SA1019. http.CloseNotifier is deprecated but we keep it here to not break existing users.
return d.ResponseWriter.(http.CloseNotifier).CloseNotify()
}
func (d flusherDelegator) Flush() {
+ // If applicable, call WriteHeader here so that observeWriteHeader is
+ // handled appropriately.
+ if !d.wroteHeader {
+ d.WriteHeader(http.StatusOK)
+ }
d.ResponseWriter.(http.Flusher).Flush()
}
func (d hijackerDelegator) Hijack() (net.Conn, *bufio.ReadWriter, error) {
return d.ResponseWriter.(http.Hijacker).Hijack()
}
func (d readerFromDelegator) ReadFrom(re io.Reader) (int64, error) {
+ // If applicable, call WriteHeader here so that observeWriteHeader is
+ // handled appropriately.
if !d.wroteHeader {
d.WriteHeader(http.StatusOK)
}
@@ -335,8 +347,7 @@
}
id := 0
- //lint:ignore SA1019 http.CloseNotifier is deprecated but we don't want to
- //remove support from client_golang yet.
+ //nolint:staticcheck // Ignore SA1019. http.CloseNotifier is deprecated but we keep it here to not break existing users.
if _, ok := w.(http.CloseNotifier); ok {
id += closeNotifier
}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go
index cea5a90..d86d0cf 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go
@@ -99,7 +99,7 @@
inFlightSem = make(chan struct{}, opts.MaxRequestsInFlight)
}
if opts.Registry != nil {
- // Initialize all possibilites that can occur below.
+ // Initialize all possibilities that can occur below.
errCnt.WithLabelValues("gathering")
errCnt.WithLabelValues("encoding")
if err := opts.Registry.Register(errCnt); err != nil {
@@ -144,7 +144,12 @@
}
}
- contentType := expfmt.Negotiate(req.Header)
+ var contentType expfmt.Format
+ if opts.EnableOpenMetrics {
+ contentType = expfmt.NegotiateIncludingOpenMetrics(req.Header)
+ } else {
+ contentType = expfmt.Negotiate(req.Header)
+ }
header := rsp.Header()
header.Set(contentTypeHeader, string(contentType))
@@ -162,28 +167,40 @@
enc := expfmt.NewEncoder(w, contentType)
- var lastErr error
- for _, mf := range mfs {
- if err := enc.Encode(mf); err != nil {
- lastErr = err
- if opts.ErrorLog != nil {
- opts.ErrorLog.Println("error encoding and sending metric family:", err)
- }
- errCnt.WithLabelValues("encoding").Inc()
- switch opts.ErrorHandling {
- case PanicOnError:
- panic(err)
- case ContinueOnError:
- // Handled later.
- case HTTPErrorOnError:
- httpError(rsp, err)
- return
- }
+ // handleError handles the error according to opts.ErrorHandling
+ // and returns true if we have to abort after the handling.
+ handleError := func(err error) bool {
+ if err == nil {
+ return false
}
+ if opts.ErrorLog != nil {
+ opts.ErrorLog.Println("error encoding and sending metric family:", err)
+ }
+ errCnt.WithLabelValues("encoding").Inc()
+ switch opts.ErrorHandling {
+ case PanicOnError:
+ panic(err)
+ case HTTPErrorOnError:
+ // We cannot really send an HTTP error at this
+ // point because we most likely have written
+ // something to rsp already. But at least we can
+ // stop sending.
+ return true
+ }
+ // Do nothing in all other cases, including ContinueOnError.
+ return false
}
- if lastErr != nil {
- httpError(rsp, lastErr)
+ for _, mf := range mfs {
+ if handleError(enc.Encode(mf)) {
+ return
+ }
+ }
+ if closer, ok := enc.(expfmt.Closer); ok {
+ // This in particular takes care of the final "# EOF\n" line for OpenMetrics.
+ if handleError(closer.Close()) {
+ return
+ }
}
})
@@ -255,7 +272,12 @@
// errors are encountered.
const (
// Serve an HTTP status code 500 upon the first error
- // encountered. Report the error message in the body.
+ // encountered. Report the error message in the body. Note that HTTP
+ // errors cannot be served anymore once the beginning of a regular
+ // payload has been sent. Thus, in the (unlikely) case that encoding the
+ // payload into the negotiated wire format fails, serving the response
+ // will simply be aborted. Set an ErrorLog in HandlerOpts to detect
+ // those errors.
HTTPErrorOnError HandlerErrorHandling = iota
// Ignore errors and try to serve as many metrics as possible. However,
// if no metrics can be served, serve an HTTP status code 500 and the
@@ -281,8 +303,12 @@
// HandlerOpts specifies options how to serve metrics via an http.Handler. The
// zero value of HandlerOpts is a reasonable default.
type HandlerOpts struct {
- // ErrorLog specifies an optional logger for errors collecting and
- // serving metrics. If nil, errors are not logged at all.
+ // ErrorLog specifies an optional Logger for errors collecting and
+ // serving metrics. If nil, errors are not logged at all. Note that the
+ // type of a reported error is often prometheus.MultiError, which
+ // formats into a multi-line error string. If you want to avoid the
+ // latter, create a Logger implementation that detects a
+ // prometheus.MultiError and formats the contained errors into one line.
ErrorLog Logger
// ErrorHandling defines how errors are handled. Note that errors are
// logged regardless of the configured ErrorHandling provided ErrorLog
@@ -318,6 +344,16 @@
// away). Until the implementation is improved, it is recommended to
// implement a separate timeout in potentially slow Collectors.
Timeout time.Duration
+ // If true, the experimental OpenMetrics encoding is added to the
+ // possible options during content negotiation. Note that Prometheus
+ // 2.5.0+ will negotiate OpenMetrics as first priority. OpenMetrics is
+ // the only way to transmit exemplars. However, the move to OpenMetrics
+ // is not completely transparent. Most notably, the values of "quantile"
+ // labels of Summaries and "le" labels of Histograms are formatted with
+ // a trailing ".0" if they would otherwise look like integer numbers
+ // (which changes the identity of the resulting series on the Prometheus
+ // server).
+ EnableOpenMetrics bool
}
// gzipAccepted returns whether the client will accept gzip-encoded content.
@@ -334,11 +370,9 @@
}
// httpError removes any content-encoding header and then calls http.Error with
-// the provided error and http.StatusInternalServerErrer. Error contents is
-// supposed to be uncompressed plain text. However, same as with a plain
-// http.Error, any header settings will be void if the header has already been
-// sent. The error message will still be written to the writer, but it will
-// probably be of limited use.
+// the provided error and http.StatusInternalServerError. Error contents is
+// supposed to be uncompressed plain text. Same as with a plain http.Error, this
+// must not be called if the header or any payload has already been sent.
func httpError(rsp http.ResponseWriter, err error) {
rsp.Header().Del(contentEncodingHeader)
http.Error(
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go
index 9db2438..ab037db 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go
@@ -43,14 +43,14 @@
// InstrumentHandlerDuration is a middleware that wraps the provided
// http.Handler to observe the request duration with the provided ObserverVec.
-// The ObserverVec must have zero, one, or two non-const non-curried labels. For
-// those, the only allowed label names are "code" and "method". The function
-// panics otherwise. The Observe method of the Observer in the ObserverVec is
-// called with the request duration in seconds. Partitioning happens by HTTP
-// status code and/or HTTP method if the respective instance label names are
-// present in the ObserverVec. For unpartitioned observations, use an
-// ObserverVec with zero labels. Note that partitioning of Histograms is
-// expensive and should be used judiciously.
+// The ObserverVec must have valid metric and label names and must have zero,
+// one, or two non-const non-curried labels. For those, the only allowed label
+// names are "code" and "method". The function panics otherwise. The Observe
+// method of the Observer in the ObserverVec is called with the request duration
+// in seconds. Partitioning happens by HTTP status code and/or HTTP method if
+// the respective instance label names are present in the ObserverVec. For
+// unpartitioned observations, use an ObserverVec with zero labels. Note that
+// partitioning of Histograms is expensive and should be used judiciously.
//
// If the wrapped Handler does not set a status code, a status code of 200 is assumed.
//
@@ -79,12 +79,13 @@
}
// InstrumentHandlerCounter is a middleware that wraps the provided http.Handler
-// to observe the request result with the provided CounterVec. The CounterVec
-// must have zero, one, or two non-const non-curried labels. For those, the only
-// allowed label names are "code" and "method". The function panics
-// otherwise. Partitioning of the CounterVec happens by HTTP status code and/or
-// HTTP method if the respective instance label names are present in the
-// CounterVec. For unpartitioned counting, use a CounterVec with zero labels.
+// to observe the request result with the provided CounterVec. The CounterVec
+// must have valid metric and label names and must have zero, one, or two
+// non-const non-curried labels. For those, the only allowed label names are
+// "code" and "method". The function panics otherwise. Partitioning of the
+// CounterVec happens by HTTP status code and/or HTTP method if the respective
+// instance label names are present in the CounterVec. For unpartitioned
+// counting, use a CounterVec with zero labels.
//
// If the wrapped Handler does not set a status code, a status code of 200 is assumed.
//
@@ -110,14 +111,15 @@
// InstrumentHandlerTimeToWriteHeader is a middleware that wraps the provided
// http.Handler to observe with the provided ObserverVec the request duration
-// until the response headers are written. The ObserverVec must have zero, one,
-// or two non-const non-curried labels. For those, the only allowed label names
-// are "code" and "method". The function panics otherwise. The Observe method of
-// the Observer in the ObserverVec is called with the request duration in
-// seconds. Partitioning happens by HTTP status code and/or HTTP method if the
-// respective instance label names are present in the ObserverVec. For
-// unpartitioned observations, use an ObserverVec with zero labels. Note that
-// partitioning of Histograms is expensive and should be used judiciously.
+// until the response headers are written. The ObserverVec must have valid
+// metric and label names and must have zero, one, or two non-const non-curried
+// labels. For those, the only allowed label names are "code" and "method". The
+// function panics otherwise. The Observe method of the Observer in the
+// ObserverVec is called with the request duration in seconds. Partitioning
+// happens by HTTP status code and/or HTTP method if the respective instance
+// label names are present in the ObserverVec. For unpartitioned observations,
+// use an ObserverVec with zero labels. Note that partitioning of Histograms is
+// expensive and should be used judiciously.
//
// If the wrapped Handler panics before calling WriteHeader, no value is
// reported.
@@ -139,15 +141,15 @@
}
// InstrumentHandlerRequestSize is a middleware that wraps the provided
-// http.Handler to observe the request size with the provided ObserverVec. The
-// ObserverVec must have zero, one, or two non-const non-curried labels. For
-// those, the only allowed label names are "code" and "method". The function
-// panics otherwise. The Observe method of the Observer in the ObserverVec is
-// called with the request size in bytes. Partitioning happens by HTTP status
-// code and/or HTTP method if the respective instance label names are present in
-// the ObserverVec. For unpartitioned observations, use an ObserverVec with zero
-// labels. Note that partitioning of Histograms is expensive and should be used
-// judiciously.
+// http.Handler to observe the request size with the provided ObserverVec. The
+// ObserverVec must have valid metric and label names and must have zero, one,
+// or two non-const non-curried labels. For those, the only allowed label names
+// are "code" and "method". The function panics otherwise. The Observe method of
+// the Observer in the ObserverVec is called with the request size in
+// bytes. Partitioning happens by HTTP status code and/or HTTP method if the
+// respective instance label names are present in the ObserverVec. For
+// unpartitioned observations, use an ObserverVec with zero labels. Note that
+// partitioning of Histograms is expensive and should be used judiciously.
//
// If the wrapped Handler does not set a status code, a status code of 200 is assumed.
//
@@ -174,15 +176,15 @@
}
// InstrumentHandlerResponseSize is a middleware that wraps the provided
-// http.Handler to observe the response size with the provided ObserverVec. The
-// ObserverVec must have zero, one, or two non-const non-curried labels. For
-// those, the only allowed label names are "code" and "method". The function
-// panics otherwise. The Observe method of the Observer in the ObserverVec is
-// called with the response size in bytes. Partitioning happens by HTTP status
-// code and/or HTTP method if the respective instance label names are present in
-// the ObserverVec. For unpartitioned observations, use an ObserverVec with zero
-// labels. Note that partitioning of Histograms is expensive and should be used
-// judiciously.
+// http.Handler to observe the response size with the provided ObserverVec. The
+// ObserverVec must have valid metric and label names and must have zero, one,
+// or two non-const non-curried labels. For those, the only allowed label names
+// are "code" and "method". The function panics otherwise. The Observe method of
+// the Observer in the ObserverVec is called with the response size in
+// bytes. Partitioning happens by HTTP status code and/or HTTP method if the
+// respective instance label names are present in the ObserverVec. For
+// unpartitioned observations, use an ObserverVec with zero labels. Note that
+// partitioning of Histograms is expensive and should be used judiciously.
//
// If the wrapped Handler does not set a status code, a status code of 200 is assumed.
//
@@ -198,6 +200,11 @@
})
}
+// checkLabels returns whether the provided Collector has a non-const,
+// non-curried label named "code" and/or "method". It panics if the provided
+// Collector does not have a Desc or has more than one Desc or its Desc is
+// invalid. It also panics if the Collector has any non-const, non-curried
+// labels that are not named "code" or "method".
func checkLabels(c prometheus.Collector) (code bool, method bool) {
// TODO(beorn7): Remove this hacky way to check for instance labels
// once Descriptors can have their dimensionality queried.
@@ -225,6 +232,10 @@
close(descc)
+ // Make sure the Collector has a valid Desc by registering it with a
+ // temporary registry.
+ prometheus.NewRegistry().MustRegister(c)
+
// Create a ConstMetric with the Desc. Since we don't know how many
// variable labels there are, try for as long as it needs.
for err := errors.New("dummy"); err != nil; lvs = append(lvs, magicString) {