Browse Source

add "chain_id" label for all metrics (#3123)

* add "chain_id" label for all metrics

Refs #3082

* fix labels extraction
pull/3136/head
Anton Kaliaev 6 years ago
committed by Ethan Buchman
parent
commit
dcb8f88525
6 changed files with 89 additions and 42 deletions
  1. +2
    -0
      CHANGELOG_PENDING.md
  2. +27
    -17
      consensus/metrics.go
  3. +20
    -10
      mempool/metrics.go
  4. +7
    -5
      node/node.go
  5. +17
    -7
      p2p/metrics.go
  6. +16
    -3
      state/metrics.go

+ 2
- 0
CHANGELOG_PENDING.md View File

@ -12,6 +12,7 @@ Special thanks to external contributors on this release:
* Apps * Apps
* Go API * Go API
- [node] \#3082 MetricsProvider now requires you to pass a chain ID
* Blockchain Protocol * Blockchain Protocol
* [merkle] \#2713 Merkle trees now match the RFC 6962 specification * [merkle] \#2713 Merkle trees now match the RFC 6962 specification
@ -22,6 +23,7 @@ Special thanks to external contributors on this release:
### IMPROVEMENTS: ### IMPROVEMENTS:
- [rpc] \#3065 return maxPerPage (100), not defaultPerPage (30) if `per_page` is greater than the max 100. - [rpc] \#3065 return maxPerPage (100), not defaultPerPage (30) if `per_page` is greater than the max 100.
- [instrumentation] \#3082 add 'chain_id' label for all metrics
### BUG FIXES: ### BUG FIXES:
- [log] \#3060 fix year format - [log] \#3060 fix year format

+ 27
- 17
consensus/metrics.go View File

@ -8,7 +8,11 @@ import (
stdprometheus "github.com/prometheus/client_golang/prometheus" stdprometheus "github.com/prometheus/client_golang/prometheus"
) )
const MetricsSubsystem = "consensus"
const (
// MetricsSubsystem is a subsystem shared by all metrics exposed by this
// package.
MetricsSubsystem = "consensus"
)
// Metrics contains metrics exposed by this package. // Metrics contains metrics exposed by this package.
type Metrics struct { type Metrics struct {
@ -50,101 +54,107 @@ type Metrics struct {
} }
// PrometheusMetrics returns Metrics build using Prometheus client library. // PrometheusMetrics returns Metrics build using Prometheus client library.
func PrometheusMetrics(namespace string) *Metrics {
// Optionally, labels can be provided along with their values ("foo",
// "fooValue").
func PrometheusMetrics(namespace string, labelsAndValues ...string) *Metrics {
labels := []string{}
for i := 0; i < len(labelsAndValues); i += 2 {
labels = append(labels, labelsAndValues[i])
}
return &Metrics{ return &Metrics{
Height: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ Height: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace, Namespace: namespace,
Subsystem: MetricsSubsystem, Subsystem: MetricsSubsystem,
Name: "height", Name: "height",
Help: "Height of the chain.", Help: "Height of the chain.",
}, []string{}),
}, labels).With(labelsAndValues...),
Rounds: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ Rounds: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace, Namespace: namespace,
Subsystem: MetricsSubsystem, Subsystem: MetricsSubsystem,
Name: "rounds", Name: "rounds",
Help: "Number of rounds.", Help: "Number of rounds.",
}, []string{}),
}, labels).With(labelsAndValues...),
Validators: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ Validators: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace, Namespace: namespace,
Subsystem: MetricsSubsystem, Subsystem: MetricsSubsystem,
Name: "validators", Name: "validators",
Help: "Number of validators.", Help: "Number of validators.",
}, []string{}),
}, labels).With(labelsAndValues...),
ValidatorsPower: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ ValidatorsPower: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace, Namespace: namespace,
Subsystem: MetricsSubsystem, Subsystem: MetricsSubsystem,
Name: "validators_power", Name: "validators_power",
Help: "Total power of all validators.", Help: "Total power of all validators.",
}, []string{}),
}, labels).With(labelsAndValues...),
MissingValidators: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ MissingValidators: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace, Namespace: namespace,
Subsystem: MetricsSubsystem, Subsystem: MetricsSubsystem,
Name: "missing_validators", Name: "missing_validators",
Help: "Number of validators who did not sign.", Help: "Number of validators who did not sign.",
}, []string{}),
}, labels).With(labelsAndValues...),
MissingValidatorsPower: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ MissingValidatorsPower: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace, Namespace: namespace,
Subsystem: MetricsSubsystem, Subsystem: MetricsSubsystem,
Name: "missing_validators_power", Name: "missing_validators_power",
Help: "Total power of the missing validators.", Help: "Total power of the missing validators.",
}, []string{}),
}, labels).With(labelsAndValues...),
ByzantineValidators: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ ByzantineValidators: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace, Namespace: namespace,
Subsystem: MetricsSubsystem, Subsystem: MetricsSubsystem,
Name: "byzantine_validators", Name: "byzantine_validators",
Help: "Number of validators who tried to double sign.", Help: "Number of validators who tried to double sign.",
}, []string{}),
}, labels).With(labelsAndValues...),
ByzantineValidatorsPower: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ ByzantineValidatorsPower: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace, Namespace: namespace,
Subsystem: MetricsSubsystem, Subsystem: MetricsSubsystem,
Name: "byzantine_validators_power", Name: "byzantine_validators_power",
Help: "Total power of the byzantine validators.", Help: "Total power of the byzantine validators.",
}, []string{}),
}, labels).With(labelsAndValues...),
BlockIntervalSeconds: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ BlockIntervalSeconds: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace, Namespace: namespace,
Subsystem: MetricsSubsystem, Subsystem: MetricsSubsystem,
Name: "block_interval_seconds", Name: "block_interval_seconds",
Help: "Time between this and the last block.", Help: "Time between this and the last block.",
}, []string{}),
}, labels).With(labelsAndValues...),
NumTxs: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ NumTxs: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace, Namespace: namespace,
Subsystem: MetricsSubsystem, Subsystem: MetricsSubsystem,
Name: "num_txs", Name: "num_txs",
Help: "Number of transactions.", Help: "Number of transactions.",
}, []string{}),
}, labels).With(labelsAndValues...),
BlockSizeBytes: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ BlockSizeBytes: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace, Namespace: namespace,
Subsystem: MetricsSubsystem, Subsystem: MetricsSubsystem,
Name: "block_size_bytes", Name: "block_size_bytes",
Help: "Size of the block.", Help: "Size of the block.",
}, []string{}),
}, labels).With(labelsAndValues...),
TotalTxs: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ TotalTxs: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace, Namespace: namespace,
Subsystem: MetricsSubsystem, Subsystem: MetricsSubsystem,
Name: "total_txs", Name: "total_txs",
Help: "Total number of transactions.", Help: "Total number of transactions.",
}, []string{}),
}, labels).With(labelsAndValues...),
CommittedHeight: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ CommittedHeight: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace, Namespace: namespace,
Subsystem: MetricsSubsystem, Subsystem: MetricsSubsystem,
Name: "latest_block_height", Name: "latest_block_height",
Help: "The latest block height.", Help: "The latest block height.",
}, []string{}),
}, labels).With(labelsAndValues...),
FastSyncing: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ FastSyncing: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace, Namespace: namespace,
Subsystem: MetricsSubsystem, Subsystem: MetricsSubsystem,
Name: "fast_syncing", Name: "fast_syncing",
Help: "Whether or not a node is fast syncing. 1 if yes, 0 if no.", Help: "Whether or not a node is fast syncing. 1 if yes, 0 if no.",
}, []string{}),
}, labels).With(labelsAndValues...),
BlockParts: prometheus.NewCounterFrom(stdprometheus.CounterOpts{ BlockParts: prometheus.NewCounterFrom(stdprometheus.CounterOpts{
Namespace: namespace, Namespace: namespace,
Subsystem: MetricsSubsystem, Subsystem: MetricsSubsystem,
Name: "block_parts", Name: "block_parts",
Help: "Number of blockparts transmitted by peer.", Help: "Number of blockparts transmitted by peer.",
}, []string{"peer_id"}),
}, append(labels, "peer_id")).With(labelsAndValues...),
} }
} }


+ 20
- 10
mempool/metrics.go View File

@ -7,7 +7,11 @@ import (
stdprometheus "github.com/prometheus/client_golang/prometheus" stdprometheus "github.com/prometheus/client_golang/prometheus"
) )
const MetricsSubsytem = "mempool"
const (
// MetricsSubsystem is a subsystem shared by all metrics exposed by this
// package.
MetricsSubsystem = "mempool"
)
// Metrics contains metrics exposed by this package. // Metrics contains metrics exposed by this package.
// see MetricsProvider for descriptions. // see MetricsProvider for descriptions.
@ -23,33 +27,39 @@ type Metrics struct {
} }
// PrometheusMetrics returns Metrics build using Prometheus client library. // PrometheusMetrics returns Metrics build using Prometheus client library.
func PrometheusMetrics(namespace string) *Metrics {
// Optionally, labels can be provided along with their values ("foo",
// "fooValue").
func PrometheusMetrics(namespace string, labelsAndValues ...string) *Metrics {
labels := []string{}
for i := 0; i < len(labelsAndValues); i += 2 {
labels = append(labels, labelsAndValues[i])
}
return &Metrics{ return &Metrics{
Size: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ Size: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace, Namespace: namespace,
Subsystem: MetricsSubsytem,
Subsystem: MetricsSubsystem,
Name: "size", Name: "size",
Help: "Size of the mempool (number of uncommitted transactions).", Help: "Size of the mempool (number of uncommitted transactions).",
}, []string{}),
}, labels).With(labelsAndValues...),
TxSizeBytes: prometheus.NewHistogramFrom(stdprometheus.HistogramOpts{ TxSizeBytes: prometheus.NewHistogramFrom(stdprometheus.HistogramOpts{
Namespace: namespace, Namespace: namespace,
Subsystem: MetricsSubsytem,
Subsystem: MetricsSubsystem,
Name: "tx_size_bytes", Name: "tx_size_bytes",
Help: "Transaction sizes in bytes.", Help: "Transaction sizes in bytes.",
Buckets: stdprometheus.ExponentialBuckets(1, 3, 17), Buckets: stdprometheus.ExponentialBuckets(1, 3, 17),
}, []string{}),
}, labels).With(labelsAndValues...),
FailedTxs: prometheus.NewCounterFrom(stdprometheus.CounterOpts{ FailedTxs: prometheus.NewCounterFrom(stdprometheus.CounterOpts{
Namespace: namespace, Namespace: namespace,
Subsystem: MetricsSubsytem,
Subsystem: MetricsSubsystem,
Name: "failed_txs", Name: "failed_txs",
Help: "Number of failed transactions.", Help: "Number of failed transactions.",
}, []string{}),
}, labels).With(labelsAndValues...),
RecheckTimes: prometheus.NewCounterFrom(stdprometheus.CounterOpts{ RecheckTimes: prometheus.NewCounterFrom(stdprometheus.CounterOpts{
Namespace: namespace, Namespace: namespace,
Subsystem: MetricsSubsytem,
Subsystem: MetricsSubsystem,
Name: "recheck_times", Name: "recheck_times",
Help: "Number of times transactions are rechecked in the mempool.", Help: "Number of times transactions are rechecked in the mempool.",
}, []string{}),
}, labels).With(labelsAndValues...),
} }
} }


+ 7
- 5
node/node.go View File

@ -117,15 +117,17 @@ func DefaultNewNode(config *cfg.Config, logger log.Logger) (*Node, error) {
} }
// MetricsProvider returns a consensus, p2p and mempool Metrics. // MetricsProvider returns a consensus, p2p and mempool Metrics.
type MetricsProvider func() (*cs.Metrics, *p2p.Metrics, *mempl.Metrics, *sm.Metrics)
type MetricsProvider func(chainID string) (*cs.Metrics, *p2p.Metrics, *mempl.Metrics, *sm.Metrics)
// DefaultMetricsProvider returns Metrics build using Prometheus client library // DefaultMetricsProvider returns Metrics build using Prometheus client library
// if Prometheus is enabled. Otherwise, it returns no-op Metrics. // if Prometheus is enabled. Otherwise, it returns no-op Metrics.
func DefaultMetricsProvider(config *cfg.InstrumentationConfig) MetricsProvider { func DefaultMetricsProvider(config *cfg.InstrumentationConfig) MetricsProvider {
return func() (*cs.Metrics, *p2p.Metrics, *mempl.Metrics, *sm.Metrics) {
return func(chainID string) (*cs.Metrics, *p2p.Metrics, *mempl.Metrics, *sm.Metrics) {
if config.Prometheus { if config.Prometheus {
return cs.PrometheusMetrics(config.Namespace), p2p.PrometheusMetrics(config.Namespace),
mempl.PrometheusMetrics(config.Namespace), sm.PrometheusMetrics(config.Namespace)
return cs.PrometheusMetrics(config.Namespace, "chain_id", chainID),
p2p.PrometheusMetrics(config.Namespace, "chain_id", chainID),
mempl.PrometheusMetrics(config.Namespace, "chain_id", chainID),
sm.PrometheusMetrics(config.Namespace, "chain_id", chainID)
} }
return cs.NopMetrics(), p2p.NopMetrics(), mempl.NopMetrics(), sm.NopMetrics() return cs.NopMetrics(), p2p.NopMetrics(), mempl.NopMetrics(), sm.NopMetrics()
} }
@ -274,7 +276,7 @@ func NewNode(config *cfg.Config,
consensusLogger.Info("This node is not a validator", "addr", addr, "pubKey", pubKey) consensusLogger.Info("This node is not a validator", "addr", addr, "pubKey", pubKey)
} }
csMetrics, p2pMetrics, memplMetrics, smMetrics := metricsProvider()
csMetrics, p2pMetrics, memplMetrics, smMetrics := metricsProvider(genDoc.ChainID)
// Make MempoolReactor // Make MempoolReactor
mempool := mempl.NewMempool( mempool := mempl.NewMempool(


+ 17
- 7
p2p/metrics.go View File

@ -7,7 +7,11 @@ import (
stdprometheus "github.com/prometheus/client_golang/prometheus" stdprometheus "github.com/prometheus/client_golang/prometheus"
) )
const MetricsSubsystem = "p2p"
const (
// MetricsSubsystem is a subsystem shared by all metrics exposed by this
// package.
MetricsSubsystem = "p2p"
)
// Metrics contains metrics exposed by this package. // Metrics contains metrics exposed by this package.
type Metrics struct { type Metrics struct {
@ -24,38 +28,44 @@ type Metrics struct {
} }
// PrometheusMetrics returns Metrics build using Prometheus client library. // PrometheusMetrics returns Metrics build using Prometheus client library.
func PrometheusMetrics(namespace string) *Metrics {
// Optionally, labels can be provided along with their values ("foo",
// "fooValue").
func PrometheusMetrics(namespace string, labelsAndValues ...string) *Metrics {
labels := []string{}
for i := 0; i < len(labelsAndValues); i += 2 {
labels = append(labels, labelsAndValues[i])
}
return &Metrics{ return &Metrics{
Peers: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ Peers: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace, Namespace: namespace,
Subsystem: MetricsSubsystem, Subsystem: MetricsSubsystem,
Name: "peers", Name: "peers",
Help: "Number of peers.", Help: "Number of peers.",
}, []string{}),
}, labels).With(labelsAndValues...),
PeerReceiveBytesTotal: prometheus.NewCounterFrom(stdprometheus.CounterOpts{ PeerReceiveBytesTotal: prometheus.NewCounterFrom(stdprometheus.CounterOpts{
Namespace: namespace, Namespace: namespace,
Subsystem: MetricsSubsystem, Subsystem: MetricsSubsystem,
Name: "peer_receive_bytes_total", Name: "peer_receive_bytes_total",
Help: "Number of bytes received from a given peer.", Help: "Number of bytes received from a given peer.",
}, []string{"peer_id"}),
}, append(labels, "peer_id")).With(labelsAndValues...),
PeerSendBytesTotal: prometheus.NewCounterFrom(stdprometheus.CounterOpts{ PeerSendBytesTotal: prometheus.NewCounterFrom(stdprometheus.CounterOpts{
Namespace: namespace, Namespace: namespace,
Subsystem: MetricsSubsystem, Subsystem: MetricsSubsystem,
Name: "peer_send_bytes_total", Name: "peer_send_bytes_total",
Help: "Number of bytes sent to a given peer.", Help: "Number of bytes sent to a given peer.",
}, []string{"peer_id"}),
}, append(labels, "peer_id")).With(labelsAndValues...),
PeerPendingSendBytes: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ PeerPendingSendBytes: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace, Namespace: namespace,
Subsystem: MetricsSubsystem, Subsystem: MetricsSubsystem,
Name: "peer_pending_send_bytes", Name: "peer_pending_send_bytes",
Help: "Number of pending bytes to be sent to a given peer.", Help: "Number of pending bytes to be sent to a given peer.",
}, []string{"peer_id"}),
}, append(labels, "peer_id")).With(labelsAndValues...),
NumTxs: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ NumTxs: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace, Namespace: namespace,
Subsystem: MetricsSubsystem, Subsystem: MetricsSubsystem,
Name: "num_txs", Name: "num_txs",
Help: "Number of transactions submitted by each peer.", Help: "Number of transactions submitted by each peer.",
}, []string{"peer_id"}),
}, append(labels, "peer_id")).With(labelsAndValues...),
} }
} }


+ 16
- 3
state/metrics.go View File

@ -7,14 +7,26 @@ import (
stdprometheus "github.com/prometheus/client_golang/prometheus" stdprometheus "github.com/prometheus/client_golang/prometheus"
) )
const MetricsSubsystem = "state"
const (
// MetricsSubsystem is a subsystem shared by all metrics exposed by this
// package.
MetricsSubsystem = "state"
)
// Metrics contains metrics exposed by this package.
type Metrics struct { type Metrics struct {
// Time between BeginBlock and EndBlock. // Time between BeginBlock and EndBlock.
BlockProcessingTime metrics.Histogram BlockProcessingTime metrics.Histogram
} }
func PrometheusMetrics(namespace string) *Metrics {
// PrometheusMetrics returns Metrics build using Prometheus client library.
// Optionally, labels can be provided along with their values ("foo",
// "fooValue").
func PrometheusMetrics(namespace string, labelsAndValues ...string) *Metrics {
labels := []string{}
for i := 0; i < len(labelsAndValues); i += 2 {
labels = append(labels, labelsAndValues[i])
}
return &Metrics{ return &Metrics{
BlockProcessingTime: prometheus.NewHistogramFrom(stdprometheus.HistogramOpts{ BlockProcessingTime: prometheus.NewHistogramFrom(stdprometheus.HistogramOpts{
Namespace: namespace, Namespace: namespace,
@ -22,10 +34,11 @@ func PrometheusMetrics(namespace string) *Metrics {
Name: "block_processing_time", Name: "block_processing_time",
Help: "Time between BeginBlock and EndBlock in ms.", Help: "Time between BeginBlock and EndBlock in ms.",
Buckets: stdprometheus.LinearBuckets(1, 10, 10), Buckets: stdprometheus.LinearBuckets(1, 10, 10),
}, []string{}),
}, labels).With(labelsAndValues...),
} }
} }
// NopMetrics returns no-op Metrics.
func NopMetrics() *Metrics { func NopMetrics() *Metrics {
return &Metrics{ return &Metrics{
BlockProcessingTime: discard.NewHistogram(), BlockProcessingTime: discard.NewHistogram(),


Loading…
Cancel
Save