Как собирать метрики с помощью Prometheus?
Комментарии (2)
Ответ сгенерирован нейросетью и может содержать ошибки
Сбор метрик с помощью Prometheus
Prometheus — это мониторинговая система с открытым исходным кодом, которая собирает метрики по модели pull-based (запрос данных агентом). Для сбора метрик из Go-приложений используется клиентская библиотека prometheus/client_golang.
Основные шаги настройки
1. Установка и импорт библиотеки
go get github.com/prometheus/client_golang
import (
"net/http"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
2. Определение метрик Существует четыре основных типа метрик:
- Counter — монотонно возрастающий счетчик
- Gauge — значение, которое может увеличиваться и уменьшаться
- Histogram — выборки наблюдений (обычно длительности запросов или размеры ответов)
- Summary — аналогичен гистограмме, но вычисляет квантили
var (
// Создаем метрику типа Counter
requestsTotal = prometheus.NewCounter(
prometheus.CounterOpts{
Name: "http_requests_total",
Help: "Total number of HTTP requests",
},
)
// Создаем метрику типа Gauge
activeUsers = prometheus.NewGauge(
prometheus.GaugeOpts{
Name: "active_users",
Help: "Number of active users",
},
)
// Создаем метрику типа Histogram
requestDuration = prometheus.NewHistogram(
prometheus.HistogramOpts{
Name: "http_request_duration_seconds",
Help: "Duration of HTTP requests",
Buckets: prometheus.DefBuckets, // стандартные bucket'ы
},
)
)
3. Регистрация метрик в реестре
func init() {
// Регистрируем метрики в дефолтном реестре
prometheus.MustRegister(requestsTotal)
prometheus.MustRegister(activeUsers)
prometheus.MustRegister(requestDuration)
// Можно регистрировать сразу несколько метрик
prometheus.MustRegister(prometheus.NewBuildInfoCollector())
}
4. Экспозиция метрик через HTTP endpoint
func main() {
// Создаем endpoint для сбора метрик Prometheus
http.Handle("/metrics", promhttp.Handler())
// Пример обновления метрик
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
// Увеличиваем счетчик запросов
requestsTotal.Inc()
// Измеряем длительность запроса
timer := prometheus.NewTimer(requestDuration)
defer timer.ObserveDuration()
// Обновляем gauge
activeUsers.Set(42)
w.Write([]byte("Hello, Prometheus!"))
})
// Запускаем сервер
http.ListenAndServe(":8080", nil)
}
Продвинутые техники
1. Метрики с labels (лейблами)
var (
requestsByMethod = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "http_requests_by_method_total",
Help: "Total HTTP requests by method",
},
[]string{"method", "endpoint"}, // лейблы
)
)
// Использование
requestsByMethod.WithLabelValues("GET", "/api/users").Inc()
requestsByMethod.WithLabelValues("POST", "/api/users").Add(2)
2. Кастомные коллекторы
type CustomCollector struct {
customMetric prometheus.Gauge
}
func NewCustomCollector() *CustomCollector {
return &CustomCollector{
customMetric: prometheus.NewGauge(
prometheus.GaugeOpts{
Name: "custom_metric",
Help: "A custom metric",
},
),
}
}
func (c *CustomCollector) Describe(ch chan<- *prometheus.Desc) {
c.customMetric.Describe(ch)
}
func (c *CustomCollector) Collect(ch chan<- prometheus.Metric) {
// Логика обновления метрики
c.customMetric.Set(calculateValue())
c.customMetric.Collect(ch)
}
3. Middleware для сбора метрик HTTP
func prometheusMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Создаем wrapped response writer для отслеживания статуса
rw := NewResponseWriter(w)
// Замеряем длительность
timer := prometheus.NewTimer(requestDuration)
defer timer.ObserveDuration()
// Увеличиваем счетчики
requestsTotal.Inc()
requestsByMethod.WithLabelValues(r.Method, r.URL.Path).Inc()
next.ServeHTTP(rw, r)
// Метрика по кодам ответа
statusCode := strconv.Itoa(rw.statusCode)
requestsByStatus.WithLabelValues(statusCode, r.Method).Inc()
})
}
Конфигурация Prometheus
prometheus.yml:
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'go_application'
static_configs:
- targets: ['localhost:8080']
metrics_path: '/metrics'
Практические рекомендации
- Именование метрик: используйте
snake_case, суффиксы_total,_seconds,_bytes - Лейблы: не создавайте кардинальность (высокую уникальность) лейблов
- Производительность: используйте
promautoдля автоматической регистрации
var (
metric = promauto.NewCounter(
prometheus.CounterOpts{
Name: "metric_name",
Help: "Metric help",
},
)
)
- Инструментация: используйте готовые инструменты для популярных библиотек
- Pushgateway: для кратковременных задач используйте Pushgateway
import "github.com/prometheus/client_golang/prometheus/push"
pusher := push.New("http://pushgateway:9091", "job_name")
pusher.Collector(requestsTotal)
pusher.Push()
Сбор метрик с Prometheus в Go — это мощный и гибкий инструмент для мониторинга приложений, который при правильной настройке предоставляет глубокую видимость в работу системы и помогает быстро обнаруживать и диагностировать проблемы.