Prometheus metrics in Go (Golang): a complete guide
Prometheus is an open-source monitoring system that has become the de facto standard for collecting and analyzing metrics in modern microservice architectures. In the Go (Golang) ecosystem, the prometheus/client_golang library provides a powerful and flexible toolkit for instrumenting applications. In this article, we will thoroughly explore how to add Prometheus metrics to your Go application, configure HTTP endpoints, and create custom metric types.
Installation and setup
To get started, you need to install the official Prometheus client for Go:
go get github.com/prometheus/client_golang/prometheusgo get github.com/prometheus/client_golang/prometheus/promhttpThe first library provides the core for creating and registering metrics, the second provides a ready-made HTTP handler for the /metrics endpoint.
Basic Prometheus metric types
Prometheus supports four main metric types, each designed for specific tasks:
- Counter — a monotonically increasing value. Ideal for counting the number of requests, errors, completed tasks.
- Gauge — a value that can both increase and decrease. Used for current temperature, number of active connections, queue size.
- Histogram — collects observations (e.g., request execution time) and groups them into configurable buckets. Allows calculating quantiles.
- Summary — similar to a histogram, but calculates quantiles on the application side. Recommended for cases where quantiles are critical for business logic.
Practical example: HTTP server with metrics
Let's create a simple web application that records the number of requests, their duration, and the current number of active connections.
package main
import ( "fmt" "net/http" "time"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp")
var ( // Request counter with "method" and "endpoint" labels requestCounter = prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "http_requests_total", Help: "Total number of HTTP requests", }, []string{"method", "endpoint"}, )
// Histogram for request duration requestDuration = prometheus.NewHistogramVec( prometheus.HistogramOpts{ Name: "http_request_duration_seconds", Help: "Histogram of request duration in seconds", Buckets: prometheus.DefBuckets, // [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10] }, []string{"method", "endpoint"}, )
// Gauge for active connections activeConnections = prometheus.NewGauge( prometheus.GaugeOpts{ Name: "http_active_connections", Help: "Current number of active connections", }, ))
func init() { // Register metrics in the Prometheus registry prometheus.MustRegister(requestCounter) prometheus.MustRegister(requestDuration) prometheus.MustRegister(activeConnections)}
// middleware wraps each HTTP request to collect metricsfunc metricsMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Increment the active connections counter activeConnections.Inc() defer activeConnections.Dec()
start := time.Now() next.ServeHTTP(w, r) duration := time.Since(start).Seconds()
// Record request metrics requestCounter.WithLabelVal Also in library
Parsing HTML in Swift: SwiftSoup Library for iOS/macOS
Testing in JavaScript (Node.js): Frameworks and Tools
Generating PDF Reports in Go: Library Overview and Code Examples
WireMock.Net C# (.NET) Guide: Mock HTTP Servers & Examples