forked from alpe/cosmos-tracing
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtracing.go
75 lines (61 loc) · 2.22 KB
/
tracing.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package tracing
import (
"bytes"
"io"
"os"
"time"
"github.com/cometbft/cometbft/libs/log"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/opentracing/opentracing-go"
otlog "github.com/opentracing/opentracing-go/log"
)
type storeLogSetting int
const (
all storeLogSetting = iota
writesOnly
nothing
)
// Exec callback to be executed within a tracing contexts. returned error is for tracking only and not causing any side effects
type Exec func(workCtx sdk.Context, span opentracing.Span) error
// DoWithTracing execute callback in tracing context
func DoWithTracing(ctx sdk.Context, operationName string, logStore storeLogSetting, cb Exec) {
DoWithTracingAsync(ctx, operationName, logStore, cb)()
}
func DoWithTracingAsync(ctx sdk.Context, operationName string, logStore storeLogSetting, cb Exec) func() {
var now time.Time
ctx, now = WithBlockTimeClock(ctx)
span, goCtx := opentracing.StartSpanFromContext(ctx.Context(), operationName, opentracing.StartTime(now))
span.SetTag(tagBlockHeight, ctx.BlockHeight())
ms := NewTracingMultiStore(ctx.MultiStore(), logStore == writesOnly)
if logStore != nothing {
ctx = ctx.WithMultiStore(ms)
}
em := sdk.NewEventManager()
var buf bytes.Buffer
logger := log.NewTMLogger(log.NewSyncWriter(io.MultiWriter(&buf, os.Stdout)))
gm := NewTraceGasMeter(ctx.GasMeter())
if err := cb(ctx.WithContext(goCtx).WithEventManager(em).WithLogger(logger).WithGasMeter(gm), span); err != nil {
span.LogFields(otlog.Error(err))
span.SetTag(tagErrored, "true")
}
if logStore != nothing {
span.LogFields(safeLogField(logRawStoreIO, ms.getStoreDataLimited(MaxStoreTraced)))
}
span.LogFields(safeLogField(logRawEvents, toJson(em.Events())))
span.LogFields(safeLogField(logRawLoggerOut, cutLength(buf.String(), MaxSDKLogTraced)))
gasUsage := struct {
Application []GasTrace
Storage []GasTrace
}{gm.traces, ms.traceGasMeter.traces}
span.LogFields(safeLogField(logGasUsage, toJson(gasUsage)))
ctx.EventManager().EmitEvents(em.Events())
return func() {
_, now := WithBlockTimeClock(ctx)
span.FinishWithOptions(opentracing.FinishOptions{
FinishTime: now,
})
}
}
func safeLogField(key string, descr string) otlog.Field {
return otlog.String(key, cutLength(descr, DefaultMaxLength))
}