Replace hashicorp/go-multierror by own implementation
The own implementation is much easier as it only has to serve our one use case.
This commit is contained in:
parent
f0c45acc50
commit
1dc03a72f6
|
@ -82,18 +82,18 @@ func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler {
|
|||
mfs, err := reg.Gather()
|
||||
if err != nil {
|
||||
if opts.ErrorLog != nil {
|
||||
opts.ErrorLog.Println("error collecting metrics:", err)
|
||||
opts.ErrorLog.Println("error gathering metrics:", err)
|
||||
}
|
||||
switch opts.ErrorHandling {
|
||||
case PanicOnError:
|
||||
panic(err)
|
||||
case ContinueOnError:
|
||||
if len(mfs) == 0 {
|
||||
http.Error(w, "No metrics collected, last error:\n\n"+err.Error(), http.StatusInternalServerError)
|
||||
http.Error(w, "No metrics gathered, last error:\n\n"+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
case HTTPErrorOnError:
|
||||
http.Error(w, "An error has occurred during metrics collection:\n\n"+err.Error(), http.StatusInternalServerError)
|
||||
http.Error(w, "An error has occurred during metrics gathering:\n\n"+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,14 +88,12 @@ func TestHandlerErrorHandling(t *testing.T) {
|
|||
ErrorLog: logger,
|
||||
ErrorHandling: PanicOnError,
|
||||
})
|
||||
wantMsg := `error collecting metrics: 1 error(s) occurred:
|
||||
|
||||
wantMsg := `error gathering metrics: 1 error(s) occurred:
|
||||
* error collecting metric Desc{fqName: "invalid_metric", help: "not helpful", constLabels: {}, variableLabels: []}: collect error
|
||||
`
|
||||
wantErrorBody := `An error has occurred during metrics collection:
|
||||
wantErrorBody := `An error has occurred during metrics gathering:
|
||||
|
||||
1 error(s) occurred:
|
||||
|
||||
* error collecting metric Desc{fqName: "invalid_metric", help: "not helpful", constLabels: {}, variableLabels: []}: collect error
|
||||
`
|
||||
wantOKBody := `# HELP name docstring
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
package prometheus
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
|
@ -21,7 +22,6 @@ import (
|
|||
"sync"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
|
||||
dto "github.com/prometheus/client_model/go"
|
||||
)
|
||||
|
@ -220,6 +220,22 @@ func (err AlreadyRegisteredError) Error() string {
|
|||
return "duplicate metrics collector registration attempted"
|
||||
}
|
||||
|
||||
// MultiError is a slice of errors implementing the error interface. It is used
|
||||
// by a Gatherer to report multiple errors during MetricFamily gathering.
|
||||
type MultiError []error
|
||||
|
||||
func (errs MultiError) Error() string {
|
||||
if len(errs) == 0 {
|
||||
return ""
|
||||
}
|
||||
buf := &bytes.Buffer{}
|
||||
fmt.Fprintf(buf, "%d error(s) occurred:", len(errs))
|
||||
for _, err := range errs {
|
||||
fmt.Fprintf(buf, "\n* %s", err)
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// Registry registers Prometheus collectors, collects their metrics, and gathers
|
||||
// them into MetricFamilies for exposition. It implements Registerer and
|
||||
// Gatherer. The zero value is not usable. Create instances with NewRegistry or
|
||||
|
@ -366,7 +382,7 @@ func (r *Registry) Gather() ([]*dto.MetricFamily, error) {
|
|||
metricChan = make(chan Metric, capMetricChan)
|
||||
metricHashes = map[uint64]struct{}{}
|
||||
wg sync.WaitGroup
|
||||
errs error // The collected errors to return in the end.
|
||||
errs MultiError // The collected errors to return in the end.
|
||||
registeredDescIDs map[uint64]struct{} // Only used for pedantic checks
|
||||
)
|
||||
|
||||
|
@ -419,7 +435,7 @@ func (r *Registry) Gather() ([]*dto.MetricFamily, error) {
|
|||
}
|
||||
dtoMetric := &dto.Metric{}
|
||||
if err := metric.Write(dtoMetric); err != nil {
|
||||
errs = multierror.Append(errs, fmt.Errorf(
|
||||
errs = append(errs, fmt.Errorf(
|
||||
"error collecting metric %v: %s", desc, err,
|
||||
))
|
||||
continue
|
||||
|
@ -438,13 +454,13 @@ func (r *Registry) Gather() ([]*dto.MetricFamily, error) {
|
|||
case dtoMetric.Histogram != nil:
|
||||
metricFamily.Type = dto.MetricType_HISTOGRAM.Enum()
|
||||
default:
|
||||
errs = multierror.Append(errs, fmt.Errorf(
|
||||
errs = append(errs, fmt.Errorf(
|
||||
"empty metric collected: %s", dtoMetric,
|
||||
))
|
||||
continue
|
||||
}
|
||||
if err := r.checkConsistency(metricFamily, dtoMetric, desc, metricHashes, registeredDescIDs); err != nil {
|
||||
errs = multierror.Append(errs, err)
|
||||
errs = append(errs, err)
|
||||
continue
|
||||
}
|
||||
metricFamily.Metric = append(metricFamily.Metric, dtoMetric)
|
||||
|
@ -464,7 +480,7 @@ func (r *Registry) Gather() ([]*dto.MetricFamily, error) {
|
|||
}
|
||||
for _, m := range mf.Metric {
|
||||
if err := r.checkConsistency(existingMF, m, nil, metricHashes, nil); err != nil {
|
||||
errs = multierror.Append(errs, err)
|
||||
errs = append(errs, err)
|
||||
continue
|
||||
}
|
||||
existingMF.Metric = append(existingMF.Metric, m)
|
||||
|
@ -493,6 +509,11 @@ func (r *Registry) Gather() ([]*dto.MetricFamily, error) {
|
|||
for _, name := range names {
|
||||
result = append(result, metricFamiliesByName[name])
|
||||
}
|
||||
// We cannot just `return result, errs`. Even if errs == nil, it will
|
||||
// not be seen as nil through the error interface.
|
||||
if len(errs) == 0 {
|
||||
return result, nil
|
||||
}
|
||||
return result, errs
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue