Как вы организуете сбор и мониторинг метрик в своих Go-приложениях?

Ответ

Для сбора и мониторинга метрик я использую стек, ставший стандартом в cloud-native разработке: Prometheus + Grafana.

1. Prometheus

Prometheus — это система мониторинга и база данных временных рядов. Она работает по модели pull: сервер Prometheus периодически опрашивает (scrapes) эндпоинт /metrics вашего приложения, чтобы собрать свежие данные.

В Go-приложении это реализуется с помощью библиотеки client_golang.

Основные типы метрик:

  • Counter: Монотонно растущий счетчик (например, общее число HTTP-запросов).
  • Gauge: Значение, которое может увеличиваться и уменьшаться (например, количество активных горутин).
  • Histogram: Распределение значений по корзинам (бакетам) (например, время ответа на запрос).
  • Summary: Похож на гистограмму, но предоставляет квантили на стороне клиента.

Пример кода:

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

var (
    // Создаем счетчик для общего числа HTTP-запросов
    httpRequestsTotal = promauto.NewCounter(prometheus.CounterOpts{
        Name: "myapp_http_requests_total",
        Help: "Total number of HTTP requests.",
    })
)

func myHandler(w http.ResponseWriter, r *http.Request) {
    // Увеличиваем счетчик при каждом вызове
    httpRequestsTotal.Inc()
    w.Write([]byte("Hello, World!"))
}

func main() {
    http.HandleFunc("/", myHandler)
    // Отдаем метрики по эндпоинту /metrics
    http.Handle("/metrics", promhttp.Handler())
    http.ListenAndServe(":8080", nil)
}

2. Grafana

Grafana — это инструмент для визуализации данных из Prometheus (и многих других источников). Она позволяет:

  • Строить красивые и информативные дашборды.
  • Настраивать алертинг при выходе метрик за пороговые значения.

3. OpenTelemetry (OTel)

Это более современный и комплексный подход, который стремится унифицировать сбор метрик, логов и трейсов (signals). OTel может экспортировать данные в Prometheus, Jaeger и другие системы, что делает его гибким решением для построения полной системы observability.

Ответ 18+ 🔞

Слушай, а вот как я обычно за метриками слежу, чтобы понять, что там моё приложение под капотом творит. Стандартный такой стек, все его знают, но от этого не менее охуенный: Prometheus + Grafana.

1. Prometheus — наш главный вышибалка данных

Это, блядь, такая система мониторинга, которая сама лезет к твоему приложению и вытягивает из него цифры. Работает по принципу pull: представь, что это такой навязчивый сосед, который каждые N секунд стучится к тебе на эндпоинт /metrics и спрашивает: «Ну чё там по показаниям?».

В Go для этого есть библиотека client_golang, без неё — нихуя.

Какие бывают метрики, чтобы не путаться:

  • Counter (Счётчик): Только вверх, только хардкор. Например, общее число запросов. Уменьшить его — это как пытаться впихнуть невпихуемое обратно.
  • Gauge (Измеритель): А вот эта штука может и расти, и падать. Типа количество активных горутин — то ползёт вверх, то обваливается, волнение ебать.
  • Histogram (Гистограмма): Раскидывает значения по корзинам. Хочешь знать, сколько запросов обработалось быстрее 100 мс, а сколько медленнее 500? Вот для этого он.
  • Summary (Сводка): Похож на гистограмму, но квантили считает сам, на своей стороне. Хитрый, блядь.

Смотри, как это выглядит в коде, реально просто:

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

var (
    // Создаём счётчик для HTTP-запросов. Имя даём осмысленное, а то потом сам не поймёшь.
    httpRequestsTotal = promauto.NewCounter(prometheus.CounterOpts{
        Name: "myapp_http_requests_total",
        Help: "Total number of HTTP requests.",
    })
)

func myHandler(w http.ResponseWriter, r *http.Request) {
    // На каждый запрос — чик, и счётчик подрос.
    httpRequestsTotal.Inc()
    w.Write([]byte("Hello, World!"))
}

func main() {
    http.HandleFunc("/", myHandler)
    // А это волшебная дверь, куда Prometheus будет стучаться за метриками.
    http.Handle("/metrics", promhttp.Handler())
    http.ListenAndServe(":8080", nil)
}

Вот и вся магия. Запустил — и у тебя уже есть /metrics, который отдаёт кучу цифр. Prometheus их схавает и сохранит.

2. Grafana — чтобы глаза не вытекали

Ну, Prometheus данные собрал, а смотреть на них в его вебинтерфейсе — это, простите, как в экселе графики рисовать. Уныло, блядь.

Grafana — это вот где начинается красота. Берёшь данные из Prometheus и делаешь из них такие дашборды, что хоть начальству показывай. Крутилки, вертелки, графики всякие. А ещё она умеет в алертинг — когда метрика уползла куда не надо, она тебе в слак/телегу/куда угодно вопить начнёт. Очень удобно, когда в три часа ночи что-то падает.

3. OpenTelemetry (OTel) — новый крутой пацан в районе

А это, ёпта, уже следующий уровень. Если Prometheus в основном про метрики, то OTel заточен на всю observability сразу: метрики, логи и трейсы (трассировку). Он как швейцарский нож, блядь.

Главная фишка в том, что он не привязан к одной системе. Настроил в коде сбор данных через OTel, а экспортировать их можешь куда угодно: метрики — в Prometheus, трейсы — в Jaeger. Гибко, модульно, и в тренде, сука. Если проект серьёзный и долгий, присмотреться к нему стоит, а то потом с миграцией будет больно, как от манды с ушами.