-
Notifications
You must be signed in to change notification settings - Fork 225
/
stats.go
137 lines (113 loc) · 3.95 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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// (c) 2021-2022, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package stats
import (
"fmt"
"time"
"github.com/ava-labs/subnet-evm/metrics"
"github.com/ava-labs/subnet-evm/plugin/evm/message"
)
var (
_ ClientSyncerStats = &clientSyncerStats{}
_ ClientSyncerStats = &noopStats{}
)
type ClientSyncerStats interface {
GetMetric(message.Request) (MessageMetric, error)
}
type MessageMetric interface {
IncRequested()
IncSucceeded()
IncFailed()
IncInvalidResponse()
IncReceived(int64)
UpdateRequestLatency(time.Duration)
}
type messageMetric struct {
requested metrics.Counter // Number of times a request has been sent
succeeded metrics.Counter // Number of times a request has succeeded
failed metrics.Counter // Number of times a request failed (does not include invalid responses)
invalidResponse metrics.Counter // Number of times a request failed due to an invalid response
received metrics.Counter // Number of items that have been received
requestLatency metrics.Timer // Latency for this request
}
func NewMessageMetric(name string) MessageMetric {
return &messageMetric{
requested: metrics.GetOrRegisterCounter(fmt.Sprintf("%s_requested", name), nil),
succeeded: metrics.GetOrRegisterCounter(fmt.Sprintf("%s_succeeded", name), nil),
failed: metrics.GetOrRegisterCounter(fmt.Sprintf("%s_failed", name), nil),
invalidResponse: metrics.GetOrRegisterCounter(fmt.Sprintf("%s_invalid_response", name), nil),
received: metrics.GetOrRegisterCounter(fmt.Sprintf("%s_received", name), nil),
requestLatency: metrics.GetOrRegisterTimer(fmt.Sprintf("%s_request_latency", name), nil),
}
}
func (m *messageMetric) IncRequested() {
m.requested.Inc(1)
}
func (m *messageMetric) IncSucceeded() {
m.succeeded.Inc(1)
}
func (m *messageMetric) IncFailed() {
m.failed.Inc(1)
}
func (m *messageMetric) IncInvalidResponse() {
m.invalidResponse.Inc(1)
}
func (m *messageMetric) IncReceived(size int64) {
m.received.Inc(size)
}
func (m *messageMetric) UpdateRequestLatency(duration time.Duration) {
m.requestLatency.Update(duration)
}
type clientSyncerStats struct {
atomicTrieLeavesMetric,
stateTrieLeavesMetric,
codeRequestMetric,
blockRequestMetric MessageMetric
}
// NewClientSyncerStats returns stats for the client syncer
func NewClientSyncerStats() ClientSyncerStats {
return &clientSyncerStats{
atomicTrieLeavesMetric: NewMessageMetric("sync_atomic_trie_leaves"),
stateTrieLeavesMetric: NewMessageMetric("sync_state_trie_leaves"),
codeRequestMetric: NewMessageMetric("sync_code"),
blockRequestMetric: NewMessageMetric("sync_blocks"),
}
}
// GetMetric returns the appropriate messaage metric for the given request
func (c *clientSyncerStats) GetMetric(msgIntf message.Request) (MessageMetric, error) {
switch msg := msgIntf.(type) {
case message.BlockRequest:
return c.blockRequestMetric, nil
case message.CodeRequest:
return c.codeRequestMetric, nil
case message.LeafsRequest:
return c.stateTrieLeavesMetric, nil
default:
return nil, fmt.Errorf("attempted to get metric for invalid request with type %T", msg)
}
}
// no-op implementation of ClientSyncerStats
type noopStats struct {
noop noopMsgMetric
}
type noopMsgMetric struct{}
func (noopMsgMetric) IncRequested() {}
func (noopMsgMetric) IncSucceeded() {}
func (noopMsgMetric) IncFailed() {}
func (noopMsgMetric) IncInvalidResponse() {}
func (noopMsgMetric) IncReceived(int64) {}
func (noopMsgMetric) UpdateRequestLatency(time.Duration) {}
func NewNoOpStats() ClientSyncerStats {
return &noopStats{}
}
func (n noopStats) GetMetric(_ message.Request) (MessageMetric, error) {
return n.noop, nil
}
// NewStats returns syncer stats if enabled or a no-op version if disabled.
func NewStats(enabled bool) ClientSyncerStats {
if enabled {
return NewClientSyncerStats()
} else {
return NewNoOpStats()
}
}