-
Notifications
You must be signed in to change notification settings - Fork 9
/
stats.go
120 lines (100 loc) · 2.76 KB
/
stats.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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package chainload
import (
"time"
metrics "github.com/rcrowley/go-metrics"
"go.uber.org/zap/zapcore"
)
var (
latestBlockNumberTimer = metrics.GetOrRegisterTimer("timer/latestBlockNumber", nil)
sendTxTimer = metrics.GetOrRegisterTimer("timer/sendTx", nil)
sendTxErrMeter = metrics.GetOrRegisterMeter("meter/sendTx/err", nil)
signTxTimer = metrics.GetOrRegisterTimer("timer/signTx", nil)
suggestGasPriceTimer = metrics.GetOrRegisterTimer("timer/suggestGasPrice", nil)
pendingBalanceAtTimer = metrics.GetOrRegisterTimer("timer/pendingBalanceAt", nil)
pendingNonceAtTimer = metrics.GetOrRegisterTimer("timer/pendingNonceAt", nil)
)
// Report holds statistics for a stretch of time.
type Report struct {
dur time.Duration // Length of report.
txs int64 // Successful transaction sends.
errs int64 // Failed transaction sends.
}
func (r *Report) MarshalLogObject(oe zapcore.ObjectEncoder) error {
oe.AddDuration("duration", r.dur)
oe.AddInt64("txs", r.txs)
oe.AddInt64("errs", r.errs)
oe.AddFloat64("tps", r.TPS())
return nil
}
func (r *Report) TPS() float64 {
return float64(r.txs) / r.dur.Seconds()
}
type Status struct {
latest, recent, total Report
}
func (s *Status) MarshalLogObject(oe zapcore.ObjectEncoder) error {
oe.AddObject("latest", &s.latest)
oe.AddObject("recent", &s.recent)
oe.AddObject("total", &s.total)
return nil
}
// Reporter tracks statistics and emits reports for an execution.
type Reporter interface {
// Report generates a report since the last (or start).
Report() *Report
}
func NewReporter() Reporter {
return &reporter{
lastTS: time.Now(),
}
}
type reporter struct {
// Last report.
lastTS time.Time // Must init with start for seed report to make sense.
lastTxs int64
lastErrs int64
}
func (s *reporter) Report() *Report {
now := time.Now()
txs := sendTxTimer.Count()
errs := sendTxErrMeter.Count()
r := &Report{
dur: now.Sub(s.lastTS),
txs: txs - s.lastTxs,
errs: errs - s.lastErrs,
}
s.lastTS = now
s.lastTxs = txs
s.lastErrs = errs
return r
}
// Reports keeps a history of recent reports.
type Reports struct {
latest *Report
recent [10]*Report // Circular buffer or recent reports.
recIdx int // Index into recent to place next report.
total Report
}
// Add adds the report to the set of reports.
func (r *Reports) Add(rep *Report) *Status {
r.latest = rep
r.recent[r.recIdx] = rep
r.recIdx = (r.recIdx + 1) % 10
r.total.dur += rep.dur
r.total.txs += rep.txs
r.total.errs += rep.errs
return r.status()
}
func (r *Reports) status() *Status {
var s Status
s.latest = *r.latest
for _, rec := range r.recent {
if rec != nil {
s.recent.dur += rec.dur
s.recent.txs += rec.txs
s.recent.errs += rec.errs
}
}
s.total = r.total
return &s
}