Мониторинг Go приложений: метрики и алерты на продвинутом уровне

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Продвинутый мониторинг Go-приложений: от метрик до алертов

В современной разработке на Go (Golang) базового логирования и Health Check недостаточно. Для production-систем требуется глубокая observability: сбор кастомных метрик, их экспорт в Prometheus, визуализация в Grafana и автоматические алерты. В этой статье мы разберём продвинутый уровень мониторинга Go-приложений — от архитектуры метрик до настройки алертов на основе бизнес-логики.

Архитектура мониторинга: Prometheus + Go

Стандартный стек мониторинга для Go включает:

  • Prometheus — система сбора и хранения метрик (pull-модель).
  • Go-клиент Prometheus (prometheus/client_golang) — библиотека для экспорта метрик.
  • Grafana — визуализация дашбордов.
  • Alertmanager — управление алертами (email, Slack, Telegram).

Go-приложение должно предоставлять HTTP-эндпоинт (обычно /metrics), с которого Prometheus забирает данные. Рассмотрим базовую настройку.

package main

import (
    "net/http"
    "github.com/prometheus/client_golang/prometheus"
    "github.com/prometheus/client_golang/prometheus/promhttp"
)

func main() {
    // Регистрация стандартных метрик Go (runtime, GC, goroutines)
    prometheus.MustRegister(prometheus.NewProcessCollector(prometheus.ProcessCollectorOpts{}))
    prometheus.MustRegister(prometheus.NewGoCollector())

    http.Handle("/metrics", promhttp.Handler())
    http.ListenAndServe(":8080", nil)
}

Запустив приложение, вы получите стандартные метрики: go_goroutines, process_cpu_seconds_total, go_memstats_alloc_bytes и другие. Но для продвинутого мониторинга этого недостаточно — нужны кастомные метрики.

Создание кастомных метрик: Gauge, Counter, Histogram

Prometheus поддерживает четыре основных типа метрик. Рассмотрим их на примере Go-приложения, обрабатывающего HTTP-запросы.

Counter (счётчик) — количество событий

Используется для подсчёта запросов, ошибок, выполнения задач.

var requestCounter = prometheus.NewCounterVec(
    prometheus.CounterOpts{
        Name: "http_requests_total",
        Help: "Общее количество HTTP-запросов",
    },
    []string{"method", "endpoint", "status"},
)

func init() {
    prometheus.MustRegister(requestCounter)
}

func handler(w http.ResponseWriter, r *http.Request) {
    // Обработка запроса
    requestCounter.WithLabelValues(r.Method, r.URL.Path, "200").Inc()
}

Gauge (измеритель) — текущие значения

Идеален для мониторинга очередей, пулов соединений, температуры.

var queueSize = prometheus.NewGauge(
    prometheus.GaugeOpts{
        Name: "task_queue_size",
        Help: "Текущий размер очереди задач",
    },
)

func addToQueue() {
    queueSize.Inc()
}

func processFromQueue() {
    queueSize.Dec()
}

Histogram (гистограмма) — распределение значений

Используется для измерения времени ответа или размера данных.

var requestDuration = prometheus.NewHistogramVec(
    prometheus.HistogramOpts{
        Name:    "http_request_duration_seconds",
        Help:    "Гистограмма времени обработки запросов",
        Buckets: prometheus.DefBuckets, // 0.005, 0.01, 0.025, 0.05, ...
    },
    []string{"endpoint"},
)

func measureRequest(endpoint string, duration float64) {
    requestDuration.WithLabelValues(endpoint).Observe(duration)
}

Summary (суммарий) — квантили

Похож на гистограмму, но вычисляет точные квантили (p50, p95, p99).

var requestLatency = prometheus.NewSummaryVec(
    prometheus.SummaryOpts{
        Name:       "http_request_latency_seconds",
        Help:       "Латентность запросов (квантили)",
        Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
    },
    []string{"endpoint"},
)

Продвинутые техники: middleware и бизнес-метрики

Чтобы не загромождать бизнес-логику, обёртывайте сбор метрик в middleware. Пример для net/http:

func MetricsMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        start := time.Now()
        wrapped := &responseWriter{ResponseWriter: w, statusCode: http.StatusOK}
        next.ServeHTTP(wrapped, r)
        duration := time.Since(start).Seconds()

        requestCounter.WithLabelValues(r.Method, r.URL.Path, strconv.Itoa(wrapped.statusCode)).Inc()
        requestDuration.WithLabelValues(r.URL.Path).Observe(duration)
    })
}

type responseWriter struct {
    http.ResponseWriter
    statusCode int
}

func (rw *responseWriter) WriteHeader(code int) {
    rw.statusCode = code
    rw.ResponseWriter.WriteHeader(code)
}

Бизнес-метрики — это метрики, отражающие состояние вашего продукта: количество активных пользователей, скорость обработки транзакций, уровень ошибок в платёжном шлюзе. Например:

var activeUsers = prometheus.NewGauge(prometheus.GaugeOpts{
    Name: "active_users_count",
    Help: "Количество активных пользователей в системе",
})

// В бизнес-слое:
func userLoggedIn() {
    activeUsers.Inc()
}

func userLoggedOut() {
    activeUsers.Dec()
}

Такие метрики позволяют строить алерты не на уровне CPU, а на уровне бизнес-событий.

Настройка алертов: PromQL и Alertmanager

Алерты в Prometheus настраиваются через правила (rules) на языке PromQL. Файл rules.yml:

groups:
  - name: go_app_alerts
    rules:
      - alert: HighRequestLatency
        expr: histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m])) > 1
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Высокая латентность запросов ({{ $value }}s)"

      - alert: TooManyErrors
        expr: rate(http_requests_total{status=~                

Блоги

Рекомендаций по книгам