Skip to content

Commit a289ef3

Browse files
committed
chore: add store tracing
1 parent f791038 commit a289ef3

File tree

3 files changed

+701
-0
lines changed

3 files changed

+701
-0
lines changed

node/full.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ func newFullNode(
8181

8282
mainKV := store.NewEvNodeKVStore(database)
8383
evstore := store.New(mainKV)
84+
if nodeConfig.Instrumentation.IsTracingEnabled() {
85+
evstore = store.WithTracingStore(evstore)
86+
}
8487

8588
headerSyncService, err := initHeaderSyncService(mainKV, nodeConfig, genesis, p2pClient, logger)
8689
if err != nil {

pkg/store/tracing.go

Lines changed: 337 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,337 @@
1+
package store
2+
3+
import (
4+
"context"
5+
6+
ds "github.com/ipfs/go-datastore"
7+
"go.opentelemetry.io/otel"
8+
"go.opentelemetry.io/otel/attribute"
9+
"go.opentelemetry.io/otel/codes"
10+
"go.opentelemetry.io/otel/trace"
11+
12+
"github.com/evstack/ev-node/types"
13+
)
14+
15+
var _ Store = (*tracedStore)(nil)
16+
17+
type tracedStore struct {
18+
inner Store
19+
tracer trace.Tracer
20+
}
21+
22+
// WithTracingStore wraps a Store with OpenTelemetry tracing.
23+
func WithTracingStore(inner Store) Store {
24+
return &tracedStore{
25+
inner: inner,
26+
tracer: otel.Tracer("ev-node/store"),
27+
}
28+
}
29+
30+
func (t *tracedStore) Height(ctx context.Context) (uint64, error) {
31+
ctx, span := t.tracer.Start(ctx, "Store.Height")
32+
defer span.End()
33+
34+
height, err := t.inner.Height(ctx)
35+
if err != nil {
36+
span.RecordError(err)
37+
span.SetStatus(codes.Error, err.Error())
38+
return height, err
39+
}
40+
41+
span.SetAttributes(attribute.Int64("height", int64(height)))
42+
return height, nil
43+
}
44+
45+
func (t *tracedStore) GetBlockData(ctx context.Context, height uint64) (*types.SignedHeader, *types.Data, error) {
46+
ctx, span := t.tracer.Start(ctx, "Store.GetBlockData",
47+
trace.WithAttributes(attribute.Int64("height", int64(height))),
48+
)
49+
defer span.End()
50+
51+
header, data, err := t.inner.GetBlockData(ctx, height)
52+
if err != nil {
53+
span.RecordError(err)
54+
span.SetStatus(codes.Error, err.Error())
55+
return header, data, err
56+
}
57+
58+
return header, data, nil
59+
}
60+
61+
func (t *tracedStore) GetBlockByHash(ctx context.Context, hash []byte) (*types.SignedHeader, *types.Data, error) {
62+
ctx, span := t.tracer.Start(ctx, "Store.GetBlockByHash",
63+
trace.WithAttributes(attribute.String("hash", string(hash))),
64+
)
65+
defer span.End()
66+
67+
header, data, err := t.inner.GetBlockByHash(ctx, hash)
68+
if err != nil {
69+
span.RecordError(err)
70+
span.SetStatus(codes.Error, err.Error())
71+
return header, data, err
72+
}
73+
74+
if header != nil {
75+
span.SetAttributes(attribute.Int64("height", int64(header.Height())))
76+
}
77+
return header, data, nil
78+
}
79+
80+
func (t *tracedStore) GetSignature(ctx context.Context, height uint64) (*types.Signature, error) {
81+
ctx, span := t.tracer.Start(ctx, "Store.GetSignature",
82+
trace.WithAttributes(attribute.Int64("height", int64(height))),
83+
)
84+
defer span.End()
85+
86+
sig, err := t.inner.GetSignature(ctx, height)
87+
if err != nil {
88+
span.RecordError(err)
89+
span.SetStatus(codes.Error, err.Error())
90+
return sig, err
91+
}
92+
93+
return sig, nil
94+
}
95+
96+
func (t *tracedStore) GetSignatureByHash(ctx context.Context, hash []byte) (*types.Signature, error) {
97+
ctx, span := t.tracer.Start(ctx, "Store.GetSignatureByHash",
98+
trace.WithAttributes(attribute.String("hash", string(hash))),
99+
)
100+
defer span.End()
101+
102+
sig, err := t.inner.GetSignatureByHash(ctx, hash)
103+
if err != nil {
104+
span.RecordError(err)
105+
span.SetStatus(codes.Error, err.Error())
106+
return sig, err
107+
}
108+
109+
return sig, nil
110+
}
111+
112+
func (t *tracedStore) GetHeader(ctx context.Context, height uint64) (*types.SignedHeader, error) {
113+
ctx, span := t.tracer.Start(ctx, "Store.GetHeader",
114+
trace.WithAttributes(attribute.Int64("height", int64(height))),
115+
)
116+
defer span.End()
117+
118+
header, err := t.inner.GetHeader(ctx, height)
119+
if err != nil {
120+
span.RecordError(err)
121+
span.SetStatus(codes.Error, err.Error())
122+
return header, err
123+
}
124+
125+
return header, nil
126+
}
127+
128+
func (t *tracedStore) GetState(ctx context.Context) (types.State, error) {
129+
ctx, span := t.tracer.Start(ctx, "Store.GetState")
130+
defer span.End()
131+
132+
state, err := t.inner.GetState(ctx)
133+
if err != nil {
134+
span.RecordError(err)
135+
span.SetStatus(codes.Error, err.Error())
136+
return state, err
137+
}
138+
139+
span.SetAttributes(attribute.Int64("state.height", int64(state.LastBlockHeight)))
140+
return state, nil
141+
}
142+
143+
func (t *tracedStore) GetStateAtHeight(ctx context.Context, height uint64) (types.State, error) {
144+
ctx, span := t.tracer.Start(ctx, "Store.GetStateAtHeight",
145+
trace.WithAttributes(attribute.Int64("height", int64(height))),
146+
)
147+
defer span.End()
148+
149+
state, err := t.inner.GetStateAtHeight(ctx, height)
150+
if err != nil {
151+
span.RecordError(err)
152+
span.SetStatus(codes.Error, err.Error())
153+
return state, err
154+
}
155+
156+
return state, nil
157+
}
158+
159+
func (t *tracedStore) GetMetadata(ctx context.Context, key string) ([]byte, error) {
160+
ctx, span := t.tracer.Start(ctx, "Store.GetMetadata",
161+
trace.WithAttributes(attribute.String("key", key)),
162+
)
163+
defer span.End()
164+
165+
data, err := t.inner.GetMetadata(ctx, key)
166+
if err != nil {
167+
span.RecordError(err)
168+
span.SetStatus(codes.Error, err.Error())
169+
return data, err
170+
}
171+
172+
span.SetAttributes(attribute.Int("value.size", len(data)))
173+
return data, nil
174+
}
175+
176+
func (t *tracedStore) SetMetadata(ctx context.Context, key string, value []byte) error {
177+
ctx, span := t.tracer.Start(ctx, "Store.SetMetadata",
178+
trace.WithAttributes(
179+
attribute.String("key", key),
180+
attribute.Int("value.size", len(value)),
181+
),
182+
)
183+
defer span.End()
184+
185+
err := t.inner.SetMetadata(ctx, key, value)
186+
if err != nil {
187+
span.RecordError(err)
188+
span.SetStatus(codes.Error, err.Error())
189+
return err
190+
}
191+
192+
return nil
193+
}
194+
195+
func (t *tracedStore) Rollback(ctx context.Context, height uint64, aggregator bool) error {
196+
ctx, span := t.tracer.Start(ctx, "Store.Rollback",
197+
trace.WithAttributes(
198+
attribute.Int64("height", int64(height)),
199+
attribute.Bool("aggregator", aggregator),
200+
),
201+
)
202+
defer span.End()
203+
204+
err := t.inner.Rollback(ctx, height, aggregator)
205+
if err != nil {
206+
span.RecordError(err)
207+
span.SetStatus(codes.Error, err.Error())
208+
return err
209+
}
210+
211+
return nil
212+
}
213+
214+
func (t *tracedStore) Close() error {
215+
return t.inner.Close()
216+
}
217+
218+
func (t *tracedStore) NewBatch(ctx context.Context) (Batch, error) {
219+
ctx, span := t.tracer.Start(ctx, "Store.NewBatch")
220+
defer span.End()
221+
222+
batch, err := t.inner.NewBatch(ctx)
223+
if err != nil {
224+
span.RecordError(err)
225+
span.SetStatus(codes.Error, err.Error())
226+
return nil, err
227+
}
228+
229+
return &tracedBatch{
230+
inner: batch,
231+
tracer: t.tracer,
232+
}, nil
233+
}
234+
235+
var _ Batch = (*tracedBatch)(nil)
236+
237+
type tracedBatch struct {
238+
inner Batch
239+
tracer trace.Tracer
240+
}
241+
242+
func (b *tracedBatch) SaveBlockData(header *types.SignedHeader, data *types.Data, signature *types.Signature) error {
243+
_, span := b.tracer.Start(context.Background(), "Batch.SaveBlockData",
244+
trace.WithAttributes(attribute.Int64("height", int64(header.Height()))),
245+
)
246+
defer span.End()
247+
248+
err := b.inner.SaveBlockData(header, data, signature)
249+
if err != nil {
250+
span.RecordError(err)
251+
span.SetStatus(codes.Error, err.Error())
252+
return err
253+
}
254+
255+
return nil
256+
}
257+
258+
func (b *tracedBatch) SetHeight(height uint64) error {
259+
_, span := b.tracer.Start(context.Background(), "Batch.SetHeight",
260+
trace.WithAttributes(attribute.Int64("height", int64(height))),
261+
)
262+
defer span.End()
263+
264+
err := b.inner.SetHeight(height)
265+
if err != nil {
266+
span.RecordError(err)
267+
span.SetStatus(codes.Error, err.Error())
268+
return err
269+
}
270+
271+
return nil
272+
}
273+
274+
func (b *tracedBatch) UpdateState(state types.State) error {
275+
_, span := b.tracer.Start(context.Background(), "Batch.UpdateState",
276+
trace.WithAttributes(attribute.Int64("state.height", int64(state.LastBlockHeight))),
277+
)
278+
defer span.End()
279+
280+
err := b.inner.UpdateState(state)
281+
if err != nil {
282+
span.RecordError(err)
283+
span.SetStatus(codes.Error, err.Error())
284+
return err
285+
}
286+
287+
return nil
288+
}
289+
290+
func (b *tracedBatch) Commit() error {
291+
_, span := b.tracer.Start(context.Background(), "Batch.Commit")
292+
defer span.End()
293+
294+
err := b.inner.Commit()
295+
if err != nil {
296+
span.RecordError(err)
297+
span.SetStatus(codes.Error, err.Error())
298+
return err
299+
}
300+
301+
return nil
302+
}
303+
304+
func (b *tracedBatch) Put(key ds.Key, value []byte) error {
305+
_, span := b.tracer.Start(context.Background(), "Batch.Put",
306+
trace.WithAttributes(
307+
attribute.String("key", key.String()),
308+
attribute.Int("value.size", len(value)),
309+
),
310+
)
311+
defer span.End()
312+
313+
err := b.inner.Put(key, value)
314+
if err != nil {
315+
span.RecordError(err)
316+
span.SetStatus(codes.Error, err.Error())
317+
return err
318+
}
319+
320+
return nil
321+
}
322+
323+
func (b *tracedBatch) Delete(key ds.Key) error {
324+
_, span := b.tracer.Start(context.Background(), "Batch.Delete",
325+
trace.WithAttributes(attribute.String("key", key.String())),
326+
)
327+
defer span.End()
328+
329+
err := b.inner.Delete(key)
330+
if err != nil {
331+
span.RecordError(err)
332+
span.SetStatus(codes.Error, err.Error())
333+
return err
334+
}
335+
336+
return nil
337+
}

0 commit comments

Comments
 (0)