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