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,