github.com/badrootd/nibiru-cometbft@v0.37.5-0.20240307173500-2a75559eee9b/p2p/metrics.go (about)

     1  package p2p
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"regexp"
     7  	"sync"
     8  
     9  	"github.com/go-kit/kit/metrics"
    10  )
    11  
    12  const (
    13  	// MetricsSubsystem is a subsystem shared by all metrics exposed by this
    14  	// package.
    15  	MetricsSubsystem = "p2p"
    16  )
    17  
    18  var (
    19  	// valueToLabelRegexp is used to find the golang package name and type name
    20  	// so that the name can be turned into a prometheus label where the characters
    21  	// in the label do not include prometheus special characters such as '*' and '.'.
    22  	valueToLabelRegexp = regexp.MustCompile(`\*?(\w+)\.(.*)`)
    23  )
    24  
    25  //go:generate go run ../scripts/metricsgen -struct=Metrics
    26  
    27  // Metrics contains metrics exposed by this package.
    28  type Metrics struct {
    29  	// Number of peers.
    30  	Peers metrics.Gauge
    31  	// Number of bytes received from a given peer.
    32  	PeerReceiveBytesTotal metrics.Counter `metrics_labels:"peer_id,chID"`
    33  	// Number of bytes sent to a given peer.
    34  	PeerSendBytesTotal metrics.Counter `metrics_labels:"peer_id,chID"`
    35  	// Pending bytes to be sent to a given peer.
    36  	PeerPendingSendBytes metrics.Gauge `metrics_labels:"peer_id"`
    37  	// Number of transactions submitted by each peer.
    38  	NumTxs metrics.Gauge `metrics_labels:"peer_id"`
    39  	// Number of bytes of each message type received.
    40  	MessageReceiveBytesTotal metrics.Counter `metrics_labels:"message_type"`
    41  	// Number of bytes of each message type sent.
    42  	MessageSendBytesTotal metrics.Counter `metrics_labels:"message_type"`
    43  }
    44  
    45  type metricsLabelCache struct {
    46  	mtx               *sync.RWMutex
    47  	messageLabelNames map[reflect.Type]string
    48  }
    49  
    50  // ValueToMetricLabel is a method that is used to produce a prometheus label value of the golang
    51  // type that is passed in.
    52  // This method uses a map on the Metrics struct so that each label name only needs
    53  // to be produced once to prevent expensive string operations.
    54  func (m *metricsLabelCache) ValueToMetricLabel(i interface{}) string {
    55  	t := reflect.TypeOf(i)
    56  	m.mtx.RLock()
    57  
    58  	if s, ok := m.messageLabelNames[t]; ok {
    59  		m.mtx.RUnlock()
    60  		return s
    61  	}
    62  	m.mtx.RUnlock()
    63  
    64  	s := t.String()
    65  	ss := valueToLabelRegexp.FindStringSubmatch(s)
    66  	l := fmt.Sprintf("%s_%s", ss[1], ss[2])
    67  	m.mtx.Lock()
    68  	defer m.mtx.Unlock()
    69  	m.messageLabelNames[t] = l
    70  	return l
    71  }
    72  
    73  func newMetricsLabelCache() *metricsLabelCache {
    74  	return &metricsLabelCache{
    75  		mtx:               &sync.RWMutex{},
    76  		messageLabelNames: map[reflect.Type]string{},
    77  	}
    78  }