diff --git a/cache/metercacher/cache.go b/cache/metercacher/cache.go index c2ff666f25e7..f6f9a81abcff 100644 --- a/cache/metercacher/cache.go +++ b/cache/metercacher/cache.go @@ -4,48 +4,55 @@ package metercacher import ( + "time" + "github.com/prometheus/client_golang/prometheus" "github.com/ava-labs/avalanchego/cache" - "github.com/ava-labs/avalanchego/utils/timer/mockable" ) var _ cache.Cacher[struct{}, struct{}] = (*Cache[struct{}, struct{}])(nil) type Cache[K comparable, V any] struct { - metrics cache.Cacher[K, V] - clock mockable.Clock + metrics *metrics } func New[K comparable, V any]( namespace string, registerer prometheus.Registerer, cache cache.Cacher[K, V], -) (cache.Cacher[K, V], error) { - meterCache := &Cache[K, V]{Cacher: cache} - return meterCache, meterCache.metrics.Initialize(namespace, registerer) +) (*Cache[K, V], error) { + metrics, err := newMetrics(namespace, registerer) + return &Cache[K, V]{ + Cacher: cache, + metrics: metrics, + }, err } func (c *Cache[K, V]) Put(key K, value V) { - start := c.clock.Time() + start := time.Now() c.Cacher.Put(key, value) - end := c.clock.Time() - c.put.Observe(float64(end.Sub(start))) - c.len.Set(float64(c.Cacher.Len())) - c.portionFilled.Set(c.Cacher.PortionFilled()) + putDuration := time.Since(start) + + c.metrics.putCount.Inc() + c.metrics.putTime.Add(float64(putDuration)) + c.metrics.len.Set(float64(c.Cacher.Len())) + c.metrics.portionFilled.Set(c.Cacher.PortionFilled()) } func (c *Cache[K, V]) Get(key K) (V, bool) { - start := c.clock.Time() + start := time.Now() value, has := c.Cacher.Get(key) - end := c.clock.Time() - c.get.Observe(float64(end.Sub(start))) + getDuration := time.Since(start) + if has { - c.hit.Inc() + c.metrics.getCount.With(hitLabels).Inc() + c.metrics.getTime.With(hitLabels).Add(float64(getDuration)) } else { - c.miss.Inc() + c.metrics.getCount.With(missLabels).Inc() + c.metrics.getTime.With(missLabels).Add(float64(getDuration)) } return value, has @@ -53,12 +60,14 @@ func (c *Cache[K, V]) Get(key K) (V, bool) { func (c *Cache[K, _]) Evict(key K) { c.Cacher.Evict(key) - c.len.Set(float64(c.Cacher.Len())) - c.portionFilled.Set(c.Cacher.PortionFilled()) + + c.metrics.len.Set(float64(c.Cacher.Len())) + c.metrics.portionFilled.Set(c.Cacher.PortionFilled()) } func (c *Cache[_, _]) Flush() { c.Cacher.Flush() - c.len.Set(float64(c.Cacher.Len())) - c.portionFilled.Set(c.Cacher.PortionFilled()) + + c.metrics.len.Set(float64(c.Cacher.Len())) + c.metrics.portionFilled.Set(c.Cacher.PortionFilled()) } diff --git a/cache/metercacher/metrics.go b/cache/metercacher/metrics.go index 39e0d8066574..7026728a570a 100644 --- a/cache/metercacher/metrics.go +++ b/cache/metercacher/metrics.go @@ -4,67 +4,86 @@ package metercacher import ( - "fmt" - "github.com/prometheus/client_golang/prometheus" - "github.com/ava-labs/avalanchego/utils/metric" - "github.com/ava-labs/avalanchego/utils/wrappers" + "github.com/ava-labs/avalanchego/utils" ) -func newAveragerMetric(namespace, name string, reg prometheus.Registerer, errs *wrappers.Errs) metric.Averager { - return metric.NewAveragerWithErrs( - namespace, - name, - "time (in ns) of a "+name, - reg, - errs, - ) -} +const ( + resultLabel = "result" + hitResult = "hit" + missResult = "miss" +) -func newCounterMetric(namespace, name string, reg prometheus.Registerer, errs *wrappers.Errs) prometheus.Counter { - c := prometheus.NewCounter(prometheus.CounterOpts{ - Namespace: namespace, - Name: name, - Help: fmt.Sprintf("# of times a %s occurred", name), - }) - errs.Add(reg.Register(c)) - return c -} +var ( + resultLabels = []string{resultLabel} + hitLabels = prometheus.Labels{ + resultLabel: hitResult, + } + missLabels = prometheus.Labels{ + resultLabel: missResult, + } +) type metrics struct { - get metric.Averager - put metric.Averager + getCount *prometheus.CounterVec + getTime *prometheus.CounterVec + + putCount prometheus.Counter + putTime prometheus.Counter + len prometheus.Gauge portionFilled prometheus.Gauge - hit prometheus.Counter - miss prometheus.Counter } -func (m *metrics) Initialize( +func newMetrics( namespace string, reg prometheus.Registerer, -) error { - errs := wrappers.Errs{} - m.get = newAveragerMetric(namespace, "get", reg, &errs) - m.put = newAveragerMetric(namespace, "put", reg, &errs) - m.len = prometheus.NewGauge( - prometheus.GaugeOpts{ +) (*metrics, error) { + m := &metrics{ + getCount: prometheus.NewCounterVec( + prometheus.CounterOpts{ + Namespace: namespace, + Name: "get_count", + Help: "number of get calls", + }, + resultLabels, + ), + getTime: prometheus.NewCounterVec( + prometheus.CounterOpts{ + Namespace: namespace, + Name: "get_time", + Help: "time spent (ns) in get calls", + }, + resultLabels, + ), + putCount: prometheus.NewCounter(prometheus.CounterOpts{ + Namespace: namespace, + Name: "put_count", + Help: "number of put calls", + }), + putTime: prometheus.NewCounter(prometheus.CounterOpts{ + Namespace: namespace, + Name: "put_time", + Help: "time spent (ns) in put calls", + }), + len: prometheus.NewGauge(prometheus.GaugeOpts{ Namespace: namespace, Name: "len", Help: "number of entries", - }, - ) - errs.Add(reg.Register(m.len)) - m.portionFilled = prometheus.NewGauge( - prometheus.GaugeOpts{ + }), + portionFilled: prometheus.NewGauge(prometheus.GaugeOpts{ Namespace: namespace, Name: "portion_filled", Help: "fraction of cache filled", - }, + }), + } + return m, utils.Err( + reg.Register(m.getCount), + reg.Register(m.getTime), + reg.Register(m.putCount), + reg.Register(m.putTime), + reg.Register(m.len), + reg.Register(m.portionFilled), ) - errs.Add(reg.Register(m.portionFilled)) - m.hit = newCounterMetric(namespace, "hit", reg, &errs) - m.miss = newCounterMetric(namespace, "miss", reg, &errs) - return errs.Err } diff --git a/vms/components/chain/state_test.go b/vms/components/chain/state_test.go index d1a71beedf63..e4376be502aa 100644 --- a/vms/components/chain/state_test.go +++ b/vms/components/chain/state_test.go @@ -18,7 +18,6 @@ import ( "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/consensus/snowman/snowmantest" "github.com/ava-labs/avalanchego/utils/hashing" - "github.com/ava-labs/avalanchego/utils/metric" ) var ( @@ -532,7 +531,7 @@ func TestMeteredCache(t *testing.T) { _, err := NewMeteredState(registry, config) require.NoError(err) _, err = NewMeteredState(registry, config) - require.ErrorIs(err, metric.ErrFailedRegistering) + require.Error(err) //nolint:forbidigo // error is not exported https://github.com/prometheus/client_golang/blob/main/prometheus/registry.go#L315 } // Test the bytesToIDCache