Стандартный набор метрик prometheus в Go -программе?go-97

При инструментировании Go-приложения для мониторинга с Prometheus обычно используют четыре основных типа метрик, которые покрывают большинство потребностей наблюдения за приложением. Рассмотрим каждый тип с примерами реализации.

1. Счетчики

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

import (
    "github.com/prometheus/client_golang/prometheus"
    "github.com/prometheus/client_golang/prometheus/promauto"
)

var (
    requestsCounter = promauto.NewCounter(prometheus.CounterOpts{
        Name: "http_requests_total",
        Help: "Total number of HTTP requests",
    })

    errorsCounter = promauto.NewCounterVec(prometheus.CounterOpts{
        Name: "http_errors_total",
        Help: "Total number of HTTP errors by type",
    }, []string{"code", "method"})
)

Использование:

requestsCounter.Inc()
errorsCounter.WithLabelValues("500", "POST").Inc()

2. Гетсы

Гетсы - метрики, которые могут как увеличиваться, так и уменьшаться. Показывают текущее состояние.

var (
    memoryUsage = promauto.NewGauge(prometheus.GaugeOpts{
        Name: "memory_usage_bytes",
        Help: "Current memory usage in bytes",
    })

    activeConnections = promauto.NewGaugeVec(prometheus.GaugeOpts{
        Name: "active_connections",
        Help: "Number of active connections",
    }, []string{"protocol"})
)

Использование:

memoryUsage.Set(usedMemory)
activeConnections.WithLabelValues("http").Inc()
activeConnections.WithLabelValues("http").Dec()

3. Гистограммы

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

var (
    requestDuration = promauto.NewHistogram(prometheus.HistogramOpts{
        Name:    "http_request_duration_seconds",
        Help:    "Duration of HTTP requests in seconds",
        Buckets: prometheus.DefBuckets, // Стандартные бакеты
    })

    responseSizes = promauto.NewHistogramVec(prometheus.HistogramOpts{
        Name:    "http_response_size_bytes",
        Help:    "Size of HTTP responses",
        Buckets: []float64{100, 1000, 10000, 100000},
    }, []string{"method"})
)

Использование:

start := time.Now()
// выполнение запроса
requestDuration.Observe(time.Since(start).Seconds())
responseSizes.WithLabelValues("GET").Observe(float64(size))

4. Сводки

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

var (
    requestSummary = promauto.NewSummary(prometheus.SummaryOpts{
        Name: "http_request_summary_seconds",
        Help: "Summary of HTTP request durations",
        Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
    })
)

Стандартный набор метрик для Go-приложения

  1. Runtime метрики (автоматически собираются):
    • Количество горутин
    • Использование памяти
    • GC паузы
    • Количество потоков
import _ "github.com/prometheus/client_golang/prometheus/collectors"
registry.MustRegister(collectors.NewGoCollector())
  1. HTTP метрики:

    • Количество запросов
    • Время выполнения
    • Размеры запросов/ответов
    • Коды ответов
  2. Бизнес-метрики:

    • Количество обработанных элементов
    • Очереди задач
    • Кэш-хиты/миссы
  3. База данных:

    • Время запросов
    • Количество соединений
    • Ошибки запросов

Пример полной инициализации

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"
    "github.com/prometheus/client_golang/prometheus/collectors"
)

var (
    requestsTotal = promauto.NewCounterVec(
        prometheus.CounterOpts{
            Name: "http_requests_total",
            Help: "Total number of HTTP requests",
        },
        []string{"method", "path", "status"},
    )

    requestDuration = promauto.NewHistogramVec(
        prometheus.HistogramOpts{
            Name:    "http_request_duration_seconds",
            Help:    "HTTP request duration distribution",
            Buckets: []float64{0.1, 0.3, 1, 3, 10},
        },
        []string{"method", "path"},
    )
)

func main() {
    // Регистрируем стандартные метрики Go
    prometheus.MustRegister(collectors.NewGoCollector())

    // HTTP handler с инструментацией
    http.Handle("/metrics", promhttp.Handler())
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        start := time.Now()

        // Обработка запроса...

        duration := time.Since(start).Seconds()
        requestDuration.WithLabelValues(r.Method, r.URL.Path).Observe(duration)
        requestsTotal.WithLabelValues(r.Method, r.URL.Path, "200").Inc()
    })

    http.ListenAndServe(":8080", nil)
}

Лучшие практики

  1. Именование метрик:

    • Используйте _total для счетчиков
    • Указывайте единицы измерения (_seconds, _bytes)
    • Используйте нижнее подчеркивание вместо точек
  2. Метки (labels):

    • Не злоупотребляйте количеством меток
    • Избегайте высококардинальных меток (например, user_id)
    • Заранее определите набор возможных значений
  3. Производительность:

    • Используйте promauto для автоматической регистрации
    • Для высоконагруженных участков используйте WithLabelValues вместо With

Резюмируем

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