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

     1  package consensus
     2  
     3  import (
     4  	"strings"
     5  	"time"
     6  
     7  	"github.com/go-kit/kit/metrics"
     8  
     9  	cstypes "github.com/badrootd/nibiru-cometbft/consensus/types"
    10  	cmtproto "github.com/badrootd/nibiru-cometbft/proto/tendermint/types"
    11  	"github.com/badrootd/nibiru-cometbft/types"
    12  )
    13  
    14  const (
    15  	// MetricsSubsystem is a subsystem shared by all metrics exposed by this
    16  	// package.
    17  	MetricsSubsystem = "consensus"
    18  )
    19  
    20  //go:generate go run ../scripts/metricsgen -struct=Metrics
    21  
    22  // Metrics contains metrics exposed by this package.
    23  type Metrics struct {
    24  	// Height of the chain.
    25  	Height metrics.Gauge
    26  
    27  	// Last height signed by this validator if the node is a validator.
    28  	ValidatorLastSignedHeight metrics.Gauge `metrics_labels:"validator_address"`
    29  
    30  	// Number of rounds.
    31  	Rounds metrics.Gauge
    32  
    33  	// Histogram of round duration.
    34  	RoundDurationSeconds metrics.Histogram `metrics_buckettype:"exprange" metrics_bucketsizes:"0.1, 100, 8"`
    35  
    36  	// Number of validators.
    37  	Validators metrics.Gauge
    38  	// Total power of all validators.
    39  	ValidatorsPower metrics.Gauge
    40  	// Power of a validator.
    41  	ValidatorPower metrics.Gauge `metrics_labels:"validator_address"`
    42  	// Amount of blocks missed per validator.
    43  	ValidatorMissedBlocks metrics.Gauge `metrics_labels:"validator_address"`
    44  	// Number of validators who did not sign.
    45  	MissingValidators metrics.Gauge
    46  	// Total power of the missing validators.
    47  	MissingValidatorsPower metrics.Gauge
    48  	// Number of validators who tried to double sign.
    49  	ByzantineValidators metrics.Gauge
    50  	// Total power of the byzantine validators.
    51  	ByzantineValidatorsPower metrics.Gauge
    52  
    53  	// Time between this and the last block.
    54  	BlockIntervalSeconds metrics.Histogram
    55  
    56  	// Number of transactions.
    57  	NumTxs metrics.Gauge
    58  	// Size of the block.
    59  	BlockSizeBytes metrics.Gauge
    60  	// Total number of transactions.
    61  	TotalTxs metrics.Gauge
    62  	// The latest block height.
    63  	CommittedHeight metrics.Gauge `metrics_name:"latest_block_height"`
    64  	// Whether or not a node is block syncing. 1 if yes, 0 if no.
    65  	BlockSyncing metrics.Gauge
    66  	// Whether or not a node is state syncing. 1 if yes, 0 if no.
    67  	StateSyncing metrics.Gauge
    68  
    69  	// Number of block parts transmitted by each peer.
    70  	BlockParts metrics.Counter `metrics_labels:"peer_id"`
    71  
    72  	// Histogram of durations for each step in the consensus protocol.
    73  	StepDurationSeconds metrics.Histogram `metrics_labels:"step" metrics_buckettype:"exprange" metrics_bucketsizes:"0.1, 100, 8"`
    74  	stepStart           time.Time
    75  
    76  	// Number of block parts received by the node, separated by whether the part
    77  	// was relevant to the block the node is trying to gather or not.
    78  	BlockGossipPartsReceived metrics.Counter `metrics_labels:"matches_current"`
    79  
    80  	// QuroumPrevoteMessageDelay is the interval in seconds between the proposal
    81  	// timestamp and the timestamp of the earliest prevote that achieved a quorum
    82  	// during the prevote step.
    83  	//
    84  	// To compute it, sum the voting power over each prevote received, in increasing
    85  	// order of timestamp. The timestamp of the first prevote to increase the sum to
    86  	// be above 2/3 of the total voting power of the network defines the endpoint
    87  	// the endpoint of the interval. Subtract the proposal timestamp from this endpoint
    88  	// to obtain the quorum delay.
    89  	//metrics:Interval in seconds between the proposal timestamp and the timestamp of the earliest prevote that achieved a quorum.
    90  	QuorumPrevoteDelay metrics.Gauge `metrics_labels:"proposer_address"`
    91  
    92  	// FullPrevoteDelay is the interval in seconds between the proposal
    93  	// timestamp and the timestamp of the latest prevote in a round where 100%
    94  	// of the voting power on the network issued prevotes.
    95  	//metrics:Interval in seconds between the proposal timestamp and the timestamp of the latest prevote in a round where all validators voted.
    96  	FullPrevoteDelay metrics.Gauge `metrics_labels:"proposer_address"`
    97  
    98  	// ProposalReceiveCount is the total number of proposals received by this node
    99  	// since process start.
   100  	// The metric is annotated by the status of the proposal from the application,
   101  	// either 'accepted' or 'rejected'.
   102  	ProposalReceiveCount metrics.Counter `metrics_labels:"status"`
   103  
   104  	// ProposalCreationCount is the total number of proposals created by this node
   105  	// since process start.
   106  	ProposalCreateCount metrics.Counter
   107  
   108  	// RoundVotingPowerPercent is the percentage of the total voting power received
   109  	// with a round. The value begins at 0 for each round and approaches 1.0 as
   110  	// additional voting power is observed. The metric is labeled by vote type.
   111  	RoundVotingPowerPercent metrics.Gauge `metrics_labels:"vote_type"`
   112  
   113  	// LateVotes stores the number of votes that were received by this node that
   114  	// correspond to earlier heights and rounds than this node is currently
   115  	// in.
   116  	LateVotes metrics.Counter `metrics_labels:"vote_type"`
   117  }
   118  
   119  // RecordConsMetrics uses for recording the block related metrics during fast-sync.
   120  func (m *Metrics) RecordConsMetrics(block *types.Block) {
   121  	m.NumTxs.Set(float64(len(block.Data.Txs)))
   122  	m.TotalTxs.Add(float64(len(block.Data.Txs)))
   123  	m.BlockSizeBytes.Set(float64(block.Size()))
   124  	m.CommittedHeight.Set(float64(block.Height))
   125  }
   126  
   127  func (m *Metrics) MarkProposalProcessed(accepted bool) {
   128  	status := "accepted"
   129  	if !accepted {
   130  		status = "rejected"
   131  	}
   132  	m.ProposalReceiveCount.With("status", status).Add(1)
   133  }
   134  
   135  func (m *Metrics) MarkVoteReceived(vt cmtproto.SignedMsgType, power, totalPower int64) {
   136  	p := float64(power) / float64(totalPower)
   137  	n := strings.ToLower(strings.TrimPrefix(vt.String(), "SIGNED_MSG_TYPE_"))
   138  	m.RoundVotingPowerPercent.With("vote_type", n).Add(p)
   139  }
   140  
   141  func (m *Metrics) MarkRound(r int32, st time.Time) {
   142  	m.Rounds.Set(float64(r))
   143  	roundTime := time.Since(st).Seconds()
   144  	m.RoundDurationSeconds.Observe(roundTime)
   145  
   146  	pvt := cmtproto.PrevoteType
   147  	pvn := strings.ToLower(strings.TrimPrefix(pvt.String(), "SIGNED_MSG_TYPE_"))
   148  	m.RoundVotingPowerPercent.With("vote_type", pvn).Set(0)
   149  
   150  	pct := cmtproto.PrecommitType
   151  	pcn := strings.ToLower(strings.TrimPrefix(pct.String(), "SIGNED_MSG_TYPE_"))
   152  	m.RoundVotingPowerPercent.With("vote_type", pcn).Set(0)
   153  }
   154  
   155  func (m *Metrics) MarkLateVote(vt cmtproto.SignedMsgType) {
   156  	n := strings.ToLower(strings.TrimPrefix(vt.String(), "SIGNED_MSG_TYPE_"))
   157  	m.LateVotes.With("vote_type", n).Add(1)
   158  }
   159  
   160  func (m *Metrics) MarkStep(s cstypes.RoundStepType) {
   161  	if !m.stepStart.IsZero() {
   162  		stepTime := time.Since(m.stepStart).Seconds()
   163  		stepName := strings.TrimPrefix(s.String(), "RoundStep")
   164  		m.StepDurationSeconds.With("step", stepName).Observe(stepTime)
   165  	}
   166  	m.stepStart = time.Now()
   167  }