client_golang: github.com/prometheus/client_golang/prometheus/promauto Index | Files

package promauto

import "github.com/prometheus/client_golang/prometheus/promauto"

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

Package Files

auto.go

func NewCounter Uses

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 Uses

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 Uses

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 Uses

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 Uses

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 Uses

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 Uses

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 Uses

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 Uses

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 Uses

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.

Package promauto imports 1 packages (graph) and is imported by 38 packages. Updated 2018-11-07. Refresh now. Tools for package owners.