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 }