prometheus-paperless-exporter/multicollector.go

63 lines
1.3 KiB
Go
Raw Permalink Normal View History

package main
import (
"context"
"log"
"runtime"
"time"
"github.com/prometheus/client_golang/prometheus"
"golang.org/x/sync/errgroup"
)
type multiCollectorMember interface {
describe(chan<- *prometheus.Desc)
collect(context.Context, chan<- prometheus.Metric) error
}
type multiCollector struct {
// Impose a timeout on collection if non-zero.
timeout time.Duration
members []multiCollectorMember
}
var _ prometheus.Collector = (*multiCollector)(nil)
func newMultiCollector(m ...multiCollectorMember) *multiCollector {
return &multiCollector{
members: m,
}
}
func (c *multiCollector) Describe(ch chan<- *prometheus.Desc) {
for _, i := range c.members {
i.describe(ch)
}
}
func (c *multiCollector) Collect(ch chan<- prometheus.Metric) {
ctx := context.Background()
if c.timeout != 0 {
var cancel context.CancelFunc
ctx, cancel = context.WithTimeout(ctx, c.timeout)
defer cancel()
}
g, ctx := errgroup.WithContext(ctx)
g.SetLimit(runtime.GOMAXPROCS(0))
for _, i := range c.members {
collect := i.collect
g.Go(func() error { return collect(ctx, ch) })
}
if err := g.Wait(); err != nil {
log.Printf("Metrics collection failed: %v", err.Error())
ch <- prometheus.NewInvalidMetric(
prometheus.NewDesc("paperless_error", "Metrics collection failed", nil, nil),
err)
}
}