github.com/opzlabs/tendermint@v0.34.27-terra.rc.2/consensus/metrics.go (about)

     1  package consensus
     2  
     3  import (
     4  	"strings"
     5  	"time"
     6  
     7  	"github.com/go-kit/kit/metrics"
     8  	"github.com/go-kit/kit/metrics/discard"
     9  	cstypes "github.com/tendermint/tendermint/consensus/types"
    10  
    11  	prometheus "github.com/go-kit/kit/metrics/prometheus"
    12  	stdprometheus "github.com/prometheus/client_golang/prometheus"
    13  )
    14  
    15  const (
    16  	// MetricsSubsystem is a subsystem shared by all metrics exposed by this
    17  	// package.
    18  	MetricsSubsystem = "consensus"
    19  )
    20  
    21  // Metrics contains metrics exposed by this package.
    22  type Metrics struct {
    23  	// Height of the chain.
    24  	Height metrics.Gauge
    25  
    26  	// ValidatorLastSignedHeight of a validator.
    27  	ValidatorLastSignedHeight metrics.Gauge
    28  
    29  	// Number of rounds.
    30  	Rounds metrics.Gauge
    31  
    32  	// Number of validators.
    33  	Validators metrics.Gauge
    34  	// Total power of all validators.
    35  	ValidatorsPower metrics.Gauge
    36  	// Power of a validator.
    37  	ValidatorPower metrics.Gauge
    38  	// Amount of blocks missed by a validator.
    39  	ValidatorMissedBlocks metrics.Gauge
    40  	// Number of validators who did not sign.
    41  	MissingValidators metrics.Gauge
    42  	// Total power of the missing validators.
    43  	MissingValidatorsPower metrics.Gauge
    44  	// Number of validators who tried to double sign.
    45  	ByzantineValidators metrics.Gauge
    46  	// Total power of the byzantine validators.
    47  	ByzantineValidatorsPower metrics.Gauge
    48  
    49  	// Time between this and the last block.
    50  	BlockIntervalSeconds metrics.Histogram
    51  
    52  	// Number of transactions.
    53  	NumTxs metrics.Gauge
    54  	// Size of the block.
    55  	BlockSizeBytes metrics.Gauge
    56  	// Total number of transactions.
    57  	TotalTxs metrics.Gauge
    58  	// The latest block height.
    59  	CommittedHeight metrics.Gauge
    60  	// Whether or not a node is fast syncing. 1 if yes, 0 if no.
    61  	FastSyncing metrics.Gauge
    62  	// Whether or not a node is state syncing. 1 if yes, 0 if no.
    63  	StateSyncing metrics.Gauge
    64  
    65  	// Number of blockparts transmitted by peer.
    66  	BlockParts metrics.Counter
    67  
    68  	// Histogram of step duration.
    69  	StepDuration metrics.Histogram
    70  	stepStart    time.Time
    71  
    72  	// Number of block parts received by the node, separated by whether the part
    73  	// was relevant to the block the node is trying to gather or not.
    74  	BlockGossipPartsReceived metrics.Counter
    75  
    76  	// QuroumPrevoteMessageDelay is the interval in seconds between the proposal
    77  	// timestamp and the timestamp of the earliest prevote that achieved a quorum
    78  	// during the prevote step.
    79  	//
    80  	// To compute it, sum the voting power over each prevote received, in increasing
    81  	// order of timestamp. The timestamp of the first prevote to increase the sum to
    82  	// be above 2/3 of the total voting power of the network defines the endpoint
    83  	// the endpoint of the interval. Subtract the proposal timestamp from this endpoint
    84  	// to obtain the quorum delay.
    85  	QuorumPrevoteMessageDelay metrics.Gauge
    86  
    87  	// FullPrevoteMessageDelay is the interval in seconds between the proposal
    88  	// timestamp and the timestamp of the latest prevote in a round where 100%
    89  	// of the voting power on the network issued prevotes.
    90  	FullPrevoteMessageDelay metrics.Gauge
    91  }
    92  
    93  // PrometheusMetrics returns Metrics build using Prometheus client library.
    94  // Optionally, labels can be provided along with their values ("foo",
    95  // "fooValue").
    96  func PrometheusMetrics(namespace string, labelsAndValues ...string) *Metrics {
    97  	labels := []string{}
    98  	for i := 0; i < len(labelsAndValues); i += 2 {
    99  		labels = append(labels, labelsAndValues[i])
   100  	}
   101  	return &Metrics{
   102  		Height: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
   103  			Namespace: namespace,
   104  			Subsystem: MetricsSubsystem,
   105  			Name:      "height",
   106  			Help:      "Height of the chain.",
   107  		}, labels).With(labelsAndValues...),
   108  		Rounds: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
   109  			Namespace: namespace,
   110  			Subsystem: MetricsSubsystem,
   111  			Name:      "rounds",
   112  			Help:      "Number of rounds.",
   113  		}, labels).With(labelsAndValues...),
   114  		Validators: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
   115  			Namespace: namespace,
   116  			Subsystem: MetricsSubsystem,
   117  			Name:      "validators",
   118  			Help:      "Number of validators.",
   119  		}, labels).With(labelsAndValues...),
   120  		ValidatorLastSignedHeight: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
   121  			Namespace: namespace,
   122  			Subsystem: MetricsSubsystem,
   123  			Name:      "validator_last_signed_height",
   124  			Help:      "Last signed height for a validator",
   125  		}, append(labels, "validator_address")).With(labelsAndValues...),
   126  		ValidatorMissedBlocks: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
   127  			Namespace: namespace,
   128  			Subsystem: MetricsSubsystem,
   129  			Name:      "validator_missed_blocks",
   130  			Help:      "Total missed blocks for a validator",
   131  		}, append(labels, "validator_address")).With(labelsAndValues...),
   132  		ValidatorsPower: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
   133  			Namespace: namespace,
   134  			Subsystem: MetricsSubsystem,
   135  			Name:      "validators_power",
   136  			Help:      "Total power of all validators.",
   137  		}, labels).With(labelsAndValues...),
   138  		ValidatorPower: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
   139  			Namespace: namespace,
   140  			Subsystem: MetricsSubsystem,
   141  			Name:      "validator_power",
   142  			Help:      "Power of a validator",
   143  		}, append(labels, "validator_address")).With(labelsAndValues...),
   144  		MissingValidators: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
   145  			Namespace: namespace,
   146  			Subsystem: MetricsSubsystem,
   147  			Name:      "missing_validators",
   148  			Help:      "Number of validators who did not sign.",
   149  		}, labels).With(labelsAndValues...),
   150  		MissingValidatorsPower: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
   151  			Namespace: namespace,
   152  			Subsystem: MetricsSubsystem,
   153  			Name:      "missing_validators_power",
   154  			Help:      "Total power of the missing validators.",
   155  		}, labels).With(labelsAndValues...),
   156  		ByzantineValidators: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
   157  			Namespace: namespace,
   158  			Subsystem: MetricsSubsystem,
   159  			Name:      "byzantine_validators",
   160  			Help:      "Number of validators who tried to double sign.",
   161  		}, labels).With(labelsAndValues...),
   162  		ByzantineValidatorsPower: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
   163  			Namespace: namespace,
   164  			Subsystem: MetricsSubsystem,
   165  			Name:      "byzantine_validators_power",
   166  			Help:      "Total power of the byzantine validators.",
   167  		}, labels).With(labelsAndValues...),
   168  		BlockIntervalSeconds: prometheus.NewHistogramFrom(stdprometheus.HistogramOpts{
   169  			Namespace: namespace,
   170  			Subsystem: MetricsSubsystem,
   171  			Name:      "block_interval_seconds",
   172  			Help:      "Time between this and the last block.",
   173  		}, labels).With(labelsAndValues...),
   174  		NumTxs: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
   175  			Namespace: namespace,
   176  			Subsystem: MetricsSubsystem,
   177  			Name:      "num_txs",
   178  			Help:      "Number of transactions.",
   179  		}, labels).With(labelsAndValues...),
   180  		BlockSizeBytes: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
   181  			Namespace: namespace,
   182  			Subsystem: MetricsSubsystem,
   183  			Name:      "block_size_bytes",
   184  			Help:      "Size of the block.",
   185  		}, labels).With(labelsAndValues...),
   186  		TotalTxs: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
   187  			Namespace: namespace,
   188  			Subsystem: MetricsSubsystem,
   189  			Name:      "total_txs",
   190  			Help:      "Total number of transactions.",
   191  		}, labels).With(labelsAndValues...),
   192  		CommittedHeight: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
   193  			Namespace: namespace,
   194  			Subsystem: MetricsSubsystem,
   195  			Name:      "latest_block_height",
   196  			Help:      "The latest block height.",
   197  		}, labels).With(labelsAndValues...),
   198  		FastSyncing: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
   199  			Namespace: namespace,
   200  			Subsystem: MetricsSubsystem,
   201  			Name:      "fast_syncing",
   202  			Help:      "Whether or not a node is fast syncing. 1 if yes, 0 if no.",
   203  		}, labels).With(labelsAndValues...),
   204  		StateSyncing: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
   205  			Namespace: namespace,
   206  			Subsystem: MetricsSubsystem,
   207  			Name:      "state_syncing",
   208  			Help:      "Whether or not a node is state syncing. 1 if yes, 0 if no.",
   209  		}, labels).With(labelsAndValues...),
   210  		BlockParts: prometheus.NewCounterFrom(stdprometheus.CounterOpts{
   211  			Namespace: namespace,
   212  			Subsystem: MetricsSubsystem,
   213  			Name:      "block_parts",
   214  			Help:      "Number of blockparts transmitted by peer.",
   215  		}, append(labels, "peer_id")).With(labelsAndValues...),
   216  		BlockGossipPartsReceived: prometheus.NewCounterFrom(stdprometheus.CounterOpts{
   217  			Namespace: namespace,
   218  			Subsystem: MetricsSubsystem,
   219  			Name:      "block_gossip_parts_received",
   220  			Help: "Number of block parts received by the node, labeled by whether the " +
   221  				"part was relevant to the block the node was currently gathering or not.",
   222  		}, append(labels, "matches_current")).With(labelsAndValues...),
   223  		StepDuration: prometheus.NewHistogramFrom(stdprometheus.HistogramOpts{
   224  			Namespace: namespace,
   225  			Subsystem: MetricsSubsystem,
   226  			Name:      "step_duration_seconds",
   227  			Help:      "Time spent per step.",
   228  			Buckets:   stdprometheus.ExponentialBucketsRange(0.1, 100, 8),
   229  		}, append(labels, "step")).With(labelsAndValues...),
   230  		QuorumPrevoteMessageDelay: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
   231  			Namespace: namespace,
   232  			Subsystem: MetricsSubsystem,
   233  			Name:      "quorum_prevote_message_delay",
   234  			Help: "Difference in seconds between the proposal timestamp and the timestamp " +
   235  				"of the latest prevote that achieved a quorum in the prevote step.",
   236  		}, labels).With(labelsAndValues...),
   237  		FullPrevoteMessageDelay: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
   238  			Namespace: namespace,
   239  			Subsystem: MetricsSubsystem,
   240  			Name:      "full_prevote_message_delay",
   241  			Help: "Difference in seconds between the proposal timestamp and the timestamp " +
   242  				"of the latest prevote that achieved 100% of the voting power in the prevote step.",
   243  		}, labels).With(labelsAndValues...),
   244  	}
   245  }
   246  
   247  // NopMetrics returns no-op Metrics.
   248  func NopMetrics() *Metrics {
   249  	return &Metrics{
   250  		Height: discard.NewGauge(),
   251  
   252  		ValidatorLastSignedHeight: discard.NewGauge(),
   253  
   254  		Rounds:       discard.NewGauge(),
   255  		StepDuration: discard.NewHistogram(),
   256  
   257  		Validators:               discard.NewGauge(),
   258  		ValidatorsPower:          discard.NewGauge(),
   259  		ValidatorPower:           discard.NewGauge(),
   260  		ValidatorMissedBlocks:    discard.NewGauge(),
   261  		MissingValidators:        discard.NewGauge(),
   262  		MissingValidatorsPower:   discard.NewGauge(),
   263  		ByzantineValidators:      discard.NewGauge(),
   264  		ByzantineValidatorsPower: discard.NewGauge(),
   265  
   266  		BlockIntervalSeconds: discard.NewHistogram(),
   267  
   268  		NumTxs:                    discard.NewGauge(),
   269  		BlockSizeBytes:            discard.NewGauge(),
   270  		TotalTxs:                  discard.NewGauge(),
   271  		CommittedHeight:           discard.NewGauge(),
   272  		FastSyncing:               discard.NewGauge(),
   273  		StateSyncing:              discard.NewGauge(),
   274  		BlockParts:                discard.NewCounter(),
   275  		BlockGossipPartsReceived:  discard.NewCounter(),
   276  		QuorumPrevoteMessageDelay: discard.NewGauge(),
   277  		FullPrevoteMessageDelay:   discard.NewGauge(),
   278  	}
   279  }
   280  
   281  func (m *Metrics) MarkRound(r int32) {
   282  	m.Rounds.Set(float64(r))
   283  }
   284  
   285  func (m *Metrics) MarkStep(s cstypes.RoundStepType) {
   286  	if !m.stepStart.IsZero() {
   287  		stepTime := time.Since(m.stepStart).Seconds()
   288  		stepName := strings.TrimPrefix(s.String(), "RoundStep")
   289  		m.StepDuration.With("step", stepName).Observe(stepTime)
   290  	}
   291  	m.stepStart = time.Now()
   292  }