11package evm
22
33import (
4+ "context"
45 "math/big"
6+ "sync"
57 "time"
68
79 "github.com/prometheus/client_golang/prometheus"
810 "github.com/prometheus/client_golang/prometheus/promauto"
11+ "go.opentelemetry.io/otel/attribute"
12+ "go.opentelemetry.io/otel/metric"
13+
14+ "github.com/smartcontractkit/chainlink-common/pkg/beholder"
915)
1016
1117// Prometheus gauges for the node's view of on-chain OCR2 median aggregator state (DF-22676).
2935 }, []string {"chain_id" , "contract_address" , "transmitter_id" })
3036)
3137
38+ type medianOnchainOtelInstruments struct {
39+ latestAnswer metric.Float64Gauge
40+ latestTimestampUnix metric.Float64Gauge
41+ epoch metric.Int64Gauge
42+ round metric.Int64Gauge
43+ }
44+
45+ var (
46+ medianOnchainOtelInst * medianOnchainOtelInstruments
47+ medianOnchainOtelOnce sync.Once
48+ )
49+
50+ func loadMedianOnchainOtel () * medianOnchainOtelInstruments {
51+ medianOnchainOtelOnce .Do (func () {
52+ m := beholder .GetMeter ()
53+ latestAnswer , err := m .Float64Gauge ("ocr2_onchain_transmission_latest_answer" )
54+ if err != nil {
55+ return
56+ }
57+ latestTimestampUnix , err := m .Float64Gauge ("ocr2_onchain_transmission_latest_timestamp_unix" )
58+ if err != nil {
59+ return
60+ }
61+ epoch , err := m .Int64Gauge ("ocr2_onchain_transmission_epoch" )
62+ if err != nil {
63+ return
64+ }
65+ round , err := m .Int64Gauge ("ocr2_onchain_transmission_round" )
66+ if err != nil {
67+ return
68+ }
69+ medianOnchainOtelInst = & medianOnchainOtelInstruments {
70+ latestAnswer : latestAnswer ,
71+ latestTimestampUnix : latestTimestampUnix ,
72+ epoch : epoch ,
73+ round : round ,
74+ }
75+ })
76+ return medianOnchainOtelInst
77+ }
78+
3279type medianOnchainViewMetrics struct {
3380 chainID string
3481 contract string
@@ -46,12 +93,28 @@ func newMedianOnchainViewMetrics(chainID, contractAddress, transmitterID string)
4693 }
4794}
4895
49- func (m * medianOnchainViewMetrics ) record (latestAnswer * big.Int , epoch uint32 , round uint8 , updatedAt time.Time ) {
96+ func (m * medianOnchainViewMetrics ) onchainAttrs () metric.MeasurementOption {
97+ return metric .WithAttributes (
98+ attribute .String ("chain_id" , m .chainID ),
99+ attribute .String ("contract_address" , m .contract ),
100+ attribute .String ("transmitter_id" , m .transmitterID ),
101+ )
102+ }
103+
104+ func (m * medianOnchainViewMetrics ) record (ctx context.Context , latestAnswer * big.Int , epoch uint32 , round uint8 , updatedAt time.Time ) {
50105 lv := bigIntToPromGaugeValue (latestAnswer )
51106 promOCR2OnchainLatestAnswer .WithLabelValues (m .chainID , m .contract , m .transmitterID ).Set (lv )
52107 promOCR2OnchainLatestTimestampUnix .WithLabelValues (m .chainID , m .contract , m .transmitterID ).Set (float64 (updatedAt .Unix ()))
53108 promOCR2OnchainEpoch .WithLabelValues (m .chainID , m .contract , m .transmitterID ).Set (float64 (epoch ))
54109 promOCR2OnchainRound .WithLabelValues (m .chainID , m .contract , m .transmitterID ).Set (float64 (round ))
110+
111+ if ot := loadMedianOnchainOtel (); ot != nil {
112+ opts := m .onchainAttrs ()
113+ ot .latestAnswer .Record (ctx , lv , opts )
114+ ot .latestTimestampUnix .Record (ctx , float64 (updatedAt .Unix ()), opts )
115+ ot .epoch .Record (ctx , int64 (epoch ), opts )
116+ ot .round .Record (ctx , int64 (round ), opts )
117+ }
55118}
56119
57120func bigIntToPromGaugeValue (i * big.Int ) float64 {
0 commit comments