diff --git a/pkg/cache/metrics_middleware.go b/pkg/cache/metrics_middleware.go index de60dde1c0fa9200f0a7f29829505bb1b7831c33..b2a484513c9d39ec7fd90931aebe69a471eaaae0 100644 --- a/pkg/cache/metrics_middleware.go +++ b/pkg/cache/metrics_middleware.go @@ -6,49 +6,21 @@ import ( ) type metricsMiddleware struct { - cache Cache - hitsTotal prometheus.Counter - missesTotal prometheus.Counter - invalidatesTotal prometheus.Counter + cache Cache + cacheMetrics *metrics.CacheMetrics + serviceName string } // MetricsMiddleware возвращает обертку над кэшем, которая используется для отслеживания количества хитов и промахов в кэше. -// -// subsystem указывает подсистему, к которой принадлежат метрики. -// Значение должно быть уникальным, совпадение разрешено только при совпадении ключей labels. Пустое значение допустимо. -// -// labels - список меток, где каждый элемент метки соответствует парам ключ-значение. Отсутствие допустимо. -// Значения меток должны быть уникальными в рамках одной subsystem. -// -// Метрики записываются в prometheus.DefaultRegisterer -func MetricsMiddleware(cache Cache, subsystem string, labels ...string) Cache { +func MetricsMiddleware(cache Cache, cacheMetrics *metrics.CacheMetrics, serviceName string) Cache { if cache == nil { panic("cannot wrap metrics in cache, cache is nil") } - middleware := &metricsMiddleware{ - cache: cache, - hitsTotal: prometheus.NewCounter(prometheus.CounterOpts{ - Subsystem: subsystem, - Name: "cache_hits_total", - Help: "Количество попаданий в кэш.", - }), - missesTotal: prometheus.NewCounter(prometheus.CounterOpts{ - Subsystem: subsystem, - Name: "cache_misses_total", - Help: "Количество пропусков в кэш.", - }), - invalidatesTotal: prometheus.NewCounter(prometheus.CounterOpts{ - Subsystem: subsystem, - Name: "cache_invalidates_total", - Help: "Количество инвалидаций кэша.", - }), + return &metricsMiddleware{ + cache: cache, + cacheMetrics: cacheMetrics, + serviceName: serviceName, } - prometheus.WrapRegistererWith(metrics.GetLabelsFromKV(labels), prometheus.DefaultRegisterer).MustRegister( - middleware.hitsTotal, - middleware.missesTotal, - middleware.invalidatesTotal, - ) - return middleware } func (c *metricsMiddleware) Set(key, value any) error { @@ -56,16 +28,17 @@ func (c *metricsMiddleware) Set(key, value any) error { } func (c *metricsMiddleware) Get(key any) (any, error) { + labels := prometheus.Labels{"service": c.serviceName} value, err := c.cache.Get(key) if err != nil { - c.missesTotal.Inc() + c.cacheMetrics.MissesTotal.With(labels).Inc() return nil, err } - c.hitsTotal.Inc() + c.cacheMetrics.HitsTotal.With(labels).Inc() return value, nil } func (c *metricsMiddleware) Remove(key any) error { - c.invalidatesTotal.Inc() + c.cacheMetrics.InvalidatesTotal.With(prometheus.Labels{"service": c.serviceName}).Inc() return c.cache.Remove(key) } diff --git a/pkg/metrics/cache.go b/pkg/metrics/cache.go new file mode 100644 index 0000000000000000000000000000000000000000..e2baacb69672b735dc29848e20052f57fbbe6d18 --- /dev/null +++ b/pkg/metrics/cache.go @@ -0,0 +1,38 @@ +package metrics + +import "github.com/prometheus/client_golang/prometheus" + +type CacheMetrics struct { + HitsTotal *prometheus.CounterVec + MissesTotal *prometheus.CounterVec + InvalidatesTotal *prometheus.CounterVec +} + +func NewCacheMetrics(subsystem string) *CacheMetrics { + labelNames := []string{ + "service", + } + metrics := &CacheMetrics{ + HitsTotal: prometheus.NewCounterVec(prometheus.CounterOpts{ + Subsystem: subsystem, + Name: "cache_hits_total", + Help: "Количество попаданий в кэш.", + }, labelNames), + MissesTotal: prometheus.NewCounterVec(prometheus.CounterOpts{ + Subsystem: subsystem, + Name: "cache_misses_total", + Help: "Количество пропусков в кэш.", + }, labelNames), + InvalidatesTotal: prometheus.NewCounterVec(prometheus.CounterOpts{ + Subsystem: subsystem, + Name: "cache_invalidates_total", + Help: "Количество инвалидаций кэша.", + }, labelNames), + } + prometheus.MustRegister( + metrics.HitsTotal, + metrics.MissesTotal, + metrics.InvalidatesTotal, + ) + return metrics +} diff --git a/pkg/metrics/request.go b/pkg/metrics/request.go index d172aba3a0af989f179683363cecf0b27aeb41d8..3ad04152a4c33dc8920d8f40e43f0c3cb99a3306 100644 --- a/pkg/metrics/request.go +++ b/pkg/metrics/request.go @@ -13,7 +13,7 @@ type RequestMetrics struct { // NewRequestMetrics возвращает метрики для подсчета количества удачных/неудачных запросов, а так же длительности ответов. // Метрики записываются в prometheus.DefaultRegisterer func NewRequestMetrics(subsystem string) *RequestMetrics { - requestLabelNames := []string{ + labelNames := []string{ "service", "method", } @@ -22,18 +22,18 @@ func NewRequestMetrics(subsystem string) *RequestMetrics { Subsystem: subsystem, Name: "requests_total", Help: "Количество запросов.", - }, requestLabelNames), + }, labelNames), FailedTotal: prometheus.NewCounterVec(prometheus.CounterOpts{ Subsystem: subsystem, Name: "requests_failed_total", Help: "Количество запросов, вернувших ошибку.", - }, requestLabelNames), + }, labelNames), DurationSeconds: prometheus.NewHistogramVec(prometheus.HistogramOpts{ Subsystem: subsystem, Name: "request_duration_seconds", Help: "Длительность обработки запроса.", Buckets: prometheus.DefBuckets, - }, requestLabelNames), + }, labelNames), } prometheus.MustRegister( metrics.Total,