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  }