Prometheus метрики в Go (Golang): полное руководство по мониторингу

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

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

Начать курс

Prometheus метрики в Go (Golang): полное руководство

Prometheus — это система мониторинга с открытым исходным кодом, которая стала стандартом де-факто для сбора и анализа метрик в современных микросервисных архитектурах. В экосистеме Go (Golang) библиотека prometheus/client_golang предоставляет мощный и гибкий инструментарий для инструментирования приложений. В этой статье мы подробно разберём, как добавить метрики Prometheus в ваше Go-приложение, настроить HTTP-эндпоинты и создать собственные типы метрик.

Установка и настройка

Для начала работы необходимо установить официальный клиент Prometheus для Go:

go get github.com/prometheus/client_golang/prometheus
go get github.com/prometheus/client_golang/prometheus/promhttp

Первая библиотека предоставляет ядро для создания и регистрации метрик, вторая — готовый HTTP-обработчик для эндпоинта /metrics.

Базовые типы метрик Prometheus

Prometheus поддерживает четыре основных типа метрик, каждый из которых предназначен для решения конкретных задач:

  • Counter (счётчик) — монотонно возрастающее значение. Идеально подходит для подсчёта количества запросов, ошибок, выполненных задач.
  • Gauge (измеритель) — значение, которое может как увеличиваться, так и уменьшаться. Используется для текущей температуры, количества активных подключений, размера очереди.
  • Histogram (гистограмма) — собирает наблюдения (например, время выполнения запроса) и группирует их в настраиваемые "вёдра" (buckets). Позволяет вычислять квантили.
  • Summary (сводка) — похожа на гистограмму, но вычисляет квантили на стороне приложения. Рекомендуется для случаев, когда квантили критичны для бизнес-логики.

Практический пример: HTTP-сервер с метриками

Создадим простое веб-приложение, которое регистрирует количество запросов, их длительность и текущее количество активных соединений.

package main

import (
    "fmt"
    "net/http"
    "time"

    "github.com/prometheus/client_golang/prometheus"
    "github.com/prometheus/client_golang/prometheus/promhttp"
)

var (
    // Счётчик запросов с метками "method" и "endpoint"
    requestCounter = 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 duration in seconds",
            Buckets: prometheus.DefBuckets, // [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10]
        },
        []string{"method", "endpoint"},
    )

    // Измеритель активных подключений
    activeConnections = prometheus.NewGauge(
        prometheus.GaugeOpts{
            Name: "http_active_connections",
            Help: "Current number of active connections",
        },
    )
)

func init() {
    // Регистрируем метрики в реестре Prometheus
    prometheus.MustRegister(requestCounter)
    prometheus.MustRegister(requestDuration)
    prometheus.MustRegister(activeConnections)
}

// middleware оборачивает каждый HTTP-запрос для сбора метрик
func metricsMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // Увеличиваем счётчик активных подключений
        activeConnections.Inc()
        defer activeConnections.Dec()

        start := time.Now()
        next.ServeHTTP(w, r)
        duration := time.Since(start).Seconds()

        // Записываем метрики запроса
        requestCounter.WithLabelValues(r.Method, r.URL.Path).Inc()
        requestDuration.WithLabelValues(r.Method, r.URL.Path).Observe(duration)
    })
}

func main() {
    // Создаём роутер
    mux := http.NewServeMux()

    // Обработчик для тестового эндпоинта
    mux.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
        time.Sleep(50 * time.Millisecond) // Имитация работы
        fmt.Fprintf(w, "Hello, World!")
    })

    // Эндпоинт для сбора метрик Prometheus
    mux.Handle("/metrics", promhttp.Handler())

    // Оборачиваем весь роутер middleware
    handler := metricsMiddleware(mux)

    fmt.Println("Server started on :8080")
    http.ListenAndServe(":8080", handler)
}

Как это работает

В примере выше мы создали три метрики:

  • http_requests_total — считает количество запросов, разбивая

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