Skip to content

Commit 1dc03a7

Browse files
author
beorn7
committed
Replace hashicorp/go-multierror by own implementation
The own implementation is much easier as it only has to serve our one use case.
1 parent f0c45ac commit 1dc03a7

File tree

3 files changed

+32
-13
lines changed

3 files changed

+32
-13
lines changed

prometheus/promhttp/http.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,18 +82,18 @@ func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler {
8282
mfs, err := reg.Gather()
8383
if err != nil {
8484
if opts.ErrorLog != nil {
85-
opts.ErrorLog.Println("error collecting metrics:", err)
85+
opts.ErrorLog.Println("error gathering metrics:", err)
8686
}
8787
switch opts.ErrorHandling {
8888
case PanicOnError:
8989
panic(err)
9090
case ContinueOnError:
9191
if len(mfs) == 0 {
92-
http.Error(w, "No metrics collected, last error:\n\n"+err.Error(), http.StatusInternalServerError)
92+
http.Error(w, "No metrics gathered, last error:\n\n"+err.Error(), http.StatusInternalServerError)
9393
return
9494
}
9595
case HTTPErrorOnError:
96-
http.Error(w, "An error has occurred during metrics collection:\n\n"+err.Error(), http.StatusInternalServerError)
96+
http.Error(w, "An error has occurred during metrics gathering:\n\n"+err.Error(), http.StatusInternalServerError)
9797
return
9898
}
9999
}

prometheus/promhttp/http_test.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,12 @@ func TestHandlerErrorHandling(t *testing.T) {
8888
ErrorLog: logger,
8989
ErrorHandling: PanicOnError,
9090
})
91-
wantMsg := `error collecting metrics: 1 error(s) occurred:
92-
91+
wantMsg := `error gathering metrics: 1 error(s) occurred:
9392
* error collecting metric Desc{fqName: "invalid_metric", help: "not helpful", constLabels: {}, variableLabels: []}: collect error
9493
`
95-
wantErrorBody := `An error has occurred during metrics collection:
94+
wantErrorBody := `An error has occurred during metrics gathering:
9695
9796
1 error(s) occurred:
98-
9997
* error collecting metric Desc{fqName: "invalid_metric", help: "not helpful", constLabels: {}, variableLabels: []}: collect error
10098
`
10199
wantOKBody := `# HELP name docstring

prometheus/registry.go

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@
1414
package prometheus
1515

1616
import (
17+
"bytes"
1718
"errors"
1819
"fmt"
1920
"os"
2021
"sort"
2122
"sync"
2223

2324
"github.com/golang/protobuf/proto"
24-
"github.com/hashicorp/go-multierror"
2525

2626
dto "github.com/prometheus/client_model/go"
2727
)
@@ -220,6 +220,22 @@ func (err AlreadyRegisteredError) Error() string {
220220
return "duplicate metrics collector registration attempted"
221221
}
222222

223+
// MultiError is a slice of errors implementing the error interface. It is used
224+
// by a Gatherer to report multiple errors during MetricFamily gathering.
225+
type MultiError []error
226+
227+
func (errs MultiError) Error() string {
228+
if len(errs) == 0 {
229+
return ""
230+
}
231+
buf := &bytes.Buffer{}
232+
fmt.Fprintf(buf, "%d error(s) occurred:", len(errs))
233+
for _, err := range errs {
234+
fmt.Fprintf(buf, "\n* %s", err)
235+
}
236+
return buf.String()
237+
}
238+
223239
// Registry registers Prometheus collectors, collects their metrics, and gathers
224240
// them into MetricFamilies for exposition. It implements Registerer and
225241
// Gatherer. The zero value is not usable. Create instances with NewRegistry or
@@ -366,7 +382,7 @@ func (r *Registry) Gather() ([]*dto.MetricFamily, error) {
366382
metricChan = make(chan Metric, capMetricChan)
367383
metricHashes = map[uint64]struct{}{}
368384
wg sync.WaitGroup
369-
errs error // The collected errors to return in the end.
385+
errs MultiError // The collected errors to return in the end.
370386
registeredDescIDs map[uint64]struct{} // Only used for pedantic checks
371387
)
372388

@@ -419,7 +435,7 @@ func (r *Registry) Gather() ([]*dto.MetricFamily, error) {
419435
}
420436
dtoMetric := &dto.Metric{}
421437
if err := metric.Write(dtoMetric); err != nil {
422-
errs = multierror.Append(errs, fmt.Errorf(
438+
errs = append(errs, fmt.Errorf(
423439
"error collecting metric %v: %s", desc, err,
424440
))
425441
continue
@@ -438,13 +454,13 @@ func (r *Registry) Gather() ([]*dto.MetricFamily, error) {
438454
case dtoMetric.Histogram != nil:
439455
metricFamily.Type = dto.MetricType_HISTOGRAM.Enum()
440456
default:
441-
errs = multierror.Append(errs, fmt.Errorf(
457+
errs = append(errs, fmt.Errorf(
442458
"empty metric collected: %s", dtoMetric,
443459
))
444460
continue
445461
}
446462
if err := r.checkConsistency(metricFamily, dtoMetric, desc, metricHashes, registeredDescIDs); err != nil {
447-
errs = multierror.Append(errs, err)
463+
errs = append(errs, err)
448464
continue
449465
}
450466
metricFamily.Metric = append(metricFamily.Metric, dtoMetric)
@@ -464,7 +480,7 @@ func (r *Registry) Gather() ([]*dto.MetricFamily, error) {
464480
}
465481
for _, m := range mf.Metric {
466482
if err := r.checkConsistency(existingMF, m, nil, metricHashes, nil); err != nil {
467-
errs = multierror.Append(errs, err)
483+
errs = append(errs, err)
468484
continue
469485
}
470486
existingMF.Metric = append(existingMF.Metric, m)
@@ -493,6 +509,11 @@ func (r *Registry) Gather() ([]*dto.MetricFamily, error) {
493509
for _, name := range names {
494510
result = append(result, metricFamiliesByName[name])
495511
}
512+
// We cannot just `return result, errs`. Even if errs == nil, it will
513+
// not be seen as nil through the error interface.
514+
if len(errs) == 0 {
515+
return result, nil
516+
}
496517
return result, errs
497518
}
498519

0 commit comments

Comments
 (0)