Skip to content

Commit 48c0492

Browse files
committed
chore(callstack): Better expvar insights for stackwalk decorator
1 parent 56b83a0 commit 48c0492

File tree

3 files changed

+37
-9
lines changed

3 files changed

+37
-9
lines changed

cmd/fibratus/app/stats/stats.go

+4
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,10 @@ type Stats struct {
108108
RegistryKcbMisses int `json:"registry.kcb.misses"`
109109
RegistryKeyHandleHits int `json:"registry.key.handle.hits"`
110110
RegistryUnknownKeysCount int `json:"registry.unknown.keys.count"`
111+
StackwalkEnqueued int `json:"stackwalk.enqueued"`
112+
StackwalkFlushes int `json:"stackwalk.flushes"`
113+
StackwalkFlushesProcs map[string]int `json:"stackwalk.flushes.procs"`
114+
StackwalkFlushesEvents map[string]int `json:"stackwalk.flushes.events"`
111115
YaraImageScans int `json:"yara.image.scans"`
112116
YaraProcScans int `json:"yara.proc.scans"`
113117
YaraRuleMatches int `json:"yara.rule.matches"`

pkg/kevent/stackwalk.go

+32-8
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,27 @@ import (
2727
"time"
2828
)
2929

30-
// maxDequeFlushPeriod specifies the maximum period
30+
// maxQueueTTLPeriod specifies the maximum period
3131
// for the events to reside in the queue.
32-
var maxDequeFlushPeriod = time.Second * 30
32+
var maxQueueTTLPeriod = time.Second * 10
3333

3434
// flusherInterval specifies the interval for the queue flushing.
3535
var flusherInterval = time.Second * 5
3636

37-
// callstackFlushes computes overall callstack dequeue flushes
38-
var callstackFlushes = expvar.NewInt("callstack.flushes")
37+
// stackwalkFlushes computes overall flushes for unmatched stackwalk events
38+
var stackwalkFlushes = expvar.NewInt("stackwalk.flushes")
39+
40+
// stackwalkFlushesProcs computes overall flushes for unmatched stackwalk events per process
41+
var stackwalkFlushesProcs = expvar.NewMap("stackwalk.flushes.procs")
42+
43+
// stackwalkFlushesEvents computes overall flushes for unmatched stackwalks per event type
44+
var stackwalkFlushesEvents = expvar.NewMap("stackwalk.flushes.events")
45+
46+
// stackwalkEnqueued counts the number of enqueued events in individual buckets
47+
var stackwalkEnqueued = expvar.NewInt("stackwalk.enqueued")
48+
49+
// stackwalkBuckets counts the number of overall stackwalk buckets per stack id
50+
var stackwalkBuckets = expvar.NewInt("stackwalk.buckets")
3951

4052
// StackwalkDecorator maintains a FIFO queue where events
4153
// eligible for stack enrichment are queued. Upon arrival
@@ -80,6 +92,9 @@ func (s *StackwalkDecorator) Push(e *Kevent) {
8092
} else {
8193
s.buckets[id] = append(q, e)
8294
}
95+
96+
stackwalkBuckets.Set(int64(len(s.buckets)))
97+
stackwalkEnqueued.Add(int64(len(s.buckets[id])))
8398
}
8499

85100
// Pop receives the stack walk event and pops the oldest
@@ -99,6 +114,7 @@ func (s *StackwalkDecorator) Pop(e *Kevent) *Kevent {
99114
var evt *Kevent
100115
if len(q) > 0 {
101116
evt, s.buckets[id] = q[0], q[1:]
117+
stackwalkEnqueued.Add(-int64(len(s.buckets[id])))
102118
}
103119

104120
if evt == nil {
@@ -121,6 +137,7 @@ func (s *StackwalkDecorator) RemoveBucket(id uint64) {
121137
s.mux.Lock()
122138
defer s.mux.Unlock()
123139
delete(s.buckets, id)
140+
stackwalkBuckets.Set(int64(len(s.buckets)))
124141
}
125142

126143
func (s *StackwalkDecorator) doFlush() {
@@ -138,8 +155,8 @@ func (s *StackwalkDecorator) doFlush() {
138155
}
139156

140157
// flush pushes events to the event queue if they have
141-
// been living in the deque more than the maximum allowed
142-
// flush period.
158+
// been living in the queue more than the maximum allowed
159+
// TTL period.
143160
func (s *StackwalkDecorator) flush() []error {
144161
s.mux.Lock()
145162
defer s.mux.Unlock()
@@ -152,15 +169,22 @@ func (s *StackwalkDecorator) flush() []error {
152169

153170
for id, q := range s.buckets {
154171
for i, evt := range q {
155-
if time.Since(evt.Timestamp) < maxDequeFlushPeriod {
172+
if time.Since(evt.Timestamp) < maxQueueTTLPeriod {
156173
continue
157174
}
158-
callstackFlushes.Add(1)
175+
stackwalkFlushes.Add(1)
159176
err := s.q.push(evt)
160177
if err != nil {
161178
errs = append(errs, err)
162179
}
163180
s.buckets[id] = append(q[:i], q[i+1:]...)
181+
if stackwalkEnqueued.Value() > 0 {
182+
stackwalkEnqueued.Add(-1)
183+
}
184+
if evt.PS != nil {
185+
stackwalkFlushesProcs.Add(evt.PS.Name, 1)
186+
}
187+
stackwalkFlushesEvents.Add(evt.Name, 1)
164188
}
165189
}
166190

pkg/kevent/stackwalk_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ func TestStackwalkDecorator(t *testing.T) {
9292
}
9393

9494
func init() {
95-
maxDequeFlushPeriod = time.Second * 2
95+
maxQueueTTLPeriod = time.Second * 2
9696
flusherInterval = time.Second
9797
}
9898

0 commit comments

Comments
 (0)