influxdb/kit/prom/registry.go

66 lines
2.0 KiB
Go

// Package prom provides a wrapper around a prometheus metrics registry
// so that all services are unified in how they expose prometheus metrics.
package prom
import (
"net/http"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"go.uber.org/zap"
)
// PrometheusCollector is the interface for a type to expose prometheus metrics.
// This interface is provided as a convention, so that you can optionally check
// if a type implements it and then pass its collectors to (*Registry).MustRegister.
type PrometheusCollector interface {
// PrometheusCollectors returns a slice of prometheus collectors
// containing metrics for the underlying instance.
PrometheusCollectors() []prometheus.Collector
}
// Registry embeds a prometheus registry and adds a couple convenience methods.
type Registry struct {
*prometheus.Registry
logger *zap.Logger
}
// NewRegistry returns a new registry.
func NewRegistry() *Registry {
return &Registry{
Registry: prometheus.NewRegistry(),
logger: zap.NewNop(),
}
}
// WithLogger sets the logger for the Registry.
// The logger will print any errors that occur while serving metrics over HTTP.
func (r *Registry) WithLogger(l *zap.Logger) {
r.logger = l.With(zap.String("service", "prom_registry"))
}
// HTTPHandler returns an http.Handler for the registry,
// so that the /metrics HTTP handler is uniformly configured across all apps in the platform.
func (r *Registry) HTTPHandler() http.Handler {
opts := promhttp.HandlerOpts{
ErrorLog: promLogger{r: r},
// TODO(mr): decide if we want to set MaxRequestsInFlight or Timeout.
}
return promhttp.HandlerFor(r.Registry, opts)
}
// promLogger satisfies the promhttp.Logger interface with the registry.
// Because normal usage is that WithLogger is called after HTTPHandler,
// we refer to the Registry rather than its logger.
type promLogger struct {
r *Registry
}
var _ promhttp.Logger = (*promLogger)(nil)
// Println implements promhttp.Logger.
func (pl promLogger) Println(v ...interface{}) {
pl.r.logger.Sugar().Info(v...)
}