Monitoring Go Applications: Libraries and Tools

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

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/promhttp


Example: 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

Recommendations