github.com/dominant-strategies/go-quai@v0.28.2/metrics/debug.go (about) 1 package metrics 2 3 import ( 4 "runtime/debug" 5 "time" 6 ) 7 8 var ( 9 debugMetrics struct { 10 GCStats struct { 11 LastGC Gauge 12 NumGC Gauge 13 Pause Histogram 14 //PauseQuantiles Histogram 15 PauseTotal Gauge 16 } 17 ReadGCStats Timer 18 } 19 gcStats debug.GCStats 20 ) 21 22 // Capture new values for the Go garbage collector statistics exported in 23 // debug.GCStats. This is designed to be called as a goroutine. 24 func CaptureDebugGCStats(r Registry, d time.Duration) { 25 for range time.Tick(d) { 26 CaptureDebugGCStatsOnce(r) 27 } 28 } 29 30 // Capture new values for the Go garbage collector statistics exported in 31 // debug.GCStats. This is designed to be called in a background goroutine. 32 // Giving a registry which has not been given to RegisterDebugGCStats will 33 // panic. 34 // 35 // Be careful (but much less so) with this because debug.ReadGCStats calls 36 // the C function runtime·lock(runtime·mheap) which, while not a stop-the-world 37 // operation, isn't something you want to be doing all the time. 38 func CaptureDebugGCStatsOnce(r Registry) { 39 lastGC := gcStats.LastGC 40 t := time.Now() 41 debug.ReadGCStats(&gcStats) 42 debugMetrics.ReadGCStats.UpdateSince(t) 43 44 debugMetrics.GCStats.LastGC.Update(gcStats.LastGC.UnixNano()) 45 debugMetrics.GCStats.NumGC.Update(gcStats.NumGC) 46 if lastGC != gcStats.LastGC && 0 < len(gcStats.Pause) { 47 debugMetrics.GCStats.Pause.Update(int64(gcStats.Pause[0])) 48 } 49 //debugMetrics.GCStats.PauseQuantiles.Update(gcStats.PauseQuantiles) 50 debugMetrics.GCStats.PauseTotal.Update(int64(gcStats.PauseTotal)) 51 } 52 53 // Register metrics for the Go garbage collector statistics exported in 54 // debug.GCStats. The metrics are named by their fully-qualified Go symbols, 55 // i.e. debug.GCStats.PauseTotal. 56 func RegisterDebugGCStats(r Registry) { 57 debugMetrics.GCStats.LastGC = NewGauge() 58 debugMetrics.GCStats.NumGC = NewGauge() 59 debugMetrics.GCStats.Pause = NewHistogram(NewExpDecaySample(1028, 0.015)) 60 //debugMetrics.GCStats.PauseQuantiles = NewHistogram(NewExpDecaySample(1028, 0.015)) 61 debugMetrics.GCStats.PauseTotal = NewGauge() 62 debugMetrics.ReadGCStats = NewTimer() 63 64 r.Register("debug.GCStats.LastGC", debugMetrics.GCStats.LastGC) 65 r.Register("debug.GCStats.NumGC", debugMetrics.GCStats.NumGC) 66 r.Register("debug.GCStats.Pause", debugMetrics.GCStats.Pause) 67 //r.Register("debug.GCStats.PauseQuantiles", debugMetrics.GCStats.PauseQuantiles) 68 r.Register("debug.GCStats.PauseTotal", debugMetrics.GCStats.PauseTotal) 69 r.Register("debug.ReadGCStats", debugMetrics.ReadGCStats) 70 } 71 72 // Allocate an initial slice for gcStats.Pause to avoid allocations during 73 // normal operation. 74 func init() { 75 gcStats.Pause = make([]time.Duration, 11) 76 }