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  }