github.com/wfusion/gofusion@v1.1.14/redis/metrics.go (about) 1 package redis 2 3 import ( 4 "context" 5 "log" 6 "syscall" 7 "time" 8 9 "github.com/spf13/cast" 10 11 "github.com/wfusion/gofusion/common/utils" 12 "github.com/wfusion/gofusion/config" 13 "github.com/wfusion/gofusion/metrics" 14 ) 15 16 var ( 17 metricsPoolIdleKey = []string{"redis", "idle"} 18 metricsPoolTotalKey = []string{"redis", "total"} 19 metricsPoolStaleKey = []string{"redis", "stale"} 20 metricsPoolHitsKey = []string{"redis", "hits"} 21 metricsPoolMissesKey = []string{"redis", "misses"} 22 metricsLatencyKey = []string{"redis", "latency"} 23 metricsLatencyBuckets = []float64{ 24 .1, .25, .5, .75, .90, .95, .99, 25 1, 2.5, 5, 7.5, 9, 9.5, 9.9, 26 10, 25, 50, 75, 90, 95, 99, 27 100, 250, 500, 750, 900, 950, 990, 28 } 29 ) 30 31 func startDaemonRoutines(ctx context.Context, appName, name string, conf *Conf) { 32 ticker := time.Tick(time.Second * 5) 33 app := config.Use(appName).AppName() 34 labels := []metrics.Label{ 35 {Key: "config", Value: name}, 36 {Key: "database", Value: cast.ToString(conf.DB)}, 37 } 38 39 log.Printf("%v [Gofusion] %s %s %s metrics start", syscall.Getpid(), app, config.ComponentRedis, name) 40 for { 41 select { 42 case <-ctx.Done(): 43 log.Printf("%v [Gofusion] %s %s %s metrics exited", 44 syscall.Getpid(), app, config.ComponentRedis, name) 45 return 46 case <-ticker: 47 go metricRedisStats(ctx, appName, name, labels) 48 go metricRedisLatency(ctx, appName, name, labels) 49 } 50 } 51 } 52 53 func metricRedisStats(ctx context.Context, appName, name string, labels []metrics.Label) { 54 select { 55 case <-ctx.Done(): 56 return 57 default: 58 } 59 60 _, _ = utils.Catch(func() { 61 rwlock.RLock() 62 defer rwlock.RUnlock() 63 _ = appInstances[appName][name].GetProxy() 64 instances, ok := appInstances[appName] 65 if !ok { 66 return 67 } 68 instance, ok := instances[name] 69 if !ok { 70 return 71 } 72 73 app := config.Use(appName).AppName() 74 idleKey := append([]string{app}, metricsPoolIdleKey...) 75 staleKey := append([]string{app}, metricsPoolStaleKey...) 76 totalKey := append([]string{app}, metricsPoolTotalKey...) 77 hitsKey := append([]string{app}, metricsPoolHitsKey...) 78 missesKey := append([]string{app}, metricsPoolMissesKey...) 79 80 rdsCli := instance.GetProxy() 81 stats := rdsCli.PoolStats() 82 for _, m := range metrics.Internal(metrics.AppName(appName)) { 83 select { 84 case <-ctx.Done(): 85 return 86 default: 87 if m.IsEnableServiceLabel() { 88 m.SetGauge(ctx, idleKey, float64(stats.IdleConns), metrics.Labels(labels)) 89 m.SetGauge(ctx, staleKey, float64(stats.StaleConns), metrics.Labels(labels)) 90 m.SetGauge(ctx, totalKey, float64(stats.TotalConns), metrics.Labels(labels)) 91 m.SetGauge(ctx, hitsKey, float64(stats.Hits), metrics.Labels(labels)) 92 m.SetGauge(ctx, missesKey, float64(stats.Misses), metrics.Labels(labels)) 93 } else { 94 m.SetGauge(ctx, metricsPoolIdleKey, float64(stats.IdleConns), metrics.Labels(labels)) 95 m.SetGauge(ctx, metricsPoolStaleKey, float64(stats.StaleConns), metrics.Labels(labels)) 96 m.SetGauge(ctx, metricsPoolTotalKey, float64(stats.TotalConns), metrics.Labels(labels)) 97 m.SetGauge(ctx, metricsPoolHitsKey, float64(stats.Hits), metrics.Labels(labels)) 98 m.SetGauge(ctx, metricsPoolMissesKey, float64(stats.Misses), metrics.Labels(labels)) 99 } 100 } 101 } 102 }) 103 } 104 105 func metricRedisLatency(ctx context.Context, appName, name string, labels []metrics.Label) { 106 select { 107 case <-ctx.Done(): 108 return 109 default: 110 111 } 112 113 _, _ = utils.Catch(func() { 114 rwlock.RLock() 115 defer rwlock.RUnlock() 116 instances, ok := appInstances[appName] 117 if !ok { 118 return 119 } 120 instance, ok := instances[name] 121 if !ok { 122 return 123 } 124 125 rdsCli := instance.GetProxy() 126 begin := time.Now() 127 if err := rdsCli.Ping(ctx); err != nil { 128 return 129 } 130 131 latency := float64(time.Since(begin)) / float64(time.Millisecond) 132 latencyKey := append([]string{config.Use(appName).AppName()}, metricsLatencyKey...) 133 for _, m := range metrics.Internal(metrics.AppName(appName)) { 134 select { 135 case <-ctx.Done(): 136 return 137 default: 138 if m.IsEnableServiceLabel() { 139 m.AddSample(ctx, latencyKey, latency, 140 metrics.Labels(labels), 141 metrics.PrometheusBuckets(metricsLatencyBuckets), 142 ) 143 } else { 144 m.AddSample(ctx, metricsLatencyKey, latency, 145 metrics.Labels(labels), 146 metrics.PrometheusBuckets(metricsLatencyBuckets), 147 ) 148 } 149 } 150 } 151 }) 152 }