Documentation ¶
Overview ¶
Package promauto provides constructors for the usual Prometheus metrics that return them already registered with the global registry (prometheus.DefaultRegisterer). This allows very compact code, avoiding any references to the registry altogether, but all the constructors in this package will panic if the registration fails.
The following example is a complete program to create a histogram of normally distributed random numbers from the math/rand package:
package main import ( "math/rand" "net/http" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/client_golang/prometheus/promhttp" ) var histogram = promauto.NewHistogram(prometheus.HistogramOpts{ Name: "random_numbers", Help: "A histogram of normally distributed random numbers.", Buckets: prometheus.LinearBuckets(-3, .1, 61), }) func Random() { for { histogram.Observe(rand.NormFloat64()) } } func main() { go Random() http.Handle("/metrics", promhttp.Handler()) http.ListenAndServe(":1971", nil) }
Prometheus's version of a minimal hello-world program:
package main import ( "fmt" "net/http" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/client_golang/prometheus/promhttp" ) func main() { http.Handle("/", promhttp.InstrumentHandlerCounter( promauto.NewCounterVec( prometheus.CounterOpts{ Name: "hello_requests_total", Help: "Total number of hello-world requests by HTTP code.", }, []string{"code"}, ), http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "Hello, world!") }), )) http.Handle("/metrics", promhttp.Handler()) http.ListenAndServe(":1971", nil) }
This appears very handy. So why are these constructors locked away in a separate package? There are two caveats:
First, in more complex programs, global state is often quite problematic. That's the reason why the metrics constructors in the prometheus package do not interact with the global prometheus.DefaultRegisterer on their own. You are free to use the Register or MustRegister functions to register them with the global prometheus.DefaultRegisterer, but you could as well choose a local Registerer (usually created with prometheus.NewRegistry, but there are other scenarios, e.g. testing).
The second issue is that registration may fail, e.g. if a metric inconsistent with the newly to be registered one is already registered. But how to signal and handle a panic in the automatic registration with the default registry? The only way is panicking. While panicking on invalid input provided by the programmer is certainly fine, things are a bit more subtle in this case: You might just add another package to the program, and that package (in its init function) happens to register a metric with the same name as your code. Now, all of a sudden, either your code or the code of the newly imported package panics, depending on initialization order, without any opportunity to handle the case gracefully. Even worse is a scenario where registration happens later during the runtime (e.g. upon loading some kind of plugin), where the panic could be triggered long after the code has been deployed to production. A possibility to panic should be explicitly called out by the Must… idiom, cf. prometheus.MustRegister. But adding a separate set of constructors in the prometheus package called MustRegisterNewCounterVec or similar would be quite unwieldy. Adding an extra MustRegister method to each metric, returning the registered metric, would result in nice code for those using the method, but would pollute every single metric interface for everybody avoiding the global registry.
To address both issues, the problematic auto-registering and possibly panicking constructors are all in this package with a clear warning ahead. And whoever cares about avoiding global state and possibly panicking function calls can simply ignore the existence of the promauto package altogether.
A final note: There is a similar case in the net/http package of the standard library. It has DefaultServeMux as a global instance of ServeMux, and the Handle function acts on it, panicking if a handler for the same pattern has already been registered. However, one might argue that the whole HTTP routing is usually set up closely together in the same package or file, while Prometheus metrics tend to be spread widely over the codebase, increasing the chance of surprising registration failures. Furthermore, the use of global state in net/http has been criticized widely, and some avoid it altogether.
Index ¶
- func NewCounter(opts prometheus.CounterOpts) prometheus.Counter
- func NewCounterFunc(opts prometheus.CounterOpts, function func() float64) prometheus.CounterFunc
- func NewCounterVec(opts prometheus.CounterOpts, labelNames []string) *prometheus.CounterVec
- func NewGauge(opts prometheus.GaugeOpts) prometheus.Gauge
- func NewGaugeFunc(opts prometheus.GaugeOpts, function func() float64) prometheus.GaugeFunc
- func NewGaugeVec(opts prometheus.GaugeOpts, labelNames []string) *prometheus.GaugeVec
- func NewHistogram(opts prometheus.HistogramOpts) prometheus.Histogram
- func NewHistogramVec(opts prometheus.HistogramOpts, labelNames []string) *prometheus.HistogramVec
- func NewSummary(opts prometheus.SummaryOpts) prometheus.Summary
- func NewSummaryVec(opts prometheus.SummaryOpts, labelNames []string) *prometheus.SummaryVec
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func NewCounter ¶
func NewCounter(opts prometheus.CounterOpts) prometheus.Counter
NewCounter works like the function of the same name in the prometheus package but it automatically registers the Counter with the prometheus.DefaultRegisterer. If the registration fails, NewCounter panics.
func NewCounterFunc ¶
func NewCounterFunc(opts prometheus.CounterOpts, function func() float64) prometheus.CounterFunc
NewCounterFunc works like the function of the same name in the prometheus package but it automatically registers the CounterFunc with the prometheus.DefaultRegisterer. If the registration fails, NewCounterFunc panics.
func NewCounterVec ¶
func NewCounterVec(opts prometheus.CounterOpts, labelNames []string) *prometheus.CounterVec
NewCounterVec works like the function of the same name in the prometheus package but it automatically registers the CounterVec with the prometheus.DefaultRegisterer. If the registration fails, NewCounterVec panics.
func NewGauge ¶
func NewGauge(opts prometheus.GaugeOpts) prometheus.Gauge
NewGauge works like the function of the same name in the prometheus package but it automatically registers the Gauge with the prometheus.DefaultRegisterer. If the registration fails, NewGauge panics.
func NewGaugeFunc ¶
func NewGaugeFunc(opts prometheus.GaugeOpts, function func() float64) prometheus.GaugeFunc
NewGaugeFunc works like the function of the same name in the prometheus package but it automatically registers the GaugeFunc with the prometheus.DefaultRegisterer. If the registration fails, NewGaugeFunc panics.
func NewGaugeVec ¶
func NewGaugeVec(opts prometheus.GaugeOpts, labelNames []string) *prometheus.GaugeVec
NewGaugeVec works like the function of the same name in the prometheus package but it automatically registers the GaugeVec with the prometheus.DefaultRegisterer. If the registration fails, NewGaugeVec panics.
func NewHistogram ¶
func NewHistogram(opts prometheus.HistogramOpts) prometheus.Histogram
NewHistogram works like the function of the same name in the prometheus package but it automatically registers the Histogram with the prometheus.DefaultRegisterer. If the registration fails, NewHistogram panics.
func NewHistogramVec ¶
func NewHistogramVec(opts prometheus.HistogramOpts, labelNames []string) *prometheus.HistogramVec
NewHistogramVec works like the function of the same name in the prometheus package but it automatically registers the HistogramVec with the prometheus.DefaultRegisterer. If the registration fails, NewHistogramVec panics.
func NewSummary ¶
func NewSummary(opts prometheus.SummaryOpts) prometheus.Summary
NewSummary works like the function of the same name in the prometheus package but it automatically registers the Summary with the prometheus.DefaultRegisterer. If the registration fails, NewSummary panics.
func NewSummaryVec ¶
func NewSummaryVec(opts prometheus.SummaryOpts, labelNames []string) *prometheus.SummaryVec
NewSummaryVec works like the function of the same name in the prometheus package but it automatically registers the SummaryVec with the prometheus.DefaultRegisterer. If the registration fails, NewSummaryVec panics.
Types ¶
This section is empty.