При инструментировании Go-приложения для мониторинга с Prometheus обычно используют четыре основных типа метрик, которые покрывают большинство потребностей наблюдения за приложением. Рассмотрим каждый тип с примерами реализации.
Счетчики - монотонно возрастающие метрики, которые можно только увеличивать или сбрасывать в ноль. Идеальны для подсчета событий.
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()
Гетсы - метрики, которые могут как увеличиваться, так и уменьшаться. Показывают текущее состояние.
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()
Гистограммы - измеряют распределение значений, автоматически группируя их в бакеты. Идеальны для измерения времени выполнения.
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))
Сводки - похожи на гистограммы, но вычисляют квантили на клиентской стороне. Менее популярны из-за высокой стоимости вычислений.
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},
})
)
import _ "github.com/prometheus/client_golang/prometheus/collectors"
registry.MustRegister(collectors.NewGoCollector())
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"
"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)
}
Именование метрик:
_total
для счетчиков_seconds
, _bytes
)Метки (labels):
Производительность:
promauto
для автоматической регистрацииWithLabelValues
вместо With
Стандартный набор метрик для Go-приложения включает счетчики, гетсы, гистограммы и сводки, покрывающие как системные показатели (память, горутины), так и бизнес-логику. Правильное инструментирование приложения позволяет оперативно выявлять проблемы и анализировать производительность системы.