github.com/sunblockterminal/go-sunblocktediuma@v0.0.0-20210616083421-160a35ed7cfa/metrics/runtime.go (about) 1 package metrics 2 3 import ( 4 "runtime" 5 "runtime/pprof" 6 "time" 7 ) 8 9 var ( 10 memStats runtime.MemStats 11 runtimeMetrics struct { 12 MemStats struct { 13 Alloc Gauge 14 BuckHashSys Gauge 15 DebugGC Gauge 16 EnableGC Gauge 17 Frees Gauge 18 HeapAlloc Gauge 19 HeapIdle Gauge 20 HeapInuse Gauge 21 HeapObjects Gauge 22 HeapReleased Gauge 23 HeapSys Gauge 24 LastGC Gauge 25 Lookups Gauge 26 Mallocs Gauge 27 MCacheInuse Gauge 28 MCacheSys Gauge 29 MSpanInuse Gauge 30 MSpanSys Gauge 31 NextGC Gauge 32 NumGC Gauge 33 GCCPUFraction GaugeFloat64 34 PauseNs Histogram 35 PauseTotalNs Gauge 36 StackInuse Gauge 37 StackSys Gauge 38 Sys Gauge 39 TotalAlloc Gauge 40 } 41 NumCgoCall Gauge 42 NumGoroutine Gauge 43 NumThread Gauge 44 ReadMemStats Timer 45 } 46 frees uint64 47 lookups uint64 48 mallocs uint64 49 numGC uint32 50 numCgoCalls int64 51 52 threadCreateProfile = pprof.Lookup("threadcreate") 53 ) 54 55 // Capture new values for the Go runtime statistics exported in 56 // runtime.MemStats. This is designed to be called as a goroutine. 57 func CaptureRuntimeMemStats(r Registry, d time.Duration) { 58 for range time.Tick(d) { 59 CaptureRuntimeMemStatsOnce(r) 60 } 61 } 62 63 // Capture new values for the Go runtime statistics exported in 64 // runtime.MemStats. This is designed to be called in a background 65 // goroutine. Giving a registry which has not been given to 66 // RegisterRuntimeMemStats will panic. 67 // 68 // Be very careful with this because runtime.ReadMemStats calls the C 69 // functions runtime·semacquire(&runtime·worldsema) and runtime·stoptheworld() 70 // and that last one does what it says on the tin. 71 func CaptureRuntimeMemStatsOnce(r Registry) { 72 t := time.Now() 73 runtime.ReadMemStats(&memStats) // This takes 50-200us. 74 runtimeMetrics.ReadMemStats.UpdateSince(t) 75 76 runtimeMetrics.MemStats.Alloc.Update(int64(memStats.Alloc)) 77 runtimeMetrics.MemStats.BuckHashSys.Update(int64(memStats.BuckHashSys)) 78 if memStats.DebugGC { 79 runtimeMetrics.MemStats.DebugGC.Update(1) 80 } else { 81 runtimeMetrics.MemStats.DebugGC.Update(0) 82 } 83 if memStats.EnableGC { 84 runtimeMetrics.MemStats.EnableGC.Update(1) 85 } else { 86 runtimeMetrics.MemStats.EnableGC.Update(0) 87 } 88 89 runtimeMetrics.MemStats.Frees.Update(int64(memStats.Frees - frees)) 90 runtimeMetrics.MemStats.HeapAlloc.Update(int64(memStats.HeapAlloc)) 91 runtimeMetrics.MemStats.HeapIdle.Update(int64(memStats.HeapIdle)) 92 runtimeMetrics.MemStats.HeapInuse.Update(int64(memStats.HeapInuse)) 93 runtimeMetrics.MemStats.HeapObjects.Update(int64(memStats.HeapObjects)) 94 runtimeMetrics.MemStats.HeapReleased.Update(int64(memStats.HeapReleased)) 95 runtimeMetrics.MemStats.HeapSys.Update(int64(memStats.HeapSys)) 96 runtimeMetrics.MemStats.LastGC.Update(int64(memStats.LastGC)) 97 runtimeMetrics.MemStats.Lookups.Update(int64(memStats.Lookups - lookups)) 98 runtimeMetrics.MemStats.Mallocs.Update(int64(memStats.Mallocs - mallocs)) 99 runtimeMetrics.MemStats.MCacheInuse.Update(int64(memStats.MCacheInuse)) 100 runtimeMetrics.MemStats.MCacheSys.Update(int64(memStats.MCacheSys)) 101 runtimeMetrics.MemStats.MSpanInuse.Update(int64(memStats.MSpanInuse)) 102 runtimeMetrics.MemStats.MSpanSys.Update(int64(memStats.MSpanSys)) 103 runtimeMetrics.MemStats.NextGC.Update(int64(memStats.NextGC)) 104 runtimeMetrics.MemStats.NumGC.Update(int64(memStats.NumGC - numGC)) 105 runtimeMetrics.MemStats.GCCPUFraction.Update(gcCPUFraction(&memStats)) 106 107 // <https://code.google.com/p/go/source/browse/src/pkg/runtime/mgc0.c> 108 i := numGC % uint32(len(memStats.PauseNs)) 109 ii := memStats.NumGC % uint32(len(memStats.PauseNs)) 110 if memStats.NumGC-numGC >= uint32(len(memStats.PauseNs)) { 111 for i = 0; i < uint32(len(memStats.PauseNs)); i++ { 112 runtimeMetrics.MemStats.PauseNs.Update(int64(memStats.PauseNs[i])) 113 } 114 } else { 115 if i > ii { 116 for ; i < uint32(len(memStats.PauseNs)); i++ { 117 runtimeMetrics.MemStats.PauseNs.Update(int64(memStats.PauseNs[i])) 118 } 119 i = 0 120 } 121 for ; i < ii; i++ { 122 runtimeMetrics.MemStats.PauseNs.Update(int64(memStats.PauseNs[i])) 123 } 124 } 125 frees = memStats.Frees 126 lookups = memStats.Lookups 127 mallocs = memStats.Mallocs 128 numGC = memStats.NumGC 129 130 runtimeMetrics.MemStats.PauseTotalNs.Update(int64(memStats.PauseTotalNs)) 131 runtimeMetrics.MemStats.StackInuse.Update(int64(memStats.StackInuse)) 132 runtimeMetrics.MemStats.StackSys.Update(int64(memStats.StackSys)) 133 runtimeMetrics.MemStats.Sys.Update(int64(memStats.Sys)) 134 runtimeMetrics.MemStats.TotalAlloc.Update(int64(memStats.TotalAlloc)) 135 136 currentNumCgoCalls := numCgoCall() 137 runtimeMetrics.NumCgoCall.Update(currentNumCgoCalls - numCgoCalls) 138 numCgoCalls = currentNumCgoCalls 139 140 runtimeMetrics.NumGoroutine.Update(int64(runtime.NumGoroutine())) 141 142 runtimeMetrics.NumThread.Update(int64(threadCreateProfile.Count())) 143 } 144 145 // Register runtimeMetrics for the Go runtime statistics exported in runtime and 146 // specifically runtime.MemStats. The runtimeMetrics are named by their 147 // fully-qualified Go symbols, i.e. runtime.MemStats.Alloc. 148 func RegisterRuntimeMemStats(r Registry) { 149 runtimeMetrics.MemStats.Alloc = NewGauge() 150 runtimeMetrics.MemStats.BuckHashSys = NewGauge() 151 runtimeMetrics.MemStats.DebugGC = NewGauge() 152 runtimeMetrics.MemStats.EnableGC = NewGauge() 153 runtimeMetrics.MemStats.Frees = NewGauge() 154 runtimeMetrics.MemStats.HeapAlloc = NewGauge() 155 runtimeMetrics.MemStats.HeapIdle = NewGauge() 156 runtimeMetrics.MemStats.HeapInuse = NewGauge() 157 runtimeMetrics.MemStats.HeapObjects = NewGauge() 158 runtimeMetrics.MemStats.HeapReleased = NewGauge() 159 runtimeMetrics.MemStats.HeapSys = NewGauge() 160 runtimeMetrics.MemStats.LastGC = NewGauge() 161 runtimeMetrics.MemStats.Lookups = NewGauge() 162 runtimeMetrics.MemStats.Mallocs = NewGauge() 163 runtimeMetrics.MemStats.MCacheInuse = NewGauge() 164 runtimeMetrics.MemStats.MCacheSys = NewGauge() 165 runtimeMetrics.MemStats.MSpanInuse = NewGauge() 166 runtimeMetrics.MemStats.MSpanSys = NewGauge() 167 runtimeMetrics.MemStats.NextGC = NewGauge() 168 runtimeMetrics.MemStats.NumGC = NewGauge() 169 runtimeMetrics.MemStats.GCCPUFraction = NewGaugeFloat64() 170 runtimeMetrics.MemStats.PauseNs = NewHistogram(NewExpDecaySample(1028, 0.015)) 171 runtimeMetrics.MemStats.PauseTotalNs = NewGauge() 172 runtimeMetrics.MemStats.StackInuse = NewGauge() 173 runtimeMetrics.MemStats.StackSys = NewGauge() 174 runtimeMetrics.MemStats.Sys = NewGauge() 175 runtimeMetrics.MemStats.TotalAlloc = NewGauge() 176 runtimeMetrics.NumCgoCall = NewGauge() 177 runtimeMetrics.NumGoroutine = NewGauge() 178 runtimeMetrics.NumThread = NewGauge() 179 runtimeMetrics.ReadMemStats = NewTimer() 180 181 r.Register("runtime.MemStats.Alloc", runtimeMetrics.MemStats.Alloc) 182 r.Register("runtime.MemStats.BuckHashSys", runtimeMetrics.MemStats.BuckHashSys) 183 r.Register("runtime.MemStats.DebugGC", runtimeMetrics.MemStats.DebugGC) 184 r.Register("runtime.MemStats.EnableGC", runtimeMetrics.MemStats.EnableGC) 185 r.Register("runtime.MemStats.Frees", runtimeMetrics.MemStats.Frees) 186 r.Register("runtime.MemStats.HeapAlloc", runtimeMetrics.MemStats.HeapAlloc) 187 r.Register("runtime.MemStats.HeapIdle", runtimeMetrics.MemStats.HeapIdle) 188 r.Register("runtime.MemStats.HeapInuse", runtimeMetrics.MemStats.HeapInuse) 189 r.Register("runtime.MemStats.HeapObjects", runtimeMetrics.MemStats.HeapObjects) 190 r.Register("runtime.MemStats.HeapReleased", runtimeMetrics.MemStats.HeapReleased) 191 r.Register("runtime.MemStats.HeapSys", runtimeMetrics.MemStats.HeapSys) 192 r.Register("runtime.MemStats.LastGC", runtimeMetrics.MemStats.LastGC) 193 r.Register("runtime.MemStats.Lookups", runtimeMetrics.MemStats.Lookups) 194 r.Register("runtime.MemStats.Mallocs", runtimeMetrics.MemStats.Mallocs) 195 r.Register("runtime.MemStats.MCacheInuse", runtimeMetrics.MemStats.MCacheInuse) 196 r.Register("runtime.MemStats.MCacheSys", runtimeMetrics.MemStats.MCacheSys) 197 r.Register("runtime.MemStats.MSpanInuse", runtimeMetrics.MemStats.MSpanInuse) 198 r.Register("runtime.MemStats.MSpanSys", runtimeMetrics.MemStats.MSpanSys) 199 r.Register("runtime.MemStats.NextGC", runtimeMetrics.MemStats.NextGC) 200 r.Register("runtime.MemStats.NumGC", runtimeMetrics.MemStats.NumGC) 201 r.Register("runtime.MemStats.GCCPUFraction", runtimeMetrics.MemStats.GCCPUFraction) 202 r.Register("runtime.MemStats.PauseNs", runtimeMetrics.MemStats.PauseNs) 203 r.Register("runtime.MemStats.PauseTotalNs", runtimeMetrics.MemStats.PauseTotalNs) 204 r.Register("runtime.MemStats.StackInuse", runtimeMetrics.MemStats.StackInuse) 205 r.Register("runtime.MemStats.StackSys", runtimeMetrics.MemStats.StackSys) 206 r.Register("runtime.MemStats.Sys", runtimeMetrics.MemStats.Sys) 207 r.Register("runtime.MemStats.TotalAlloc", runtimeMetrics.MemStats.TotalAlloc) 208 r.Register("runtime.NumCgoCall", runtimeMetrics.NumCgoCall) 209 r.Register("runtime.NumGoroutine", runtimeMetrics.NumGoroutine) 210 r.Register("runtime.NumThread", runtimeMetrics.NumThread) 211 r.Register("runtime.ReadMemStats", runtimeMetrics.ReadMemStats) 212 }