github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/powchain/prometheus.go (about)

     1  package powchain
     2  
     3  import (
     4  	"context"
     5  	"sync"
     6  
     7  	"github.com/prometheus/client_golang/prometheus"
     8  	"github.com/prysmaticlabs/prysm/shared/clientstats"
     9  )
    10  
    11  type BeaconNodeStatsUpdater interface {
    12  	Update(stats clientstats.BeaconNodeStats)
    13  }
    14  
    15  type PowchainCollector struct {
    16  	SyncEth1Connected          *prometheus.Desc
    17  	SyncEth1FallbackConnected  *prometheus.Desc
    18  	SyncEth1FallbackConfigured *prometheus.Desc // true if flag specified: --fallback-web3provider
    19  	updateChan                 chan clientstats.BeaconNodeStats
    20  	latestStats                clientstats.BeaconNodeStats
    21  	sync.Mutex
    22  	ctx        context.Context
    23  	finishChan chan struct{}
    24  }
    25  
    26  var _ BeaconNodeStatsUpdater = &PowchainCollector{}
    27  var _ prometheus.Collector = &PowchainCollector{}
    28  
    29  // Update satisfies the BeaconNodeStatsUpdater
    30  func (pc *PowchainCollector) Update(update clientstats.BeaconNodeStats) {
    31  	pc.updateChan <- update
    32  }
    33  
    34  // Describe is invoked by the prometheus collection loop.
    35  // It returns a set of metric Descriptor references which
    36  // are also used in Collect to group collected metrics into
    37  // a family. Describe and Collect together satisfy the
    38  // prometheus.Collector interface.
    39  func (pc *PowchainCollector) Describe(ch chan<- *prometheus.Desc) {
    40  	ch <- pc.SyncEth1Connected
    41  	ch <- pc.SyncEth1FallbackConfigured
    42  	ch <- pc.SyncEth1FallbackConnected
    43  }
    44  
    45  // Collect is invoked by the prometheus collection loop.
    46  // It returns a set of Metrics representing the observation
    47  // for the current collection period. In the case of this
    48  // collector, we use values from the latest BeaconNodeStats
    49  // value sent by the powchain Service, which updates this value
    50  // whenever an internal event could change the state of one of
    51  // the metrics.
    52  // Describe and Collect together satisfy the
    53  // prometheus.Collector interface.
    54  func (pc *PowchainCollector) Collect(ch chan<- prometheus.Metric) {
    55  	bs := pc.getLatestStats()
    56  
    57  	var syncEth1FallbackConfigured float64 = 0
    58  	if bs.SyncEth1FallbackConfigured {
    59  		syncEth1FallbackConfigured = 1
    60  	}
    61  	ch <- prometheus.MustNewConstMetric(
    62  		pc.SyncEth1FallbackConfigured,
    63  		prometheus.GaugeValue,
    64  		syncEth1FallbackConfigured,
    65  	)
    66  
    67  	var syncEth1FallbackConnected float64 = 0
    68  	if bs.SyncEth1FallbackConnected {
    69  		syncEth1FallbackConnected = 1
    70  	}
    71  	ch <- prometheus.MustNewConstMetric(
    72  		pc.SyncEth1FallbackConnected,
    73  		prometheus.GaugeValue,
    74  		syncEth1FallbackConnected,
    75  	)
    76  
    77  	var syncEth1Connected float64 = 0
    78  	if bs.SyncEth1Connected {
    79  		syncEth1Connected = 1
    80  	}
    81  	ch <- prometheus.MustNewConstMetric(
    82  		pc.SyncEth1Connected,
    83  		prometheus.GaugeValue,
    84  		syncEth1Connected,
    85  	)
    86  }
    87  
    88  func (pc *PowchainCollector) getLatestStats() clientstats.BeaconNodeStats {
    89  	pc.Lock()
    90  	defer pc.Unlock()
    91  	return pc.latestStats
    92  }
    93  
    94  func (pc *PowchainCollector) setLatestStats(bs clientstats.BeaconNodeStats) {
    95  	pc.Lock()
    96  	pc.latestStats = bs
    97  	pc.Unlock()
    98  }
    99  
   100  // unregister returns true if the prometheus DefaultRegistry
   101  // confirms that it was removed.
   102  func (pc *PowchainCollector) unregister() bool {
   103  	return prometheus.Unregister(pc)
   104  }
   105  
   106  func (pc *PowchainCollector) latestStatsUpdateLoop() {
   107  	for {
   108  		select {
   109  		case <-pc.ctx.Done():
   110  			pc.unregister()
   111  			pc.finishChan <- struct{}{}
   112  			return
   113  		case bs := <-pc.updateChan:
   114  			pc.setLatestStats(bs)
   115  		}
   116  	}
   117  }
   118  
   119  func NewPowchainCollector(ctx context.Context) (*PowchainCollector, error) {
   120  	namespace := "powchain"
   121  	updateChan := make(chan clientstats.BeaconNodeStats, 2)
   122  	c := &PowchainCollector{
   123  		SyncEth1FallbackConfigured: prometheus.NewDesc(
   124  			prometheus.BuildFQName(namespace, "", "sync_eth1_fallback_configured"),
   125  			"Boolean recording whether a fallback eth1 endpoint was configured: 0=false, 1=true.",
   126  			nil,
   127  			nil,
   128  		),
   129  		SyncEth1FallbackConnected: prometheus.NewDesc(
   130  			prometheus.BuildFQName(namespace, "", "sync_eth1_fallback_connected"),
   131  			"Boolean indicating whether a fallback eth1 endpoint is currently connected: 0=false, 1=true.",
   132  			nil,
   133  			nil,
   134  		),
   135  		SyncEth1Connected: prometheus.NewDesc(
   136  			prometheus.BuildFQName(namespace, "", "sync_eth1_connected"),
   137  			"Boolean indicating whether an eth1 endpoint is currently connected: 0=false, 1=true.",
   138  			nil,
   139  			nil,
   140  		),
   141  		updateChan: updateChan,
   142  		ctx:        ctx,
   143  		finishChan: make(chan struct{}, 1),
   144  	}
   145  	go c.latestStatsUpdateLoop()
   146  	return c, prometheus.Register(c)
   147  }
   148  
   149  type NopBeaconNodeStatsUpdater struct{}
   150  
   151  func (nop *NopBeaconNodeStatsUpdater) Update(stats clientstats.BeaconNodeStats) {}
   152  
   153  var _ BeaconNodeStatsUpdater = &NopBeaconNodeStatsUpdater{}