Мониторинг приложений Go (Golang): полный обзор инструментов и библиотек
Мониторинг — критически важная часть эксплуатации любого серверного приложения. Для экосистемы Go (Golang) разработано множество инструментов, позволяющих отслеживать производительность, состояние и ошибки в реальном времени. В этой статье мы разберём ключевые библиотеки и подходы для мониторинга Go-приложений, включая Prometheus, expvar, pprof и OpenTelemetry.
Зачем нужен мониторинг Go-приложений?
Go-приложения часто используются для высоконагруженных микросервисов, API-шлюзов и фоновых обработчиков. Без мониторинга вы рискуете пропустить:
- Утечки памяти и горутин;
- Медленные запросы и блокировки;
- Падение производительности под нагрузкой;
- Ошибки подключения к базам данных и внешним сервисам.
1. Prometheus — стандарт сбора метрик
Prometheus — де-факто стандарт для сбора метрик в мире Go. Официальная клиентская библиотека prometheus/client_golang позволяет легко экспортировать метрики в формате Prometheus.
Установка
go get github.com/prometheus/client_golang/prometheus
go get github.com/prometheus/client_golang/prometheus/promhttp
Пример: счётчик запросов и гистограмма времени
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: "Duration of HTTP requests in seconds",
Buckets: prometheus.DefBuckets,
},
[]string{"method", "endpoint"},
)
)
func init() {
prometheus.MustRegister(requestCount, requestDuration)
}
func middleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
next.ServeHTTP(w, r)
duration := time.Since(start).Seconds()
requestCount.WithLabelValues(r.Method, r.URL.Path).Inc()
requestDuration.WithLabelValues(r.Method, r.URL.Path).Observe(duration)
})
}
func main() {
mux := http.NewServeMux()
mux.Handle("/metrics", promhttp.Handler())
mux.Handle("/", middleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello, World!"))
})))
http.ListenAndServe(":8080", mux)
}
После запуска метрики будут доступны по адресу http://localhost:8080/metrics. Prometheus настроит сбор с этого эндпоинта.
2. expvar — встроенный экспорт метрик
Стандартная библиотека Go предлагает пакет expvar для публикации переменных состояния приложения. Он не требует внешних зависимостей.
Пример использования
package main
import (
"expvar"
"net/http"
)
var (
requests = expvar.NewInt("requests_total")
errors = expvar.NewInt("errors_total")
)
func handler(w http.ResponseWriter, r *http.Request) {
requests.Add(1)
// Имитация ошибки
if r.URL.Query().Get("error") == "1" {
errors.Add(1)
w.WriteHeader(http.StatusInternalServerError)
return
}
w.Write([]byte("OK"))
}
func main() {
http.HandleFunc("/debug/vars", expvar.Handler().ServeHTTP)
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}
Метрики доступны по пути /debug/vars в формате JSON. Для интеграции с Prometheus можно использовать prometheus/expvar адаптер.
3. pprof — профилирование производительности
Пакет net/http/pprof позволяет получать профили CPU, памяти, блокировок и горутин в реальном времени.
Подключение
import _ "net/http/pprof"
func main() {
http.ListenAndServe(":8080", nil)
}
После этого доступны эндпоинты:
/debug/pprof/— список профилей;/debug/pprof/heap— профиль памяти;/debug/pprof/profile— CPU профиль (30 секунд);/debug/pprof/goroutine— стек-трейсы всех горутин.
Для анализа можно использовать