github.com/MetalBlockchain/metalgo@v1.11.9/vms/avm/metrics/metrics.go (about)

     1  // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  package metrics
     5  
     6  import (
     7  	"github.com/prometheus/client_golang/prometheus"
     8  
     9  	"github.com/MetalBlockchain/metalgo/utils/metric"
    10  	"github.com/MetalBlockchain/metalgo/utils/wrappers"
    11  	"github.com/MetalBlockchain/metalgo/vms/avm/block"
    12  	"github.com/MetalBlockchain/metalgo/vms/avm/txs"
    13  )
    14  
    15  var _ Metrics = (*metrics)(nil)
    16  
    17  type Metrics interface {
    18  	metric.APIInterceptor
    19  
    20  	IncTxRefreshes()
    21  	IncTxRefreshHits()
    22  	IncTxRefreshMisses()
    23  
    24  	// MarkBlockAccepted updates all metrics relating to the acceptance of a
    25  	// block, including the underlying acceptance of the contained transactions.
    26  	MarkBlockAccepted(b block.Block) error
    27  	// MarkTxAccepted updates all metrics relating to the acceptance of a
    28  	// transaction.
    29  	//
    30  	// Note: This is not intended to be called during the acceptance of a block,
    31  	// as MarkBlockAccepted already handles updating transaction related
    32  	// metrics.
    33  	MarkTxAccepted(tx *txs.Tx) error
    34  }
    35  
    36  type metrics struct {
    37  	txMetrics *txMetrics
    38  
    39  	numTxRefreshes, numTxRefreshHits, numTxRefreshMisses prometheus.Counter
    40  
    41  	metric.APIInterceptor
    42  }
    43  
    44  func (m *metrics) IncTxRefreshes() {
    45  	m.numTxRefreshes.Inc()
    46  }
    47  
    48  func (m *metrics) IncTxRefreshHits() {
    49  	m.numTxRefreshHits.Inc()
    50  }
    51  
    52  func (m *metrics) IncTxRefreshMisses() {
    53  	m.numTxRefreshMisses.Inc()
    54  }
    55  
    56  func (m *metrics) MarkBlockAccepted(b block.Block) error {
    57  	for _, tx := range b.Txs() {
    58  		if err := tx.Unsigned.Visit(m.txMetrics); err != nil {
    59  			return err
    60  		}
    61  	}
    62  	return nil
    63  }
    64  
    65  func (m *metrics) MarkTxAccepted(tx *txs.Tx) error {
    66  	return tx.Unsigned.Visit(m.txMetrics)
    67  }
    68  
    69  func New(registerer prometheus.Registerer) (Metrics, error) {
    70  	txMetrics, err := newTxMetrics(registerer)
    71  	errs := wrappers.Errs{Err: err}
    72  
    73  	m := &metrics{txMetrics: txMetrics}
    74  
    75  	m.numTxRefreshes = prometheus.NewCounter(prometheus.CounterOpts{
    76  		Name: "tx_refreshes",
    77  		Help: "Number of times unique txs have been refreshed",
    78  	})
    79  	m.numTxRefreshHits = prometheus.NewCounter(prometheus.CounterOpts{
    80  		Name: "tx_refresh_hits",
    81  		Help: "Number of times unique txs have not been unique, but were cached",
    82  	})
    83  	m.numTxRefreshMisses = prometheus.NewCounter(prometheus.CounterOpts{
    84  		Name: "tx_refresh_misses",
    85  		Help: "Number of times unique txs have not been unique and weren't cached",
    86  	})
    87  
    88  	apiRequestMetric, err := metric.NewAPIInterceptor(registerer)
    89  	m.APIInterceptor = apiRequestMetric
    90  	errs.Add(
    91  		err,
    92  		registerer.Register(m.numTxRefreshes),
    93  		registerer.Register(m.numTxRefreshHits),
    94  		registerer.Register(m.numTxRefreshMisses),
    95  	)
    96  	return m, errs.Err
    97  }