What it is
The official Go instrumentation library for Prometheus, providing counters, gauges, histograms and summaries plus an HTTP handler to expose them.
Declare metrics, register them, update them in your code, and serve /metrics with promhttp. Labels turn one metric into a dimension you can slice.
Installation
go get github.com/prometheus/client_golang/prometheusGetting started
The smallest useful thing you can do with it, and what each part means.
go
var (
requests = promauto.NewCounterVec(prometheus.CounterOpts{
Name: "http_requests_total",
Help: "Total HTTP requests.",
}, []string{"method", "route", "status"})
duration = promauto.NewHistogramVec(prometheus.HistogramOpts{
Name: "http_request_duration_seconds",
Help: "Request latency.",
Buckets: prometheus.DefBuckets,
}, []string{"route"})
)
func instrument(route string, next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
rec := &statusRecorder{ResponseWriter: w, status: 200}
next(rec, r)
requests.WithLabelValues(r.Method, route, strconv.Itoa(rec.status)).Inc()
duration.WithLabelValues(route).Observe(time.Since(start).Seconds())
}
}
http.Handle("/metrics", promhttp.Handler())Advanced usage
Where the library earns its place over a simpler alternative.
go
queueDepth := promauto.NewGauge(prometheus.GaugeOpts{
Name: "job_queue_depth",
Help: "Jobs currently waiting.",
})
queueDepth.Set(float64(len(queue)))
queueDepth.Inc()
queueDepth.Dec()
// Derive a value only when scraped, rather than tracking it continuously.
promauto.NewGaugeFunc(prometheus.GaugeOpts{
Name: "db_open_connections",
}, func() float64 {
return float64(db.Stats().OpenConnections)
})Errors and fixes
The failures you are most likely to hit, and what actually resolves them.
- duplicate metrics collector registration attempted
- The same metric name was registered twice. Declare metrics once as package-level variables using promauto.
- Prometheus becomes slow or runs out of memory
- Cardinality explosion from a high-variance label. Replace raw paths and IDs with bounded values.
Best practices
- Never use unbounded values such as user IDs, URLs or error messages as label values.
- Follow the naming convention: units in the name, _total suffix for counters.
- Use histograms for latency so you can compute percentiles, not averages.
- Register metrics once at package level; re-registering the same name panics.
Background
Why it exists, and what it was reacting to.
Prometheus itself is written in Go, so its client library is the reference implementation and the default way Go services expose metrics.
