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  }