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