77 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Go
		
	
	
			
		
		
	
	
			77 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Go
		
	
	
package metrics
 | 
						|
 | 
						|
import (
 | 
						|
	"runtime/debug"
 | 
						|
	"time"
 | 
						|
)
 | 
						|
 | 
						|
var (
 | 
						|
	debugMetrics struct {
 | 
						|
		GCStats struct {
 | 
						|
			LastGC Gauge
 | 
						|
			NumGC  Gauge
 | 
						|
			Pause  Histogram
 | 
						|
			//PauseQuantiles Histogram
 | 
						|
			PauseTotal Gauge
 | 
						|
		}
 | 
						|
		ReadGCStats Timer
 | 
						|
	}
 | 
						|
	gcStats debug.GCStats
 | 
						|
)
 | 
						|
 | 
						|
// Capture 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)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// 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))
 | 
						|
}
 | 
						|
 | 
						|
// Register 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) {
 | 
						|
	debugMetrics.GCStats.LastGC = NewGauge()
 | 
						|
	debugMetrics.GCStats.NumGC = NewGauge()
 | 
						|
	debugMetrics.GCStats.Pause = NewHistogram(NewExpDecaySample(1028, 0.015))
 | 
						|
	//debugMetrics.GCStats.PauseQuantiles = 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.PauseQuantiles", debugMetrics.GCStats.PauseQuantiles)
 | 
						|
	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)
 | 
						|
}
 |