-
Notifications
You must be signed in to change notification settings - Fork 0
/
debug.go
82 lines (74 loc) · 2.63 KB
/
debug.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
package metrics
import (
"runtime/debug"
"sync"
"time"
)
var (
debugMetrics struct {
GCStats struct {
LastGC Gauge
NumGC Gauge
Pause Histogram
//PauseQuantiles Histogram
PauseTotal Gauge
}
ReadGCStats Timer
}
gcStats debug.GCStats
registerDebugMetricsOnce = sync.Once{}
)
// CaptureDebugGCStats captures new values for the Go garbage collector
// statistics exported in debug.GCStats. This is designed to be called as a
// goroutine.
func CaptureDebugGCStats(r Registry, d time.Duration) {
for range time.Tick(d) {
CaptureDebugGCStatsOnce(r)
}
}
// CaptureDebugGCStatsOnce capture new values for the Go garbage collector
// statistics exported in debug.GCStats. This is designed to be called in a
// background goroutine. Giving a registry which has not been given to
// RegisterDebugGCStats will panic.
//
// Be careful (but much less so) with this because debug.ReadGCStats calls
// the C function runtime·lock(runtime·mheap) which, while not a stop-the-world
// operation, isn't something you want to be doing all the time.
func CaptureDebugGCStatsOnce(r Registry) {
lastGC := gcStats.LastGC
t := time.Now()
debug.ReadGCStats(&gcStats)
debugMetrics.ReadGCStats.UpdateSince(t)
debugMetrics.GCStats.LastGC.Update(int64(gcStats.LastGC.UnixNano()))
debugMetrics.GCStats.NumGC.Update(int64(gcStats.NumGC))
if lastGC != gcStats.LastGC && 0 < len(gcStats.Pause) {
debugMetrics.GCStats.Pause.Update(int64(gcStats.Pause[0]))
}
//debugMetrics.GCStats.PauseQuantiles.Update(gcStats.PauseQuantiles)
debugMetrics.GCStats.PauseTotal.Update(int64(gcStats.PauseTotal))
}
// RegisterDebugGCStats registers metrics for the Go garbage collector statistics
// exported in debug.GCStats. The metrics are named by their fully-qualified Go
// symbols, i.e. debug.GCStats.PauseTotal.
func RegisterDebugGCStats(r Registry) {
if r == nil {
r = DefaultRegistry
}
registerDebugMetricsOnce.Do(func() {
debugMetrics.GCStats.LastGC = NewGauge()
debugMetrics.GCStats.NumGC = NewGauge()
debugMetrics.GCStats.Pause = NewHistogram(NewExpDecaySample(1028, 0.015))
debugMetrics.GCStats.PauseTotal = NewGauge()
debugMetrics.ReadGCStats = NewTimer()
r.Register("debug.GCStats.LastGC", debugMetrics.GCStats.LastGC)
r.Register("debug.GCStats.NumGC", debugMetrics.GCStats.NumGC)
r.Register("debug.GCStats.Pause", debugMetrics.GCStats.Pause)
r.Register("debug.GCStats.PauseTotal", debugMetrics.GCStats.PauseTotal)
r.Register("debug.ReadGCStats", debugMetrics.ReadGCStats)
})
}
// Allocate an initial slice for gcStats.Pause to avoid allocations during
// normal operation.
func init() {
gcStats.Pause = make([]time.Duration, 11)
}