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{}