Мониторинг Go приложений: метрики и алерты от А до Я
В современной разработке программного обеспечения мониторинг — это не роскошь, а необходимость. Для приложений на Go (Golang), которые часто используются в высоконагруженных микросервисах и инфраструктурных проектах, грамотно настроенный мониторинг позволяет вовремя обнаружить проблемы, оптимизировать производительность и обеспечить стабильную работу. В этой статье мы разберем, как настроить мониторинг Go приложений с нуля: от сбора базовых метрик до настройки алертов и визуализации в Grafana.
Почему мониторинг важен для Go-приложений?
Go — это компилируемый язык со встроенной поддержкой конкурентности. Приложения на Go часто работают в критически важных системах: от API-шлюзов до баз данных. Без мониторинга вы рискуете:
- Пропустить утечку памяти или горутин
- Не заметить деградацию производительности
- Потерять данные из-за необработанных ошибок
- Получить простои из-за нехватки ресурсов
Правильный мониторинг дает вам полную картину здоровья приложения: от использования CPU и памяти до времени ответа и частоты ошибок.
Основные метрики для мониторинга Go
Прежде чем переходить к инструментам, давайте определим, какие метрики критичны для Go-приложений:
Системные метрики
- CPU usage — загрузка процессора
- Memory usage — потребление памяти (включая heap и stack)
- Goroutines count — количество активных горутин
- GC stats — статистика сборщика мусора (время, количество циклов)
- Open file descriptors — количество открытых файловых дескрипторов
Бизнес-метрики
- Request latency — время ответа (p50, p95, p99)
- Request rate — количество запросов в секунду
- Error rate — процент ошибок
- Database connection pool — состояние пула соединений
Инструменты для мониторинга Go
Стандартный стек для мониторинга Go-приложений включает:
- Prometheus — система сбора и хранения метрик
- Grafana — визуализация и дашборды
- Alertmanager — управление алертами
- Client библиотеки Go — для экспорта метрик
Настройка сбора метрик в Go с Prometheus
Начнем с практики. Для экспорта метрик из Go-приложения мы будем использовать официальную библиотеку prometheus/client_golang.
Шаг 1: Установка зависимостей
go get github.com/prometheus/client_golang/prometheus
go get github.com/prometheus/client_golang/prometheus/promhttp
Шаг 2: Базовый HTTP сервер с метриками
package main
import (
"net/http"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
var (
httpRequestsTotal = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "http_requests_total",
Help: "Total number of HTTP requests",
},
[]string{"method", "endpoint", "status"},
)
httpRequestDuration = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "http_request_duration_seconds",
Help: "Histogram of HTTP request durations",
Buckets: prometheus.DefBuckets,
},
[]string{"method", "endpoint"},
)
)
func init() {
prometheus.MustRegister(httpRequestsTotal)
prometheus.MustRegister(httpRequestDuration)
}
func main() {
http.Handle("/metrics", promhttp.Handler())
http.HandleFunc("/api/users", func(w http.ResponseWriter, r *http.Request) {
timer := prometheus.NewTimer(httpRequestDuration.WithLabelValues(r.Method, "/api/users"))
defer timer.ObserveDuration()
// Ваша бизнес-логика
w.WriteHeader(http.StatusOK)
httpRequestsTotal.WithLabelValues(r.Method, "/api/users", "200").Inc()
})
http.ListenAndServe(":8080", nil)
}
Шаг 3: Добавление Go runtime метрик
Prometheus автоматически предоставляет метрики runtime Go, если зарегистрировать сборщик:
import (
"github.com/prometheus/client_golang/prometheus/collectors"
)
func main() {
// Регистрируем сборщик метрик Go runtime
reg := prometheus.NewRegistry()
reg.MustRegister(collectors.NewGoCollector())
reg.MustRegister(collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}))
http.Handle("/metrics", promhttp.HandlerFor(reg, promhttp.HandlerOpts{}))
}
Настройка алертов в Prometheus и Alertmanager
Сбор метрик — это только половина дела. Нам нужно настроить алерты, чтобы узнавать о проблемах до того, как они станут критическими.
Конфигурация правил алертов (alerts.yml)
groups:
- name: go_app_alerts
rules:
- alert: HighGoroutineCount
expr: go_goroutines > 1000
for: 5m
labels:
severity: warning
annotations:
summary: "High goroutine count in {{ $labels.instance }}"
description: "Goroutine count is {{ $value }} (threshold: 1000)"
- alert: HighMemoryUsage
expr: go_memstats_alloc_bytes / 1024 / 1024 > 500
for: 5m
labels:
severity: critical
annotations:
summary: "High memory usage in {{ $labels.instance }}"
description: "Memory usage is {{ $value }} MB (threshold: 500 MB)"
- alert: HighErrorRate
expr: rate(http_requests_total{status=~"5.."}[5m]) / rate(http_requests_total[5m]) > 0.05
for: 2m
labels:
severity: critical
annotations:
summary: "High error rate for {{ $labels.instance }}"
description: "Error rate is {{ $value | humanizePercentage }}"
Настройка Alertmanager (alertmanager.yml)
route:
receiver: 'default'
routes:
- match:
severity: critical
receiver: 'p