Ответ
Для сбора метрик в Go-приложениях с помощью Prometheus используется официальная клиентская библиотека github.com/prometheus/client_golang
. Процесс состоит из нескольких ключевых шагов:
- Определение и регистрация метрик: Метрики объявляются как глобальные переменные и регистрируются при старте приложения.
- Публикация метрик: Создается HTTP-эндпоинт (обычно
/metrics
), который Prometheus будет опрашивать. - Изменение значений метрик: В коде приложения значения метрик обновляются при наступлении определенных событий (например, при обработке HTTP-запроса).
Пример комплексной реализации:
package main
import (
"net/http"
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
// 1. Определяем метрики
var (
httpRequestsTotal = promauto.NewCounterVec(
prometheus.CounterOpts{
Name: "myapp_http_requests_total",
Help: "Количество всех HTTP-запросов.",
},
[]string{"method", "path"}, // Метки (labels) для детализации
)
httpRequestDuration = promauto.NewHistogram(
prometheus.HistogramOpts{
Name: "myapp_http_request_duration_seconds",
Help: "Гистограмма времени ответа на HTTP-запросы.",
},
)
)
// Middleware для сбора метрик
func prometheusMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
next.ServeHTTP(w, r)
duration := time.Since(start)
// 3. Изменяем значения метрик
httpRequestsTotal.WithLabelValues(r.Method, r.URL.Path).Inc()
httpRequestDuration.Observe(duration.Seconds())
})
}
func main() {
// Регистрация метрик происходит автоматически благодаря promauto
// 2. Публикуем метрики на эндпоинте /metrics
http.Handle("/metrics", promhttp.Handler())
// Оборачиваем наш основной обработчик в middleware
finalHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello, World!"))
})
http.Handle("/", prometheusMiddleware(finalHandler))
http.ListenAndServe(":8080", nil)
}
Основные типы метрик:
Counter
: Монотонно возрастающий счетчик (например, общее число запросов).Gauge
: Значение, которое может как увеличиваться, так и уменьшаться (например, количество активных горутин).Histogram
: Распределение значений по бакетам (корзинам). Позволяет вычислить квантили (например, 95-й перцентиль времени ответа) на стороне сервера Prometheus. Идеально для времени ответа или размера запроса.Summary
: Также измеряет распределение, но вычисляет квантили на стороне клиента. Сложнее в агрегации и более ресурсоемок для приложения.
Лучшие практики:
- Именование: Используйте префикс с названием приложения (
myapp_
) для избежания конфликтов. - Метки (Labels): Используйте метки для добавления контекста (метод, статус код, эндпоинт), но избегайте высокой кардинальности (например, не используйте
user_id
в качестве метки). - Гистограммы для задержек: Для измерения времени ответа всегда предпочитайте
Histogram
, а неSummary
, так как их можно корректно агрегировать в Prometheus.