From 0b93e8a029969a58c6e0b6171cbe71e21759e980 Mon Sep 17 00:00:00 2001
From: Alex Vanin <alexey@nspcc.ru>
Date: Mon, 15 Mar 2021 16:04:13 +0300
Subject: [PATCH] [#426] service/object: Add request duration metrics

Signed-off-by: Alex Vanin <alexey@nspcc.ru>
---
 pkg/services/object/metrics.go | 75 ++++++++++++++++++++++++++++++++++
 1 file changed, 75 insertions(+)

diff --git a/pkg/services/object/metrics.go b/pkg/services/object/metrics.go
index 1252dda65..8a28ea0d4 100644
--- a/pkg/services/object/metrics.go
+++ b/pkg/services/object/metrics.go
@@ -2,6 +2,7 @@ package object
 
 import (
 	"context"
+	"time"
 
 	"github.com/nspcc-dev/neofs-api-go/v2/object"
 	"github.com/prometheus/client_golang/prometheus"
@@ -71,6 +72,58 @@ var (
 	})
 )
 
+// Request duration metrics.
+var (
+	getDuration = prometheus.NewCounter(prometheus.CounterOpts{
+		Namespace: namespace,
+		Subsystem: subsystem,
+		Name:      "get_req_duration",
+		Help:      "Accumulated get request process duration",
+	})
+
+	putDuration = prometheus.NewCounter(prometheus.CounterOpts{
+		Namespace: namespace,
+		Subsystem: subsystem,
+		Name:      "put_req_duration",
+		Help:      "Accumulated put request process duration",
+	})
+
+	headDuration = prometheus.NewCounter(prometheus.CounterOpts{
+		Namespace: namespace,
+		Subsystem: subsystem,
+		Name:      "head_req_duration",
+		Help:      "Accumulated head request process duration",
+	})
+
+	searchDuration = prometheus.NewCounter(prometheus.CounterOpts{
+		Namespace: namespace,
+		Subsystem: subsystem,
+		Name:      "search_req_duration",
+		Help:      "Accumulated search request process duration",
+	})
+
+	deleteDuration = prometheus.NewCounter(prometheus.CounterOpts{
+		Namespace: namespace,
+		Subsystem: subsystem,
+		Name:      "delete_req_duration",
+		Help:      "Accumulated delete request process duration",
+	})
+
+	rangeDuration = prometheus.NewCounter(prometheus.CounterOpts{
+		Namespace: namespace,
+		Subsystem: subsystem,
+		Name:      "range_req_duration",
+		Help:      "Accumulated range request process duration",
+	})
+
+	rangeHashDuration = prometheus.NewCounter(prometheus.CounterOpts{
+		Namespace: namespace,
+		Subsystem: subsystem,
+		Name:      "range_hash_req_duration",
+		Help:      "Accumulated range hash request process duration",
+	})
+)
+
 func registerMetrics() {
 	prometheus.MustRegister(getCounter) // todo: replace with for loop over map
 	prometheus.MustRegister(putCounter)
@@ -79,6 +132,14 @@ func registerMetrics() {
 	prometheus.MustRegister(deleteCounter)
 	prometheus.MustRegister(rangeCounter)
 	prometheus.MustRegister(rangeHashCounter)
+
+	prometheus.MustRegister(getDuration)
+	prometheus.MustRegister(putDuration)
+	prometheus.MustRegister(headDuration)
+	prometheus.MustRegister(searchDuration)
+	prometheus.MustRegister(deleteDuration)
+	prometheus.MustRegister(rangeDuration)
+	prometheus.MustRegister(rangeHashDuration)
 }
 
 func NewMetricCollector(next ServiceServer) *MetricCollector {
@@ -90,56 +151,70 @@ func NewMetricCollector(next ServiceServer) *MetricCollector {
 }
 
 func (m MetricCollector) Get(req *object.GetRequest, stream GetObjectStream) error {
+	t := time.Now()
 	defer func() {
 		getCounter.Inc()
+		getDuration.Add(float64(time.Since(t)))
 	}()
 
 	return m.next.Get(req, stream)
 }
 
 func (m MetricCollector) Put(ctx context.Context) (object.PutObjectStreamer, error) {
+	t := time.Now()
 	defer func() {
 		putCounter.Inc()
+		putDuration.Add(float64(time.Since(t)))
 	}()
 
 	return m.next.Put(ctx)
 }
 
 func (m MetricCollector) Head(ctx context.Context, request *object.HeadRequest) (*object.HeadResponse, error) {
+	t := time.Now()
 	defer func() {
 		headCounter.Inc()
+		headDuration.Add(float64(time.Since(t)))
 	}()
 
 	return m.next.Head(ctx, request)
 }
 
 func (m MetricCollector) Search(req *object.SearchRequest, stream SearchStream) error {
+	t := time.Now()
 	defer func() {
 		searchCounter.Inc()
+		searchDuration.Add(float64(time.Since(t)))
 	}()
 
 	return m.next.Search(req, stream)
 }
 
 func (m MetricCollector) Delete(ctx context.Context, request *object.DeleteRequest) (*object.DeleteResponse, error) {
+	t := time.Now()
 	defer func() {
 		deleteCounter.Inc()
+		deleteDuration.Add(float64(time.Since(t)))
 	}()
 
 	return m.next.Delete(ctx, request)
 }
 
 func (m MetricCollector) GetRange(req *object.GetRangeRequest, stream GetObjectRangeStream) error {
+	t := time.Now()
 	defer func() {
 		rangeCounter.Inc()
+		rangeDuration.Add(float64(time.Since(t)))
 	}()
 
 	return m.next.GetRange(req, stream)
 }
 
 func (m MetricCollector) GetRangeHash(ctx context.Context, request *object.GetRangeHashRequest) (*object.GetRangeHashResponse, error) {
+	t := time.Now()
 	defer func() {
 		rangeHashCounter.Inc()
+		rangeHashDuration.Add(float64(time.Since(t)))
 	}()
 
 	return m.next.GetRangeHash(ctx, request)