github.com/thanos-io/thanos@v0.32.5/internal/cortex/chunk/cache/instrumented.go (about) 1 // Copyright (c) The Cortex Authors. 2 // Licensed under the Apache License 2.0. 3 4 package cache 5 6 import ( 7 "context" 8 9 ot "github.com/opentracing/opentracing-go" 10 otlog "github.com/opentracing/opentracing-go/log" 11 "github.com/prometheus/client_golang/prometheus" 12 "github.com/prometheus/client_golang/prometheus/promauto" 13 instr "github.com/weaveworks/common/instrument" 14 ) 15 16 // Instrument returns an instrumented cache. 17 func Instrument(name string, cache Cache, reg prometheus.Registerer) Cache { 18 valueSize := promauto.With(reg).NewHistogramVec(prometheus.HistogramOpts{ 19 Namespace: "cortex", 20 Name: "cache_value_size_bytes", 21 Help: "Size of values in the cache.", 22 // Cached chunks are generally in the KBs, but cached index can 23 // get big. Histogram goes from 1KB to 4MB. 24 // 1024 * 4^(7-1) = 4MB 25 Buckets: prometheus.ExponentialBuckets(1024, 4, 7), 26 ConstLabels: prometheus.Labels{"name": name}, 27 }, []string{"method"}) 28 29 return &instrumentedCache{ 30 name: name, 31 Cache: cache, 32 33 requestDuration: instr.NewHistogramCollector(promauto.With(reg).NewHistogramVec(prometheus.HistogramOpts{ 34 Namespace: "cortex", 35 Name: "cache_request_duration_seconds", 36 Help: "Total time spent in seconds doing cache requests.", 37 // Cache requests are very quick: smallest bucket is 16us, biggest is 1s. 38 Buckets: prometheus.ExponentialBuckets(0.000016, 4, 8), 39 ConstLabels: prometheus.Labels{"name": name}, 40 }, []string{"method", "status_code"})), 41 42 fetchedKeys: promauto.With(reg).NewCounter(prometheus.CounterOpts{ 43 Namespace: "cortex", 44 Name: "cache_fetched_keys_total", 45 Help: "Total count of keys requested from cache.", 46 ConstLabels: prometheus.Labels{"name": name}, 47 }), 48 49 hits: promauto.With(reg).NewCounter(prometheus.CounterOpts{ 50 Namespace: "cortex", 51 Name: "cache_hits_total", 52 Help: "Total count of keys found in cache.", 53 ConstLabels: prometheus.Labels{"name": name}, 54 }), 55 56 storedValueSize: valueSize.WithLabelValues("store"), 57 fetchedValueSize: valueSize.WithLabelValues("fetch"), 58 } 59 } 60 61 type instrumentedCache struct { 62 name string 63 Cache 64 65 fetchedKeys, hits prometheus.Counter 66 storedValueSize, fetchedValueSize prometheus.Observer 67 requestDuration *instr.HistogramCollector 68 } 69 70 func (i *instrumentedCache) Store(ctx context.Context, keys []string, bufs [][]byte) { 71 for j := range bufs { 72 i.storedValueSize.Observe(float64(len(bufs[j]))) 73 } 74 75 method := i.name + ".store" 76 _ = instr.CollectedRequest(ctx, method, i.requestDuration, instr.ErrorCode, func(ctx context.Context) error { 77 sp := ot.SpanFromContext(ctx) 78 sp.LogFields(otlog.Int("keys", len(keys))) 79 i.Cache.Store(ctx, keys, bufs) 80 return nil 81 }) 82 } 83 84 func (i *instrumentedCache) Fetch(ctx context.Context, keys []string) ([]string, [][]byte, []string) { 85 var ( 86 found []string 87 bufs [][]byte 88 missing []string 89 method = i.name + ".fetch" 90 ) 91 92 _ = instr.CollectedRequest(ctx, method, i.requestDuration, instr.ErrorCode, func(ctx context.Context) error { 93 sp := ot.SpanFromContext(ctx) 94 sp.LogFields(otlog.Int("keys requested", len(keys))) 95 96 found, bufs, missing = i.Cache.Fetch(ctx, keys) 97 sp.LogFields(otlog.Int("keys found", len(found)), otlog.Int("keys missing", len(keys)-len(found))) 98 return nil 99 }) 100 101 i.fetchedKeys.Add(float64(len(keys))) 102 i.hits.Add(float64(len(found))) 103 for j := range bufs { 104 i.fetchedValueSize.Observe(float64(len(bufs[j]))) 105 } 106 107 return found, bufs, missing 108 } 109 110 func (i *instrumentedCache) Stop() { 111 i.Cache.Stop() 112 }