Monitoreo de aplicaciones Go (Golang): herramientas y bibliotecas
El monitoreo es una parte esencial de la operación en producción de cualquier servicio. Para aplicaciones en Go (Golang), el ecosistema ofrece tanto soluciones integradas como potentes herramientas externas. En este artículo, analizaremos los enfoques principales: desde el perfilado básico hasta la recolección de métricas y el trazado.
1. Herramientas integradas: el paquete expvar
El paquete expvar proporciona un endpoint HTTP simple para publicar variables de estado de la aplicación. No requiere dependencias externas y es ideal para un diagnóstico rápido.
Configuración y uso
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) // El endpoint /debug/vars estará disponible automáticamente http.ListenAndServe(":8080", nil)}Después de ejecutar, vaya a /debug/vars — verá un JSON con métricas, incluyendo el contador de solicitudes, datos de GC y memoria.
2. Prometheus — el estándar de facto para métricas
Prometheus es el sistema de monitoreo más popular para Go. La biblioteca prometheus/client_golang permite exportar métricas en un formato que el servidor Prometheus entiende.
Instalación
go get github.com/prometheus/client_golang/prometheusgo get github.com/prometheus/client_golang/prometheus/promhttpEjemplo: contador e histograma
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 recopilará métricas del endpoint /metrics. Puede agregar alertas en Alertmanager basadas en estos datos.
3. Perfilado con pprof
El paquete net/http/pprof agrega endpoints a la aplicación para el perfilado de CPU, memoria, gorutinas y bloqueos. Es una herramienta indispensable para encontrar cuellos de botella.
Inicio rápido
package main
import ( "log" "net/http" _ "net/http/pprof" // registra los manejadores)
func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Hello, pprof!")) }) log.Fatal(http.ListenAndServe(":6060", nil))}Ahora están disponibles los endpoints:
/debug/pprof/— lista de perfiles/debug/pprof/profile— perfil de CPU/debug/pprof/heap— perfil de memoria/debug/pprof/goroutine— pilas de gorutinas
Analice los perfiles con el comando go tool pprof o vi