prysm-pulse/beacon-chain/powchain/prometheus.go
kasey 19ff25f171
fixes 9029 + a few related client-stats fixes/improvements (#9039)
- fix missing scrape logic for these metrics:
      - sync_eth1_connected
      - sync_eth1_fallback_configured
      - sync_eth1_fallback_connected
    - update readme to add more detailed source info
      and indicate unsupported metrics.
    - fix documentation bug in prometheus help text
      for powchain_sync_eth1_connected

Co-authored-by: kasey <kasey@users.noreply.github.com>
2021-06-14 23:59:15 +00:00

154 lines
4.4 KiB
Go

package powchain
import (
"context"
"sync"
"github.com/prometheus/client_golang/prometheus"
"github.com/prysmaticlabs/prysm/shared/clientstats"
)
type BeaconNodeStatsUpdater interface {
Update(stats clientstats.BeaconNodeStats)
}
type PowchainCollector struct {
SyncEth1Connected *prometheus.Desc
SyncEth1FallbackConnected *prometheus.Desc
SyncEth1FallbackConfigured *prometheus.Desc // true if flag specified: --fallback-web3provider
updateChan chan clientstats.BeaconNodeStats
latestStats clientstats.BeaconNodeStats
sync.Mutex
ctx context.Context
finishChan chan struct{}
}
var _ BeaconNodeStatsUpdater = &PowchainCollector{}
var _ prometheus.Collector = &PowchainCollector{}
// Update satisfies the BeaconNodeStatsUpdater
func (pc *PowchainCollector) Update(update clientstats.BeaconNodeStats) {
pc.updateChan <- update
}
// Describe is invoked by the prometheus collection loop.
// It returns a set of metric Descriptor references which
// are also used in Collect to group collected metrics into
// a family. Describe and Collect together satisfy the
// prometheus.Collector interface.
func (pc *PowchainCollector) Describe(ch chan<- *prometheus.Desc) {
ch <- pc.SyncEth1Connected
ch <- pc.SyncEth1FallbackConfigured
ch <- pc.SyncEth1FallbackConnected
}
// Collect is invoked by the prometheus collection loop.
// It returns a set of Metrics representing the observation
// for the current collection period. In the case of this
// collector, we use values from the latest BeaconNodeStats
// value sent by the powchain Service, which updates this value
// whenever an internal event could change the state of one of
// the metrics.
// Describe and Collect together satisfy the
// prometheus.Collector interface.
func (pc *PowchainCollector) Collect(ch chan<- prometheus.Metric) {
bs := pc.getLatestStats()
var syncEth1FallbackConfigured float64 = 0
if bs.SyncEth1FallbackConfigured {
syncEth1FallbackConfigured = 1
}
ch <- prometheus.MustNewConstMetric(
pc.SyncEth1FallbackConfigured,
prometheus.GaugeValue,
syncEth1FallbackConfigured,
)
var syncEth1FallbackConnected float64 = 0
if bs.SyncEth1FallbackConnected {
syncEth1FallbackConnected = 1
}
ch <- prometheus.MustNewConstMetric(
pc.SyncEth1FallbackConnected,
prometheus.GaugeValue,
syncEth1FallbackConnected,
)
var syncEth1Connected float64 = 0
if bs.SyncEth1Connected {
syncEth1Connected = 1
}
ch <- prometheus.MustNewConstMetric(
pc.SyncEth1Connected,
prometheus.GaugeValue,
syncEth1Connected,
)
}
func (pc *PowchainCollector) getLatestStats() clientstats.BeaconNodeStats {
pc.Lock()
defer pc.Unlock()
return pc.latestStats
}
func (pc *PowchainCollector) setLatestStats(bs clientstats.BeaconNodeStats) {
pc.Lock()
pc.latestStats = bs
pc.Unlock()
}
// unregister returns true if the prometheus DefaultRegistry
// confirms that it was removed.
func (pc *PowchainCollector) unregister() bool {
return prometheus.Unregister(pc)
}
func (pc *PowchainCollector) latestStatsUpdateLoop() {
for {
select {
case <-pc.ctx.Done():
pc.unregister()
pc.finishChan <- struct{}{}
return
case bs := <-pc.updateChan:
pc.setLatestStats(bs)
}
}
}
func NewPowchainCollector(ctx context.Context) (*PowchainCollector, error) {
namespace := "powchain"
updateChan := make(chan clientstats.BeaconNodeStats, 2)
c := &PowchainCollector{
SyncEth1FallbackConfigured: prometheus.NewDesc(
prometheus.BuildFQName(namespace, "", "sync_eth1_fallback_configured"),
"Boolean recording whether a fallback eth1 endpoint was configured: 0=false, 1=true.",
nil,
nil,
),
SyncEth1FallbackConnected: prometheus.NewDesc(
prometheus.BuildFQName(namespace, "", "sync_eth1_fallback_connected"),
"Boolean indicating whether a fallback eth1 endpoint is currently connected: 0=false, 1=true.",
nil,
nil,
),
SyncEth1Connected: prometheus.NewDesc(
prometheus.BuildFQName(namespace, "", "sync_eth1_connected"),
"Boolean indicating whether an eth1 endpoint is currently connected: 0=false, 1=true.",
nil,
nil,
),
updateChan: updateChan,
ctx: ctx,
finishChan: make(chan struct{}, 1),
}
go c.latestStatsUpdateLoop()
return c, prometheus.Register(c)
}
type NopBeaconNodeStatsUpdater struct{}
func (nop *NopBeaconNodeStatsUpdater) Update(stats clientstats.BeaconNodeStats) {}
var _ BeaconNodeStatsUpdater = &NopBeaconNodeStatsUpdater{}