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— считает количество запросов, разбивая
Также в библиотеке
Планировщик задач PHP: полное руководство по cron-задачам и Task Scheduler
Стандартная библиотека JavaScript (Node.js): полный обзор
Геолокация и карты в Go: обзор библиотек и примеры кода
Интернационализация (i18n) в TypeScript: библиотека i18next