github.com/wfusion/gofusion@v1.1.14/routine/metrics.go (about) 1 package routine 2 3 import ( 4 "context" 5 "log" 6 "runtime" 7 "syscall" 8 "time" 9 10 "go.uber.org/atomic" 11 12 "github.com/wfusion/gofusion/common/utils" 13 "github.com/wfusion/gofusion/config" 14 "github.com/wfusion/gofusion/metrics" 15 ) 16 17 var ( 18 metricsRuntimeCpuGoroutinesKey = []string{"runtime", "cpu", "goroutines"} 19 metricsRuntimeCpuCgoCallsKey = []string{"runtime", "cpu", "cgo_calls"} 20 metricsRuntimeFusGoroutinesKey = []string{"runtime", "fus", "goroutines"} 21 22 metricsRuntimeMemAllocKey = []string{"runtime", "mem", "alloc"} 23 metricsRuntimeMemTotalKey = []string{"runtime", "mem", "total"} 24 metricsRuntimeMemSysKey = []string{"runtime", "mem", "sys"} 25 metricsRuntimeMemLookupsKey = []string{"runtime", "mem", "lookups"} 26 metricsRuntimeMemMallocKey = []string{"runtime", "mem", "malloc"} 27 metricsRuntimeMemFreesKey = []string{"runtime", "mem", "frees"} 28 29 metricsRuntimeHeapAllocKey = []string{"runtime", "heap", "alloc"} 30 metricsRuntimeHeapSysKey = []string{"runtime", "heap", "sys"} 31 metricsRuntimeHeapIdleKey = []string{"runtime", "heap", "idle"} 32 metricsRuntimeHeapInuseKey = []string{"runtime", "heap", "inuse"} 33 metricsRuntimeHeapReleasedKey = []string{"runtime", "heap", "released"} 34 metricsRuntimeHeapObjectsKey = []string{"runtime", "heap", "objects"} 35 36 metricsRuntimeStackInuseKey = []string{"runtime", "stack", "inuse"} 37 metricsRuntimeStackSysKey = []string{"runtime", "stack", "sys"} 38 metricsRuntimeMSpanInuseKey = []string{"runtime", "mspan", "inuse"} 39 metricsRuntimeMSpanSysKey = []string{"runtime", "mspan", "sys"} 40 metricsRuntimeMCacheInuseKey = []string{"runtime", "mcache", "inuse"} 41 metricsRuntimeMCacheSysKey = []string{"runtime", "mcache", "sys"} 42 43 metricsRuntimeOtherSysKey = []string{"runtime", "other", "sys"} 44 45 metricsRuntimeGCSysKey = []string{"runtime", "gc", "sys"} 46 metricsRuntimeGCNextKey = []string{"runtime", "gc", "next"} 47 metricsRuntimeGCLastKey = []string{"runtime", "gc", "last"} 48 metricsRuntimeGCCountKey = []string{"runtime", "gc", "count"} 49 metricsRuntimeGCForceCountKey = []string{"runtime", "gc", "force", "count"} 50 metricsRuntimeGCPauseNSKey = []string{"runtime", "gc", "pause_ns"} 51 metricsRuntimeGCPauseTotalKey = []string{"runtime", "gc", "pause_total"} 52 53 metricsRuntimeGCPauseNSBuckets = []float64{ 54 1000, 2500, 5000, 7500, 9000, 9500, 9900, // 1μs - 9.9μs 55 10000, 25000, 50000, 75000, 90000, 95000, 99000, // 0.01ms - 0.099ms 56 100000, 250000, 500000, 750000, 900000, 950000, 990000, // 0.1ms - 0.99ms 57 1000000, 2500000, 5000000, 7500000, 9000000, 9500000, 9900000, // 1ms - 9.9ms 58 10000000, 25000000, 50000000, 75000000, 90000000, 95000000, 99000000, // 10ms - 99ms 59 100000000, 250000000, 500000000, 750000000, 900000000, 950000000, 990000000, // 100ms - 990ms 60 1000000000, 2500000000, 5000000000, 7500000000, 9000000000, 9500000000, 9900000000, // 1s - 9.9s 61 10000000000, 25000000000, 50000000000, 75000000000, 90000000000, 95000000000, 99000000000, // 10s - 99s 62 } 63 ) 64 65 func startDaemonRoutines(ctx context.Context, appName string, conf *Conf) { 66 ticker := time.Tick(time.Second * 5) 67 app := config.Use(appName).AppName() 68 labels := make([]metrics.Label, 0) 69 lastNumGc := atomic.NewUint32(0) 70 71 log.Printf("%v [Gofusion] %s %s metrics start", syscall.Getpid(), app, config.ComponentGoroutinePool) 72 for { 73 select { 74 case <-ctx.Done(): 75 log.Printf("%v [Gofusion] %s %s metrics exited", 76 syscall.Getpid(), app, config.ComponentGoroutinePool) 77 return 78 case <-ticker: 79 go metricsRuntime(ctx, appName, lastNumGc, conf, labels) 80 } 81 } 82 } 83 84 func metricsRuntime(ctx context.Context, appName string, lastNumGc *atomic.Uint32, conf *Conf, labels []metrics.Label) { 85 select { 86 case <-ctx.Done(): 87 return 88 default: 89 } 90 91 _, _ = utils.Catch(func() { 92 var routineNum int64 93 if idles != nil && idles[appName] != nil { 94 routineNum = int64(conf.MaxRoutineAmount) - idles[appName].Load() 95 } 96 97 // export number of Goroutines 98 totalRoutineNum := runtime.NumGoroutine() 99 totalCgoCallsNum := runtime.NumCgoCall() 100 101 // export memory stats 102 var stats runtime.MemStats 103 runtime.ReadMemStats(&stats) 104 105 // export info about the last few GC runs 106 // handle wrap around 107 if stats.NumGC < lastNumGc.Load() { 108 lastNumGc.Store(0) 109 } 110 111 // ensure we don't scan more than 256 112 if stats.NumGC-lastNumGc.Load() >= 256 { 113 lastNumGc.Store(stats.NumGC - 255) 114 } 115 116 app := config.Use(appName).AppName() 117 118 cpuGoRoutinesKey := append([]string{app}, metricsRuntimeCpuGoroutinesKey...) 119 cpuCgoCallsKey := append([]string{app}, metricsRuntimeCpuCgoCallsKey...) 120 fusGoroutineKey := append([]string{app}, metricsRuntimeFusGoroutinesKey...) 121 122 memAllocKey := append([]string{app}, metricsRuntimeMemAllocKey...) 123 memTotalKey := append([]string{app}, metricsRuntimeMemTotalKey...) 124 memSysKey := append([]string{app}, metricsRuntimeMemSysKey...) 125 memLookupsKey := append([]string{app}, metricsRuntimeMemLookupsKey...) 126 memMallocKey := append([]string{app}, metricsRuntimeMemMallocKey...) 127 memFreesKey := append([]string{app}, metricsRuntimeMemFreesKey...) 128 129 heapAllocKey := append([]string{app}, metricsRuntimeHeapAllocKey...) 130 heapSysKey := append([]string{app}, metricsRuntimeHeapSysKey...) 131 heapIdleKey := append([]string{app}, metricsRuntimeHeapIdleKey...) 132 heapInuseKey := append([]string{app}, metricsRuntimeHeapInuseKey...) 133 heapReleasedKey := append([]string{app}, metricsRuntimeHeapReleasedKey...) 134 heapObjectsKey := append([]string{app}, metricsRuntimeHeapObjectsKey...) 135 136 stackInuseKey := append([]string{app}, metricsRuntimeStackInuseKey...) 137 stackSysKey := append([]string{app}, metricsRuntimeStackSysKey...) 138 mspanInuseKey := append([]string{app}, metricsRuntimeMSpanInuseKey...) 139 mspanSysKey := append([]string{app}, metricsRuntimeMSpanSysKey...) 140 mcacheInuseKey := append([]string{app}, metricsRuntimeMCacheInuseKey...) 141 mcacheSysKey := append([]string{app}, metricsRuntimeMCacheSysKey...) 142 143 otherSysKey := append([]string{app}, metricsRuntimeOtherSysKey...) 144 145 gcSysKey := append([]string{app}, metricsRuntimeGCSysKey...) 146 gcNextKey := append([]string{app}, metricsRuntimeGCNextKey...) 147 gcLastKey := append([]string{app}, metricsRuntimeGCLastKey...) 148 gcCountKey := append([]string{app}, metricsRuntimeGCCountKey...) 149 gcForceCountKey := append([]string{app}, metricsRuntimeGCForceCountKey...) 150 gcPauseNSKey := append([]string{app}, metricsRuntimeGCPauseNSKey...) 151 gcPauseTotalKey := append([]string{app}, metricsRuntimeGCPauseTotalKey...) 152 153 metricsLabels := metrics.Labels(labels) 154 for _, m := range metrics.Internal(metrics.AppName(appName)) { 155 select { 156 case <-ctx.Done(): 157 return 158 default: 159 if m.IsEnableServiceLabel() { 160 m.SetGauge(ctx, cpuGoRoutinesKey, float64(totalRoutineNum), metricsLabels) 161 m.SetGauge(ctx, cpuCgoCallsKey, float64(totalCgoCallsNum), metricsLabels) 162 m.SetGauge(ctx, fusGoroutineKey, float64(routineNum), metricsLabels) 163 164 m.SetGauge(ctx, memAllocKey, float64(stats.Alloc), metricsLabels) 165 m.SetGauge(ctx, memTotalKey, float64(stats.TotalAlloc), metricsLabels) 166 m.SetGauge(ctx, memSysKey, float64(stats.Sys), metricsLabels) 167 m.SetGauge(ctx, memLookupsKey, float64(stats.Lookups), metricsLabels) 168 m.SetGauge(ctx, memMallocKey, float64(stats.Mallocs), metricsLabels) 169 m.SetGauge(ctx, memFreesKey, float64(stats.Frees), metricsLabels) 170 171 m.SetGauge(ctx, heapAllocKey, float64(stats.HeapAlloc), metricsLabels) 172 m.SetGauge(ctx, heapSysKey, float64(stats.HeapSys), metricsLabels) 173 m.SetGauge(ctx, heapIdleKey, float64(stats.HeapIdle), metricsLabels) 174 m.SetGauge(ctx, heapInuseKey, float64(stats.HeapInuse), metricsLabels) 175 m.SetGauge(ctx, heapReleasedKey, float64(stats.HeapReleased), metricsLabels) 176 m.SetGauge(ctx, heapObjectsKey, float64(stats.HeapObjects), metricsLabels) 177 178 m.SetGauge(ctx, stackInuseKey, float64(stats.StackInuse), metricsLabels) 179 m.SetGauge(ctx, stackSysKey, float64(stats.StackSys), metricsLabels) 180 m.SetGauge(ctx, mspanInuseKey, float64(stats.MSpanInuse), metricsLabels) 181 m.SetGauge(ctx, mspanSysKey, float64(stats.MSpanSys), metricsLabels) 182 m.SetGauge(ctx, mcacheInuseKey, float64(stats.MCacheInuse), metricsLabels) 183 m.SetGauge(ctx, mcacheSysKey, float64(stats.MCacheSys), metricsLabels) 184 185 m.SetGauge(ctx, otherSysKey, float64(stats.OtherSys), metricsLabels) 186 187 m.SetGauge(ctx, gcSysKey, float64(stats.GCSys), metricsLabels) 188 m.SetGauge(ctx, gcNextKey, float64(stats.NextGC), metricsLabels) 189 m.SetGauge(ctx, gcLastKey, float64(stats.LastGC), metricsLabels) 190 m.SetGauge(ctx, gcCountKey, float64(stats.NumGC), metricsLabels) 191 m.SetGauge(ctx, gcForceCountKey, float64(stats.NumForcedGC), metricsLabels) 192 m.SetGauge(ctx, gcPauseTotalKey, float64(stats.PauseTotalNs), metricsLabels) 193 for i := lastNumGc.Load(); i < stats.NumGC; i++ { 194 m.AddSample(ctx, gcPauseNSKey, float64(stats.PauseNs[i%256]), 195 metricsLabels, metrics.PrometheusBuckets(metricsRuntimeGCPauseNSBuckets)) 196 } 197 } else { 198 m.SetGauge(ctx, metricsRuntimeCpuGoroutinesKey, float64(totalRoutineNum), metricsLabels) 199 m.SetGauge(ctx, metricsRuntimeCpuCgoCallsKey, float64(totalCgoCallsNum), metricsLabels) 200 m.SetGauge(ctx, metricsRuntimeFusGoroutinesKey, float64(routineNum), metricsLabels) 201 202 m.SetGauge(ctx, metricsRuntimeMemAllocKey, float64(stats.Alloc), metricsLabels) 203 m.SetGauge(ctx, metricsRuntimeMemTotalKey, float64(stats.TotalAlloc), metricsLabels) 204 m.SetGauge(ctx, metricsRuntimeMemSysKey, float64(stats.Sys), metricsLabels) 205 m.SetGauge(ctx, metricsRuntimeMemLookupsKey, float64(stats.Lookups), metricsLabels) 206 m.SetGauge(ctx, metricsRuntimeMemMallocKey, float64(stats.Mallocs), metricsLabels) 207 m.SetGauge(ctx, metricsRuntimeMemFreesKey, float64(stats.Frees), metricsLabels) 208 209 m.SetGauge(ctx, metricsRuntimeHeapAllocKey, float64(stats.HeapAlloc), metricsLabels) 210 m.SetGauge(ctx, metricsRuntimeHeapSysKey, float64(stats.HeapSys), metricsLabels) 211 m.SetGauge(ctx, metricsRuntimeHeapIdleKey, float64(stats.HeapIdle), metricsLabels) 212 m.SetGauge(ctx, metricsRuntimeHeapInuseKey, float64(stats.HeapInuse), metricsLabels) 213 m.SetGauge(ctx, metricsRuntimeHeapReleasedKey, float64(stats.HeapReleased), metricsLabels) 214 m.SetGauge(ctx, metricsRuntimeHeapObjectsKey, float64(stats.HeapObjects), metricsLabels) 215 216 m.SetGauge(ctx, metricsRuntimeStackInuseKey, float64(stats.StackInuse), metricsLabels) 217 m.SetGauge(ctx, metricsRuntimeStackSysKey, float64(stats.StackSys), metricsLabels) 218 m.SetGauge(ctx, metricsRuntimeMSpanInuseKey, float64(stats.MSpanInuse), metricsLabels) 219 m.SetGauge(ctx, metricsRuntimeMSpanSysKey, float64(stats.MSpanSys), metricsLabels) 220 m.SetGauge(ctx, metricsRuntimeMCacheInuseKey, float64(stats.MCacheInuse), metricsLabels) 221 m.SetGauge(ctx, metricsRuntimeMCacheSysKey, float64(stats.MCacheSys), metricsLabels) 222 223 m.SetGauge(ctx, metricsRuntimeOtherSysKey, float64(stats.OtherSys), metricsLabels) 224 225 m.SetGauge(ctx, metricsRuntimeGCSysKey, float64(stats.GCSys), metricsLabels) 226 m.SetGauge(ctx, metricsRuntimeGCNextKey, float64(stats.NextGC), metricsLabels) 227 m.SetGauge(ctx, metricsRuntimeGCLastKey, float64(stats.LastGC), metricsLabels) 228 m.SetGauge(ctx, metricsRuntimeGCCountKey, float64(stats.NumGC), metricsLabels) 229 m.SetGauge(ctx, metricsRuntimeGCForceCountKey, float64(stats.NumForcedGC), metricsLabels) 230 m.SetGauge(ctx, metricsRuntimeGCPauseTotalKey, float64(stats.PauseTotalNs), metricsLabels) 231 for i := lastNumGc.Load(); i < stats.NumGC; i++ { 232 m.AddSample(ctx, metricsRuntimeGCPauseNSKey, float64(stats.PauseNs[i%256]), 233 metricsLabels, 234 metrics.PrometheusBuckets(metricsRuntimeGCPauseNSBuckets), 235 ) 236 } 237 } 238 } 239 } 240 241 lastNumGc.Store(stats.NumGC) 242 }) 243 }