Monitoring Go (Golang) Applications: Tools and Libraries
Monitoring is an integral part of production operation for any service. For Go (Golang) applications, the ecosystem offers both built-in solutions and powerful external tools. In this article, we will cover the main approaches: from basic profiling to metric collection and tracing.
1. Built-in Tools: The expvar Package
The expvar package provides a simple HTTP endpoint for publishing application state variables. It requires no external dependencies and is ideal for quick diagnostics.
Setup and Usage
package main
import ( "expvar" "net/http")
var requestsCount = expvar.NewInt("total_requests")
func handler(w http.ResponseWriter, r *http.Request) { requestsCount.Add(1) w.Write([]byte("OK"))}
func main() { http.HandleFunc("/api", handler) // The /debug/vars endpoint will be available automatically http.ListenAndServe(":8080", nil)}After starting, navigate to /debug/vars — you will see a JSON with metrics, including request count, GC data, and memory.
2. Prometheus — The De Facto Standard for Metrics
Prometheus is the most popular monitoring system for Go. The prometheus/client_golang library allows you to export metrics in a format understandable by the Prometheus server.
Installation
go get github.com/prometheus/client_golang/prometheusgo get github.com/prometheus/client_golang/prometheus/promhttpExample: Counter and Histogram
package main
import ( "net/http" "time"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp")
var ( requestCount = prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "http_requests_total", Help: "Total number of HTTP requests", }, []string{"method", "endpoint"}, ) requestDuration = prometheus.NewHistogramVec( prometheus.HistogramOpts{ Name: "http_request_duration_seconds", Help: "Histogram of request durations", Buckets: prometheus.DefBuckets, }, []string{"method"}, ))
func init() { prometheus.MustRegister(requestCount, requestDuration)}
func handler(w http.ResponseWriter, r *http.Request) { start := time.Now() requestCount.WithLabelValues(r.Method, r.URL.Path).Inc() w.Write([]byte("Hello")) requestDuration.WithLabelValues(r.Method).Observe(time.Since(start).Seconds())}
func main() { http.Handle("/metrics", promhttp.Handler()) http.HandleFunc("/", handler) http.ListenAndServe(":8080", nil)}Prometheus will collect metrics from the /metrics endpoint. You can add alerts in Alertmanager based on this data.
3. Profiling with pprof
The net/http/pprof package adds endpoints to the application for profiling CPU, memory, goroutines, and blocking. This is an indispensable tool for finding bottlenecks.
Quick Start
package main
import ( "log" "net/http" _ "net/http/pprof" // registers handlers)
func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Hello, pprof!")) }) log.Fatal(http.ListenAndServe(":6060", nil))}Now the following endpoints are available:
/debug/pprof/— list of profiles/debug/pprof/profile— CPU profile/debug/pprof/heap— memory profile/debug/pprof/goroutine— goroutine stacks
Analyze profiles using the go tool pprof command or vi
Also in library
Internationalization (i18n) in C# (.NET): A Complete Guide
Rate Limiting in Java: Libraries and Tools for Request Control (Bucket4j, Resilience4j)
Rate Limiting in JavaScript (Node.js): A Complete Guide to the express-rate-limit Library
Working with CSV in TypeScript: Libraries, Parsing, and Data Generation