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  }