Skip to content

Commit 07dd5d1

Browse files
authored
feat(tracing): adding eth client tracing (#2960)
<!-- Please read and fill out this form before submitting your PR. Please make sure you have reviewed our contributors guide before submitting your first PR. NOTE: PR titles should follow semantic commits: https://www.conventionalcommits.org/en/v1.0.0/ --> ## Overview This PR follows the same pattern as the previous PR and creates a decorator around the eth client that injects tracing. Sample grafana output with metrics enabled. <img width="912" height="741" alt="image" src="https://github.com/user-attachments/assets/9d32f48e-a01c-47c7-94a3-168d44aa5fe9" /> <img width="902" height="542" alt="image" src="https://github.com/user-attachments/assets/a777a28e-5f3b-42e0-a31a-7527521c249b" /> <!-- Please provide an explanation of the PR, including the appropriate context, background, goal, and rationale. If there is an issue with this information, please provide a tl;dr and link the issue. Ex: Closes #<issue number> -->
1 parent ddf8f31 commit 07dd5d1

5 files changed

Lines changed: 434 additions & 11 deletions

File tree

execution/evm/eth_rpc_client.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package evm
2+
3+
import (
4+
"context"
5+
"math/big"
6+
7+
"github.com/ethereum/go-ethereum/core/types"
8+
"github.com/ethereum/go-ethereum/ethclient"
9+
)
10+
11+
type ethRPCClient struct {
12+
client *ethclient.Client
13+
}
14+
15+
func NewEthRPCClient(client *ethclient.Client) EthRPCClient {
16+
return &ethRPCClient{client: client}
17+
}
18+
19+
func (e *ethRPCClient) HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) {
20+
return e.client.HeaderByNumber(ctx, number)
21+
}
22+
23+
func (e *ethRPCClient) GetTxs(ctx context.Context) ([]string, error) {
24+
var result []string
25+
err := e.client.Client().CallContext(ctx, &result, "txpoolExt_getTxs")
26+
if err != nil {
27+
return nil, err
28+
}
29+
return result, nil
30+
}

execution/evm/eth_rpc_tracing.go

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package evm
2+
3+
import (
4+
"context"
5+
"math/big"
6+
7+
"github.com/ethereum/go-ethereum/core/types"
8+
"go.opentelemetry.io/otel"
9+
"go.opentelemetry.io/otel/attribute"
10+
"go.opentelemetry.io/otel/codes"
11+
"go.opentelemetry.io/otel/trace"
12+
)
13+
14+
// tracedEthRPCClient wraps an EthRPCClient and records spans for observability.
15+
type tracedEthRPCClient struct {
16+
inner EthRPCClient
17+
tracer trace.Tracer
18+
}
19+
20+
// withTracingEthRPCClient decorates an EthRPCClient with OpenTelemetry tracing.
21+
func withTracingEthRPCClient(inner EthRPCClient) EthRPCClient {
22+
return &tracedEthRPCClient{
23+
inner: inner,
24+
tracer: otel.Tracer("ev-node/execution/eth-rpc"),
25+
}
26+
}
27+
28+
func (t *tracedEthRPCClient) HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) {
29+
var blockNumber string
30+
if number == nil {
31+
blockNumber = "latest"
32+
} else {
33+
blockNumber = number.String()
34+
}
35+
36+
ctx, span := t.tracer.Start(ctx, "Eth.GetBlockByNumber",
37+
trace.WithAttributes(
38+
attribute.String("method", "eth_getBlockByNumber"),
39+
attribute.String("block_number", blockNumber),
40+
),
41+
)
42+
defer span.End()
43+
44+
result, err := t.inner.HeaderByNumber(ctx, number)
45+
if err != nil {
46+
span.RecordError(err)
47+
span.SetStatus(codes.Error, err.Error())
48+
return nil, err
49+
}
50+
51+
span.SetAttributes(
52+
attribute.String("block_hash", result.Hash().Hex()),
53+
attribute.String("state_root", result.Root.Hex()),
54+
attribute.Int64("gas_limit", int64(result.GasLimit)),
55+
attribute.Int64("gas_used", int64(result.GasUsed)),
56+
attribute.Int64("timestamp", int64(result.Time)),
57+
)
58+
59+
return result, nil
60+
}
61+
62+
func (t *tracedEthRPCClient) GetTxs(ctx context.Context) ([]string, error) {
63+
ctx, span := t.tracer.Start(ctx, "TxPool.GetTxs",
64+
trace.WithAttributes(
65+
attribute.String("method", "txpoolExt_getTxs"),
66+
),
67+
)
68+
defer span.End()
69+
70+
result, err := t.inner.GetTxs(ctx)
71+
if err != nil {
72+
span.RecordError(err)
73+
span.SetStatus(codes.Error, err.Error())
74+
return nil, err
75+
}
76+
77+
span.SetAttributes(
78+
attribute.Int("tx_count", len(result)),
79+
)
80+
81+
return result, nil
82+
}

0 commit comments

Comments
 (0)