Мониторинг Go приложений: метрики и алерты на продвинутом уровне
Современные Go-приложения требуют не только высокой производительности, но и надёжного мониторинга. Базовый сбор метрик (CPU, память, запросы) — это лишь первый шаг. На продвинутом уровне необходимо внедрять пользовательские метрики, настраивать алерты на основе бизнес-логики и обеспечивать отказоустойчивость. В этой статье мы рассмотрим, как реализовать комплексный мониторинг Go-приложений с помощью Prometheus, Grafana и собственных алертов.
1. Продвинутый сбор метрик в Go с Prometheus
Библиотека prometheus/client_golang позволяет собирать не только стандартные метрики, но и пользовательские. Рассмотрим пример настройки кастомного сборщика метрик для HTTP-сервера.
package main
import (
"net/http"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
var (
requestDuration = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "http_request_duration_seconds",
Help: "Время выполнения HTTP-запросов.",
Buckets: prometheus.DefBuckets,
},
[]string{"method", "path", "status"},
)
activeRequests = prometheus.NewGauge(
prometheus.GaugeOpts{
Name: "http_active_requests_total",
Help: "Текущее количество активных запросов.",
},
)
)
func init() {
prometheus.MustRegister(requestDuration)
prometheus.MustRegister(activeRequests)
}
func metricsMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
activeRequests.Inc()
defer activeRequests.Dec()
timer := prometheus.NewTimer(prometheus.ObserverFunc(func(v float64) {
requestDuration.WithLabelValues(r.Method, r.URL.Path, "200").Observe(v)
}))
defer timer.ObserveDuration()
next.ServeHTTP(w, r)
})
}
func main() {
mux := http.NewServeMux()
mux.Handle("/metrics", promhttp.Handler())
mux.Handle("/api", metricsMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello, Go!"))
})))
http.ListenAndServe(":8080", mux)
}
В этом примере мы создаём гистограмму для длительности запросов и gauge для активных запросов. Использование меток (labels) позволяет детализировать метрики по методам, путям и статусам.
2. Настройка алертов на основе бизнес-логики
Алерты должны быть не только техническими (высокая загрузка CPU), но и бизнесовыми. Например, превышение времени ответа для критического эндпоинта или падение количества успешных транзакций. Конфигурация алертов в Prometheus (файл alerts.yml):
groups:
- name: go_app_alerts
rules:
- alert: HighRequestLatency
expr: http_request_duration_seconds{job="go-app"} > 1.0
for: 5m
labels:
severity: critical
annotations:
summary: "Высокая задержка запроса ({{ $value }}s)"
description: "Эндпоинт {{ $labels.path }} имеет задержку более 1 секунды в течение 5 минут."
- alert: ActiveRequestsSurge
expr: http_active_requests_total{job="go-app"} > 100
for: 2m
labels:
severity: warning
annotations:
summary: "Всплеск активных запросов ({{ $value }})"
description: "Количество активных запросов превысило 100 в течение 2 минут."
- alert: ErrorRateHigh
expr: rate(http_requests_total{status=~"5.."}[5m]) > 0.1
for: 10m
labels:
severity: critical
annotations:
summary: "Высокий уровень ошибок 5xx"
description: "Уровень ошибок превышает 10% за последние 10 минут."
Обратите внимание на использование for — это параметр, определяющий, как долго условие должно выполняться до отправки алерта. Это помогает избежать ложных срабатываний при кратковременных скачках.
3. Интеграция с Grafana: продвинутые дашборды
Grafana позволяет визуализировать метрики и алерты. Для продвинутого мониторинга создайте дашборд, который включает:
- График задержек: перцентили (p50, p95, p99) времени ответа.
- Тепловая карта запросов: распределение запросов по времени и статусам.
- Алерты в реальном времени: панель с активными алертами.
- Мониторинг ресурсов: память, горутины, GC-статистика.
Пример запроса для перцентилей в Grafana (PromQL):
histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket[5m])) by (le, path))
Также настройте уведомления в Grafana через Slack, Telegram или PagerDuty. Для этого используйте встроенные каналы оповещений (Alerting → Contact points).
4. Отказоустойчивость и самодиагностика
Продвинутый мониторинг включает проверку самого мониторинга. Реализуйте в Go-приложении эндпоинт /health, который возвращает статус зависимостей (база данных, кэш, внешние API). Пример:
func healthHandler(w http.ResponseWriter, r *http.Request) {
checks := map[string]bool{
"database": checkDB(),
"cache": checkCache(),
"api": checkExternalAPI(),
}
status := http.StatusOK
for _, ok := range checks {
if !ok {
status = http.StatusServiceUnavailable
break
}
}
w.WriteHeader(status)
json.NewEncoder(w).Encode(checks)
}
Добавьте метрику health_check_status и алерт на её основе. Например, если /health возвращает 503 в течение 1 минуты — отправлять уведомление.
Заключение
Продвинутый мониторинг Go-приложений превращает сырые данные в actionable инсайты. Используйте кастомные метрики Prometheus, настраивайте алерты на основе бизнес-логики, визуализируйте всё в Grafana и не забывайте про самодиагностику. Такой подход позволит не только быстро реагировать на ин