github.com/treeverse/lakefs@v1.24.1-0.20240520134607-95648127bfb0/pkg/kv/metrics.go (about) 1 package kv 2 3 import ( 4 "context" 5 6 "github.com/prometheus/client_golang/prometheus" 7 "github.com/prometheus/client_golang/prometheus/promauto" 8 ) 9 10 var ( 11 requestDuration = promauto.NewHistogramVec( 12 prometheus.HistogramOpts{ 13 Name: "kv_request_duration_seconds", 14 Help: "request durations for the kv Store", 15 Buckets: []float64{0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10}, 16 }, 17 []string{"type", "operation"}) 18 19 requestFailures = promauto.NewCounterVec(prometheus.CounterOpts{ 20 Name: "kv_request_failures_total", 21 Help: "The total number of errors while working for kv store.", 22 }, []string{"type", "operation"}) 23 ) 24 25 // StoreMetricsWrapper wraps any Store with metrics 26 type StoreMetricsWrapper struct { 27 Store 28 StoreType string 29 } 30 31 func (s *StoreMetricsWrapper) Get(ctx context.Context, partitionKey, key []byte) (*ValueWithPredicate, error) { 32 const operation = "Get" 33 timer := prometheus.NewTimer(requestDuration.WithLabelValues(s.StoreType, operation)) 34 defer timer.ObserveDuration() 35 res, err := s.Store.Get(ctx, partitionKey, key) 36 if err != nil { 37 requestFailures.WithLabelValues(s.StoreType, operation).Inc() 38 } 39 return res, err 40 } 41 42 func (s *StoreMetricsWrapper) Set(ctx context.Context, partitionKey, key, value []byte) error { 43 const operation = "Set" 44 timer := prometheus.NewTimer(requestDuration.WithLabelValues(s.StoreType, operation)) 45 defer timer.ObserveDuration() 46 err := s.Store.Set(ctx, partitionKey, key, value) 47 if err != nil { 48 requestFailures.WithLabelValues(s.StoreType, operation).Inc() 49 } 50 return err 51 } 52 53 func (s *StoreMetricsWrapper) SetIf(ctx context.Context, partitionKey, key, value []byte, valuePredicate Predicate) error { 54 const operation = "SetIf" 55 timer := prometheus.NewTimer(requestDuration.WithLabelValues(s.StoreType, operation)) 56 defer timer.ObserveDuration() 57 err := s.Store.SetIf(ctx, partitionKey, key, value, valuePredicate) 58 if err != nil { 59 requestFailures.WithLabelValues(s.StoreType, operation).Inc() 60 } 61 return err 62 } 63 64 func (s *StoreMetricsWrapper) Delete(ctx context.Context, partitionKey, key []byte) error { 65 const operation = "Delete" 66 timer := prometheus.NewTimer(requestDuration.WithLabelValues(s.StoreType, operation)) 67 defer timer.ObserveDuration() 68 err := s.Store.Delete(ctx, partitionKey, key) 69 if err != nil { 70 requestFailures.WithLabelValues(s.StoreType, operation).Inc() 71 } 72 return err 73 } 74 75 func (s *StoreMetricsWrapper) Scan(ctx context.Context, partitionKey []byte, options ScanOptions) (EntriesIterator, error) { 76 const operation = "Scan" 77 timer := prometheus.NewTimer(requestDuration.WithLabelValues(s.StoreType, operation)) 78 defer timer.ObserveDuration() 79 res, err := s.Store.Scan(ctx, partitionKey, options) 80 if err != nil { 81 requestFailures.WithLabelValues(s.StoreType, operation).Inc() 82 } 83 return res, err 84 } 85 86 func (s *StoreMetricsWrapper) Close() { 87 timer := prometheus.NewTimer(requestDuration.WithLabelValues(s.StoreType, "Close")) 88 defer timer.ObserveDuration() 89 s.Store.Close() 90 } 91 92 func storeMetrics(store Store, storeType string) *StoreMetricsWrapper { 93 return &StoreMetricsWrapper{Store: store, StoreType: storeType} 94 }