github.com/ethereum/go-ethereum@v1.16.1/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  // CaptureDebugGCStats captures new values for the Go garbage collector statistics
    23  // exported in 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  // CaptureDebugGCStatsOnce captures new values for the Go garbage collector
    31  // statistics exported in debug.GCStats. This is designed to be called in
    32  // a background goroutine. Giving a registry which has not been given to
    33  // RegisterDebugGCStats will 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  // RegisterDebugGCStats registers metrics for the Go garbage collector statistics
    54  // exported in debug.GCStats. The metrics are named by their fully-qualified Go
    55  // symbols, 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  }