metrics/handler_options.go (49 lines of code) (raw):
package metrics
import (
"context"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
// LabelValueFromContext is used to compute the label value from request context.
// Context can be filled with values from request through middleware.
// This matches promhttp.LabelValueFromCtx.
type LabelValueFromContext func(ctx context.Context) string
type labelValueFromContext struct {
name string
valueFn LabelValueFromContext
}
type handlerConfig struct {
// labelValues contains static label values.
labelValues map[string]string
// labelValuesFromContext contains dynamic label values
// which can be set by pull information from the
// context.
labelValuesFromContext []labelValueFromContext
}
// HandlerOption is used to pass options to the HandlerFactory instance.
type HandlerOption func(*handlerConfig)
// applyHandlerOptions applies the options,
// returns the config, plus a slice of promhttp.Option which can be used
// with the prometheus handlers.
func applyHandlerOptions(opts []HandlerOption) (handlerConfig, []promhttp.Option) {
config := handlerConfig{}
for _, v := range opts {
v(&config)
}
var promOpts []promhttp.Option
// Add prometheus options for labels from context
for _, v := range config.labelValuesFromContext {
promOpts = append(promOpts, promhttp.WithLabelFromCtx(v.name, promhttp.LabelValueFromCtx(v.valueFn)))
}
return config, promOpts
}
// applyOptionsToCounterVec will apply the options to a CounterVec instance.
func (c *handlerConfig) applyOptionsToCounterVec(cv *prometheus.CounterVec) *prometheus.CounterVec {
if len(c.labelValues) == 0 {
return cv
}
return cv.MustCurryWith(c.labelValues)
}
// applyOptionsToObserverVec will apply the options to an ObserverVec instance.
func (c *handlerConfig) applyOptionsToObserverVec(cv prometheus.ObserverVec) prometheus.ObserverVec {
if len(c.labelValues) == 0 {
return cv
}
return cv.MustCurryWith(c.labelValues)
}
// WithLabelValues will configure labels values to apply to this handler.
func WithLabelValues(labelValues map[string]string) HandlerOption {
return func(config *handlerConfig) {
config.labelValues = labelValues
}
}
// WithLabelFromContext will configure labels values to apply to this handler,
// allowing for dynamic label values to be added to the standard metrics.
// This is equivalent to promhttp.WithLabelFromCtx.
func WithLabelFromContext(name string, valueFn LabelValueFromContext) HandlerOption {
return func(config *handlerConfig) {
config.labelValuesFromContext = append(config.labelValuesFromContext, labelValueFromContext{name, valueFn})
}
}