Skip to content
This repository was archived by the owner on May 9, 2024. It is now read-only.

Commit cda9c26

Browse files
authored
feat: implement block delta metric (#342)
1 parent d75ae73 commit cda9c26

File tree

4 files changed

+55
-13
lines changed

4 files changed

+55
-13
lines changed

chains/evm/listener/listener.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,14 @@ type ChainClient interface {
2323
LatestBlock() (*big.Int, error)
2424
}
2525

26+
type Metrics interface {
27+
TrackBlockDelta(domainID uint8, head *big.Int, current *big.Int)
28+
}
29+
2630
type EVMListener struct {
2731
client ChainClient
2832
eventHandlers []EventHandler
33+
metrics Metrics
2934

3035
domainID uint8
3136
blockstore *store.BlockStore
@@ -42,6 +47,7 @@ func NewEVMListener(
4247
client ChainClient,
4348
eventHandlers []EventHandler,
4449
blockstore *store.BlockStore,
50+
metrics Metrics,
4551
domainID uint8,
4652
blockRetryInterval time.Duration,
4753
blockConfirmations *big.Int,
@@ -50,6 +56,7 @@ func NewEVMListener(
5056
return &EVMListener{
5157
log: logger,
5258
client: client,
59+
metrics: metrics,
5360
eventHandlers: eventHandlers,
5461
blockstore: blockstore,
5562
domainID: domainID,
@@ -85,6 +92,7 @@ func (l *EVMListener) ListenToEvents(ctx context.Context, startBlock *big.Int, m
8592
continue
8693
}
8794

95+
l.metrics.TrackBlockDelta(l.domainID, head, endBlock)
8896
l.log.Debug().Msgf("Fetching evm events for block range %s-%s", startBlock, endBlock)
8997

9098
for _, handler := range l.eventHandlers {

example/app/app.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ func Run() error {
4747
}
4848
blockstore := store.NewBlockStore(db)
4949

50+
meter, err := opentelemetry.DefaultMeter(context.Background(), configuration.RelayerConfig.OpenTelemetryCollectorURL)
51+
if err != nil {
52+
panic(err)
53+
}
54+
metrics := opentelemetry.NewOpenTelemetry(meter)
55+
5056
ctx, cancel := context.WithCancel(context.Background())
5157
chains := []relayer.RelayedChain{}
5258
for _, chainConfig := range configuration.ChainConfigs {
@@ -82,7 +88,7 @@ func Run() error {
8288
eventListener := events.NewListener(client)
8389
eventHandlers := make([]listener.EventHandler, 0)
8490
eventHandlers = append(eventHandlers, listener.NewDepositEventHandler(eventListener, depositHandler, common.HexToAddress(config.Bridge), *config.GeneralChainConfig.Id))
85-
evmListener := listener.NewEVMListener(client, eventHandlers, blockstore, *config.GeneralChainConfig.Id, config.BlockRetryInterval, config.BlockConfirmations, config.BlockInterval)
91+
evmListener := listener.NewEVMListener(client, eventHandlers, blockstore, metrics, *config.GeneralChainConfig.Id, config.BlockRetryInterval, config.BlockConfirmations, config.BlockInterval)
8692

8793
mh := executor.NewEVMMessageHandler(bridgeContract)
8894
mh.RegisterMessageHandler(config.Erc20Handler, executor.ERC20MessageHandler)
@@ -105,11 +111,6 @@ func Run() error {
105111
}
106112
}
107113

108-
meter, err := opentelemetry.DefaultMeter(context.Background(), configuration.RelayerConfig.OpenTelemetryCollectorURL)
109-
if err != nil {
110-
panic(err)
111-
}
112-
metrics := opentelemetry.NewOpenTelemetry(meter)
113114
r := relayer.NewRelayer(
114115
chains,
115116
metrics,

opentelemetry/metrics.go

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package opentelemetry
22

33
import (
4+
"context"
5+
"math/big"
6+
7+
"go.opentelemetry.io/otel/attribute"
48
"go.opentelemetry.io/otel/metric"
59
"go.opentelemetry.io/otel/metric/unit"
610
)
@@ -10,11 +14,15 @@ type ChainbridgeMetrics struct {
1014
ExecutionErrorCount metric.Int64Counter
1115
ExecutionLatency metric.Int64Histogram
1216
ExecutionLatencyPerRoute metric.Int64Histogram
17+
BlockDelta metric.Int64GaugeObserver
18+
19+
BlockDeltaMap map[uint8]*big.Int
1320
}
1421

1522
// NewChainbridgeMetrics creates an instance of ChainbridgeMetrics
1623
// with provided OpenTelemetry meter
17-
func NewChainbridgeMetrics(meter metric.Meter) *ChainbridgeMetrics {
24+
func NewChainbridgeMetrics(meter metric.Meter, genericLabels ...attribute.KeyValue) *ChainbridgeMetrics {
25+
blockDeltaMap := make(map[uint8]*big.Int)
1826
return &ChainbridgeMetrics{
1927
DepositEventCount: metric.Must(meter).NewInt64Counter(
2028
"chainbridge.DepositEventCount",
@@ -33,5 +41,16 @@ func NewChainbridgeMetrics(meter metric.Meter) *ChainbridgeMetrics {
3341
metric.WithDescription("Execution time histogram between indexing event and executing it"),
3442
metric.WithUnit(unit.Milliseconds),
3543
),
44+
BlockDelta: metric.Must(meter).NewInt64GaugeObserver(
45+
"chainbridge.BlockDelta",
46+
func(ctx context.Context, result metric.Int64ObserverResult) {
47+
for domainID, delta := range blockDeltaMap {
48+
labels := append(genericLabels, attribute.Int64("domainID", int64(domainID)))
49+
result.Observe(delta.Int64(), labels...)
50+
}
51+
},
52+
metric.WithDescription("Difference between chain head and current indexed block per domain"),
53+
),
54+
BlockDeltaMap: blockDeltaMap,
3655
}
3756
}

opentelemetry/opentelemetry.go

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package opentelemetry
22

33
import (
44
"context"
5+
"math/big"
56
"net/url"
67
"time"
78

@@ -52,37 +53,50 @@ func DefaultMeter(ctx context.Context, collectorRawURL string) (metric.Meter, er
5253

5354
type OpenTelemetry struct {
5455
metrics *ChainbridgeMetrics
56+
meter metric.Meter
5557
messageEventTime map[string]time.Time
58+
genericLabels []attribute.KeyValue
5659
}
5760

5861
// NewOpenTelemetry initializes OpenTelementry metrics
59-
func NewOpenTelemetry(meter metric.Meter) *OpenTelemetry {
60-
metrics := NewChainbridgeMetrics(meter)
62+
func NewOpenTelemetry(meter metric.Meter, labels ...attribute.KeyValue) *OpenTelemetry {
63+
metrics := NewChainbridgeMetrics(meter, labels...)
6164
return &OpenTelemetry{
6265
metrics: metrics,
66+
meter: meter,
67+
genericLabels: labels,
6368
messageEventTime: make(map[string]time.Time),
6469
}
6570
}
6671

6772
// TrackDepositMessage extracts metrics from deposit message and sends
6873
// them to OpenTelemetry collector
6974
func (t *OpenTelemetry) TrackDepositMessage(m *message.Message) {
70-
t.metrics.DepositEventCount.Add(context.Background(), 1, attribute.Int64("source", int64(m.Source)))
75+
labels := append(t.genericLabels, attribute.Int64("source", int64(m.Source)))
76+
t.metrics.DepositEventCount.Add(context.Background(), 1, labels...)
7177
t.messageEventTime[m.ID()] = time.Now()
7278
}
7379

7480
func (t *OpenTelemetry) TrackExecutionError(m *message.Message) {
75-
t.metrics.ExecutionErrorCount.Add(context.Background(), 1, attribute.Int64("destination", int64(m.Source)))
81+
labels := append(t.genericLabels, attribute.Int64("destination", int64(m.Source)))
82+
t.metrics.ExecutionErrorCount.Add(context.Background(), 1, labels...)
7683
delete(t.messageEventTime, m.ID())
7784
}
7885

7986
func (t *OpenTelemetry) TrackSuccessfulExecution(m *message.Message) {
87+
labels := append(t.genericLabels, attribute.Int64("source", int64(m.Source)))
88+
labels = append(labels, attribute.Int64("destination", int64(m.Destination)))
8089
executionLatency := time.Since(t.messageEventTime[m.ID()]).Milliseconds() / 1000
8190
t.metrics.ExecutionLatency.Record(context.Background(), executionLatency)
8291
t.metrics.ExecutionLatencyPerRoute.Record(
8392
context.Background(),
8493
executionLatency,
85-
attribute.Int64("source", int64(m.Source)),
86-
attribute.Int64("destination", int64(m.Destination)))
94+
labels...,
95+
)
8796
delete(t.messageEventTime, m.ID())
8897
}
98+
99+
func (t *OpenTelemetry) TrackBlockDelta(domainID uint8, head *big.Int, current *big.Int) {
100+
t.metrics.BlockDeltaMap[domainID] = new(big.Int).Sub(head, current)
101+
t.meter.RecordBatch(context.Background(), []attribute.KeyValue{})
102+
}

0 commit comments

Comments
 (0)