* go-metrics: fork library and introduce ResettingTimer and InfluxDB reporter. * vendor: change nonsense/go-metrics to ethersphere/go-metrics * go-metrics: add tests. move ResettingTimer logic from reporter to type. * all, metrics: pull in metrics package in go-ethereum * metrics/test: make sure metrics are enabled for tests * metrics: apply gosimple rules * metrics/exp, internal/debug: init expvar endpoint when starting pprof server * internal/debug: tiny comment formatting fix
		
			
				
	
	
		
			213 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			213 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package metrics
 | |
| 
 | |
| import (
 | |
| 	"runtime"
 | |
| 	"runtime/pprof"
 | |
| 	"time"
 | |
| )
 | |
| 
 | |
| var (
 | |
| 	memStats       runtime.MemStats
 | |
| 	runtimeMetrics struct {
 | |
| 		MemStats struct {
 | |
| 			Alloc         Gauge
 | |
| 			BuckHashSys   Gauge
 | |
| 			DebugGC       Gauge
 | |
| 			EnableGC      Gauge
 | |
| 			Frees         Gauge
 | |
| 			HeapAlloc     Gauge
 | |
| 			HeapIdle      Gauge
 | |
| 			HeapInuse     Gauge
 | |
| 			HeapObjects   Gauge
 | |
| 			HeapReleased  Gauge
 | |
| 			HeapSys       Gauge
 | |
| 			LastGC        Gauge
 | |
| 			Lookups       Gauge
 | |
| 			Mallocs       Gauge
 | |
| 			MCacheInuse   Gauge
 | |
| 			MCacheSys     Gauge
 | |
| 			MSpanInuse    Gauge
 | |
| 			MSpanSys      Gauge
 | |
| 			NextGC        Gauge
 | |
| 			NumGC         Gauge
 | |
| 			GCCPUFraction GaugeFloat64
 | |
| 			PauseNs       Histogram
 | |
| 			PauseTotalNs  Gauge
 | |
| 			StackInuse    Gauge
 | |
| 			StackSys      Gauge
 | |
| 			Sys           Gauge
 | |
| 			TotalAlloc    Gauge
 | |
| 		}
 | |
| 		NumCgoCall   Gauge
 | |
| 		NumGoroutine Gauge
 | |
| 		NumThread    Gauge
 | |
| 		ReadMemStats Timer
 | |
| 	}
 | |
| 	frees       uint64
 | |
| 	lookups     uint64
 | |
| 	mallocs     uint64
 | |
| 	numGC       uint32
 | |
| 	numCgoCalls int64
 | |
| 
 | |
| 	threadCreateProfile = pprof.Lookup("threadcreate")
 | |
| )
 | |
| 
 | |
| // Capture new values for the Go runtime statistics exported in
 | |
| // runtime.MemStats.  This is designed to be called as a goroutine.
 | |
| func CaptureRuntimeMemStats(r Registry, d time.Duration) {
 | |
| 	for range time.Tick(d) {
 | |
| 		CaptureRuntimeMemStatsOnce(r)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // Capture new values for the Go runtime statistics exported in
 | |
| // runtime.MemStats.  This is designed to be called in a background
 | |
| // goroutine.  Giving a registry which has not been given to
 | |
| // RegisterRuntimeMemStats will panic.
 | |
| //
 | |
| // Be very careful with this because runtime.ReadMemStats calls the C
 | |
| // functions runtime·semacquire(&runtime·worldsema) and runtime·stoptheworld()
 | |
| // and that last one does what it says on the tin.
 | |
| func CaptureRuntimeMemStatsOnce(r Registry) {
 | |
| 	t := time.Now()
 | |
| 	runtime.ReadMemStats(&memStats) // This takes 50-200us.
 | |
| 	runtimeMetrics.ReadMemStats.UpdateSince(t)
 | |
| 
 | |
| 	runtimeMetrics.MemStats.Alloc.Update(int64(memStats.Alloc))
 | |
| 	runtimeMetrics.MemStats.BuckHashSys.Update(int64(memStats.BuckHashSys))
 | |
| 	if memStats.DebugGC {
 | |
| 		runtimeMetrics.MemStats.DebugGC.Update(1)
 | |
| 	} else {
 | |
| 		runtimeMetrics.MemStats.DebugGC.Update(0)
 | |
| 	}
 | |
| 	if memStats.EnableGC {
 | |
| 		runtimeMetrics.MemStats.EnableGC.Update(1)
 | |
| 	} else {
 | |
| 		runtimeMetrics.MemStats.EnableGC.Update(0)
 | |
| 	}
 | |
| 
 | |
| 	runtimeMetrics.MemStats.Frees.Update(int64(memStats.Frees - frees))
 | |
| 	runtimeMetrics.MemStats.HeapAlloc.Update(int64(memStats.HeapAlloc))
 | |
| 	runtimeMetrics.MemStats.HeapIdle.Update(int64(memStats.HeapIdle))
 | |
| 	runtimeMetrics.MemStats.HeapInuse.Update(int64(memStats.HeapInuse))
 | |
| 	runtimeMetrics.MemStats.HeapObjects.Update(int64(memStats.HeapObjects))
 | |
| 	runtimeMetrics.MemStats.HeapReleased.Update(int64(memStats.HeapReleased))
 | |
| 	runtimeMetrics.MemStats.HeapSys.Update(int64(memStats.HeapSys))
 | |
| 	runtimeMetrics.MemStats.LastGC.Update(int64(memStats.LastGC))
 | |
| 	runtimeMetrics.MemStats.Lookups.Update(int64(memStats.Lookups - lookups))
 | |
| 	runtimeMetrics.MemStats.Mallocs.Update(int64(memStats.Mallocs - mallocs))
 | |
| 	runtimeMetrics.MemStats.MCacheInuse.Update(int64(memStats.MCacheInuse))
 | |
| 	runtimeMetrics.MemStats.MCacheSys.Update(int64(memStats.MCacheSys))
 | |
| 	runtimeMetrics.MemStats.MSpanInuse.Update(int64(memStats.MSpanInuse))
 | |
| 	runtimeMetrics.MemStats.MSpanSys.Update(int64(memStats.MSpanSys))
 | |
| 	runtimeMetrics.MemStats.NextGC.Update(int64(memStats.NextGC))
 | |
| 	runtimeMetrics.MemStats.NumGC.Update(int64(memStats.NumGC - numGC))
 | |
| 	runtimeMetrics.MemStats.GCCPUFraction.Update(gcCPUFraction(&memStats))
 | |
| 
 | |
| 	// <https://code.google.com/p/go/source/browse/src/pkg/runtime/mgc0.c>
 | |
| 	i := numGC % uint32(len(memStats.PauseNs))
 | |
| 	ii := memStats.NumGC % uint32(len(memStats.PauseNs))
 | |
| 	if memStats.NumGC-numGC >= uint32(len(memStats.PauseNs)) {
 | |
| 		for i = 0; i < uint32(len(memStats.PauseNs)); i++ {
 | |
| 			runtimeMetrics.MemStats.PauseNs.Update(int64(memStats.PauseNs[i]))
 | |
| 		}
 | |
| 	} else {
 | |
| 		if i > ii {
 | |
| 			for ; i < uint32(len(memStats.PauseNs)); i++ {
 | |
| 				runtimeMetrics.MemStats.PauseNs.Update(int64(memStats.PauseNs[i]))
 | |
| 			}
 | |
| 			i = 0
 | |
| 		}
 | |
| 		for ; i < ii; i++ {
 | |
| 			runtimeMetrics.MemStats.PauseNs.Update(int64(memStats.PauseNs[i]))
 | |
| 		}
 | |
| 	}
 | |
| 	frees = memStats.Frees
 | |
| 	lookups = memStats.Lookups
 | |
| 	mallocs = memStats.Mallocs
 | |
| 	numGC = memStats.NumGC
 | |
| 
 | |
| 	runtimeMetrics.MemStats.PauseTotalNs.Update(int64(memStats.PauseTotalNs))
 | |
| 	runtimeMetrics.MemStats.StackInuse.Update(int64(memStats.StackInuse))
 | |
| 	runtimeMetrics.MemStats.StackSys.Update(int64(memStats.StackSys))
 | |
| 	runtimeMetrics.MemStats.Sys.Update(int64(memStats.Sys))
 | |
| 	runtimeMetrics.MemStats.TotalAlloc.Update(int64(memStats.TotalAlloc))
 | |
| 
 | |
| 	currentNumCgoCalls := numCgoCall()
 | |
| 	runtimeMetrics.NumCgoCall.Update(currentNumCgoCalls - numCgoCalls)
 | |
| 	numCgoCalls = currentNumCgoCalls
 | |
| 
 | |
| 	runtimeMetrics.NumGoroutine.Update(int64(runtime.NumGoroutine()))
 | |
| 
 | |
| 	runtimeMetrics.NumThread.Update(int64(threadCreateProfile.Count()))
 | |
| }
 | |
| 
 | |
| // Register runtimeMetrics for the Go runtime statistics exported in runtime and
 | |
| // specifically runtime.MemStats.  The runtimeMetrics are named by their
 | |
| // fully-qualified Go symbols, i.e. runtime.MemStats.Alloc.
 | |
| func RegisterRuntimeMemStats(r Registry) {
 | |
| 	runtimeMetrics.MemStats.Alloc = NewGauge()
 | |
| 	runtimeMetrics.MemStats.BuckHashSys = NewGauge()
 | |
| 	runtimeMetrics.MemStats.DebugGC = NewGauge()
 | |
| 	runtimeMetrics.MemStats.EnableGC = NewGauge()
 | |
| 	runtimeMetrics.MemStats.Frees = NewGauge()
 | |
| 	runtimeMetrics.MemStats.HeapAlloc = NewGauge()
 | |
| 	runtimeMetrics.MemStats.HeapIdle = NewGauge()
 | |
| 	runtimeMetrics.MemStats.HeapInuse = NewGauge()
 | |
| 	runtimeMetrics.MemStats.HeapObjects = NewGauge()
 | |
| 	runtimeMetrics.MemStats.HeapReleased = NewGauge()
 | |
| 	runtimeMetrics.MemStats.HeapSys = NewGauge()
 | |
| 	runtimeMetrics.MemStats.LastGC = NewGauge()
 | |
| 	runtimeMetrics.MemStats.Lookups = NewGauge()
 | |
| 	runtimeMetrics.MemStats.Mallocs = NewGauge()
 | |
| 	runtimeMetrics.MemStats.MCacheInuse = NewGauge()
 | |
| 	runtimeMetrics.MemStats.MCacheSys = NewGauge()
 | |
| 	runtimeMetrics.MemStats.MSpanInuse = NewGauge()
 | |
| 	runtimeMetrics.MemStats.MSpanSys = NewGauge()
 | |
| 	runtimeMetrics.MemStats.NextGC = NewGauge()
 | |
| 	runtimeMetrics.MemStats.NumGC = NewGauge()
 | |
| 	runtimeMetrics.MemStats.GCCPUFraction = NewGaugeFloat64()
 | |
| 	runtimeMetrics.MemStats.PauseNs = NewHistogram(NewExpDecaySample(1028, 0.015))
 | |
| 	runtimeMetrics.MemStats.PauseTotalNs = NewGauge()
 | |
| 	runtimeMetrics.MemStats.StackInuse = NewGauge()
 | |
| 	runtimeMetrics.MemStats.StackSys = NewGauge()
 | |
| 	runtimeMetrics.MemStats.Sys = NewGauge()
 | |
| 	runtimeMetrics.MemStats.TotalAlloc = NewGauge()
 | |
| 	runtimeMetrics.NumCgoCall = NewGauge()
 | |
| 	runtimeMetrics.NumGoroutine = NewGauge()
 | |
| 	runtimeMetrics.NumThread = NewGauge()
 | |
| 	runtimeMetrics.ReadMemStats = NewTimer()
 | |
| 
 | |
| 	r.Register("runtime.MemStats.Alloc", runtimeMetrics.MemStats.Alloc)
 | |
| 	r.Register("runtime.MemStats.BuckHashSys", runtimeMetrics.MemStats.BuckHashSys)
 | |
| 	r.Register("runtime.MemStats.DebugGC", runtimeMetrics.MemStats.DebugGC)
 | |
| 	r.Register("runtime.MemStats.EnableGC", runtimeMetrics.MemStats.EnableGC)
 | |
| 	r.Register("runtime.MemStats.Frees", runtimeMetrics.MemStats.Frees)
 | |
| 	r.Register("runtime.MemStats.HeapAlloc", runtimeMetrics.MemStats.HeapAlloc)
 | |
| 	r.Register("runtime.MemStats.HeapIdle", runtimeMetrics.MemStats.HeapIdle)
 | |
| 	r.Register("runtime.MemStats.HeapInuse", runtimeMetrics.MemStats.HeapInuse)
 | |
| 	r.Register("runtime.MemStats.HeapObjects", runtimeMetrics.MemStats.HeapObjects)
 | |
| 	r.Register("runtime.MemStats.HeapReleased", runtimeMetrics.MemStats.HeapReleased)
 | |
| 	r.Register("runtime.MemStats.HeapSys", runtimeMetrics.MemStats.HeapSys)
 | |
| 	r.Register("runtime.MemStats.LastGC", runtimeMetrics.MemStats.LastGC)
 | |
| 	r.Register("runtime.MemStats.Lookups", runtimeMetrics.MemStats.Lookups)
 | |
| 	r.Register("runtime.MemStats.Mallocs", runtimeMetrics.MemStats.Mallocs)
 | |
| 	r.Register("runtime.MemStats.MCacheInuse", runtimeMetrics.MemStats.MCacheInuse)
 | |
| 	r.Register("runtime.MemStats.MCacheSys", runtimeMetrics.MemStats.MCacheSys)
 | |
| 	r.Register("runtime.MemStats.MSpanInuse", runtimeMetrics.MemStats.MSpanInuse)
 | |
| 	r.Register("runtime.MemStats.MSpanSys", runtimeMetrics.MemStats.MSpanSys)
 | |
| 	r.Register("runtime.MemStats.NextGC", runtimeMetrics.MemStats.NextGC)
 | |
| 	r.Register("runtime.MemStats.NumGC", runtimeMetrics.MemStats.NumGC)
 | |
| 	r.Register("runtime.MemStats.GCCPUFraction", runtimeMetrics.MemStats.GCCPUFraction)
 | |
| 	r.Register("runtime.MemStats.PauseNs", runtimeMetrics.MemStats.PauseNs)
 | |
| 	r.Register("runtime.MemStats.PauseTotalNs", runtimeMetrics.MemStats.PauseTotalNs)
 | |
| 	r.Register("runtime.MemStats.StackInuse", runtimeMetrics.MemStats.StackInuse)
 | |
| 	r.Register("runtime.MemStats.StackSys", runtimeMetrics.MemStats.StackSys)
 | |
| 	r.Register("runtime.MemStats.Sys", runtimeMetrics.MemStats.Sys)
 | |
| 	r.Register("runtime.MemStats.TotalAlloc", runtimeMetrics.MemStats.TotalAlloc)
 | |
| 	r.Register("runtime.NumCgoCall", runtimeMetrics.NumCgoCall)
 | |
| 	r.Register("runtime.NumGoroutine", runtimeMetrics.NumGoroutine)
 | |
| 	r.Register("runtime.NumThread", runtimeMetrics.NumThread)
 | |
| 	r.Register("runtime.ReadMemStats", runtimeMetrics.ReadMemStats)
 | |
| }
 |