Update client_golang to fix promhttp error handling (#6986)

Fixes #6139

Signed-off-by: Julien Pivotto <roidelapluie@inuits.eu>
This commit is contained in:
Julien Pivotto 2020-03-15 00:42:14 +01:00 committed by GitHub
parent a28fa010ee
commit ef138a11c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 24 additions and 21 deletions

2
go.mod
View File

@ -33,7 +33,7 @@ require (
github.com/opentracing/opentracing-go v1.1.0 github.com/opentracing/opentracing-go v1.1.0
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/prometheus/alertmanager v0.20.0 github.com/prometheus/alertmanager v0.20.0
github.com/prometheus/client_golang v1.5.0 github.com/prometheus/client_golang v1.5.1
github.com/prometheus/client_model v0.2.0 github.com/prometheus/client_model v0.2.0
github.com/prometheus/common v0.9.1 github.com/prometheus/common v0.9.1
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da

4
go.sum
View File

@ -459,8 +459,8 @@ github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U= github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U=
github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
github.com/prometheus/client_golang v1.5.0 h1:Ctq0iGpCmr3jeP77kbF2UxgvRwzWWz+4Bh9/vJTyg1A= github.com/prometheus/client_golang v1.5.1 h1:bdHYieyGlH+6OLEk2YQha8THib30KP0/yD0YH9m6xcA=
github.com/prometheus/client_golang v1.5.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=

View File

@ -53,12 +53,16 @@ func (r *responseWriterDelegator) Written() int64 {
} }
func (r *responseWriterDelegator) WriteHeader(code int) { 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.status = code
r.wroteHeader = true r.wroteHeader = true
r.ResponseWriter.WriteHeader(code) r.ResponseWriter.WriteHeader(code)
if r.observeWriteHeader != nil {
r.observeWriteHeader(code)
}
} }
func (r *responseWriterDelegator) Write(b []byte) (int, error) { func (r *responseWriterDelegator) Write(b []byte) (int, error) {

View File

@ -167,15 +167,12 @@ func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler {
enc := expfmt.NewEncoder(w, contentType) enc := expfmt.NewEncoder(w, contentType)
var lastErr error
// handleError handles the error according to opts.ErrorHandling // handleError handles the error according to opts.ErrorHandling
// and returns true if we have to abort after the handling. // and returns true if we have to abort after the handling.
handleError := func(err error) bool { handleError := func(err error) bool {
if err == nil { if err == nil {
return false return false
} }
lastErr = err
if opts.ErrorLog != nil { if opts.ErrorLog != nil {
opts.ErrorLog.Println("error encoding and sending metric family:", err) opts.ErrorLog.Println("error encoding and sending metric family:", err)
} }
@ -184,7 +181,10 @@ func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler {
case PanicOnError: case PanicOnError:
panic(err) panic(err)
case HTTPErrorOnError: case HTTPErrorOnError:
httpError(rsp, err) // 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 return true
} }
// Do nothing in all other cases, including ContinueOnError. // Do nothing in all other cases, including ContinueOnError.
@ -202,10 +202,6 @@ func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler {
return return
} }
} }
if lastErr != nil {
httpError(rsp, lastErr)
}
}) })
if opts.Timeout <= 0 { if opts.Timeout <= 0 {
@ -276,7 +272,12 @@ type HandlerErrorHandling int
// errors are encountered. // errors are encountered.
const ( const (
// Serve an HTTP status code 500 upon the first error // 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 HTTPErrorOnError HandlerErrorHandling = iota
// Ignore errors and try to serve as many metrics as possible. However, // 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 // if no metrics can be served, serve an HTTP status code 500 and the
@ -365,11 +366,9 @@ func gzipAccepted(header http.Header) bool {
} }
// httpError removes any content-encoding header and then calls http.Error with // httpError removes any content-encoding header and then calls http.Error with
// the provided error and http.StatusInternalServerErrer. Error contents is // the provided error and http.StatusInternalServerError. Error contents is
// supposed to be uncompressed plain text. However, same as with a plain // supposed to be uncompressed plain text. Same as with a plain http.Error, this
// http.Error, any header settings will be void if the header has already been // must not be called if the header or any payload has already been sent.
// sent. The error message will still be written to the writer, but it will
// probably be of limited use.
func httpError(rsp http.ResponseWriter, err error) { func httpError(rsp http.ResponseWriter, err error) {
rsp.Header().Del(contentEncodingHeader) rsp.Header().Del(contentEncodingHeader)
http.Error( http.Error(

2
vendor/modules.txt vendored
View File

@ -272,7 +272,7 @@ github.com/opentracing/opentracing-go/log
github.com/pkg/errors github.com/pkg/errors
# github.com/prometheus/alertmanager v0.20.0 # github.com/prometheus/alertmanager v0.20.0
github.com/prometheus/alertmanager/api/v2/models github.com/prometheus/alertmanager/api/v2/models
# github.com/prometheus/client_golang v1.5.0 # github.com/prometheus/client_golang v1.5.1
github.com/prometheus/client_golang/api github.com/prometheus/client_golang/api
github.com/prometheus/client_golang/api/prometheus/v1 github.com/prometheus/client_golang/api/prometheus/v1
github.com/prometheus/client_golang/prometheus github.com/prometheus/client_golang/prometheus