bosun.org@v0.0.0-20210513094433-e25bc3e69a1f/cmd/scollector/collectors/redis_counters.go (about)

     1  package collectors
     2  
     3  import (
     4  	"fmt"
     5  	"strconv"
     6  	"strings"
     7  
     8  	"bosun.org/cmd/scollector/conf"
     9  	"bosun.org/collect"
    10  	"bosun.org/metadata"
    11  	"bosun.org/models"
    12  	"bosun.org/opentsdb"
    13  	"bosun.org/slog"
    14  	"github.com/garyburd/redigo/redis"
    15  )
    16  
    17  func init() {
    18  	registerInit(func(c *conf.Conf) {
    19  		for _, red := range c.RedisCounters {
    20  			collectors = append(collectors,
    21  				&IntervalCollector{
    22  					name: "redisCounters_" + red.Server,
    23  					F: func() (opentsdb.MultiDataPoint, error) {
    24  						return c_redis_counters(red.Server, red.Database)
    25  					},
    26  				})
    27  		}
    28  	})
    29  }
    30  
    31  func c_redis_counters(server string, db int) (opentsdb.MultiDataPoint, error) {
    32  	var md opentsdb.MultiDataPoint
    33  	conn, err := redis.Dial("tcp", server, redis.DialDatabase(db))
    34  	if err != nil {
    35  		return md, slog.Wrap(err)
    36  	}
    37  	defer conn.Close()
    38  
    39  	//do a dance to detect proper hscan command for ledis or redis
    40  	hscanCmd := "XHSCAN"
    41  	info, err := redis.String(conn.Do("info", "server"))
    42  	if err != nil {
    43  		return md, slog.Wrap(err)
    44  	}
    45  	if strings.Contains(info, "redis_version") {
    46  		hscanCmd = "HSCAN"
    47  	}
    48  
    49  	cursor := "0"
    50  	for {
    51  		vals, err := redis.Values(conn.Do(hscanCmd, collect.RedisCountersKey, cursor))
    52  		if err != nil {
    53  			return md, slog.Wrap(err)
    54  		}
    55  		if len(vals) != 2 {
    56  			return md, fmt.Errorf("Unexpected number of values")
    57  		}
    58  		cursor, err = redis.String(vals[0], nil)
    59  		if err != nil {
    60  			return md, slog.Wrap(err)
    61  		}
    62  		pairs, err := redis.StringMap(vals[1], nil)
    63  		if err != nil {
    64  			return md, slog.Wrap(err)
    65  		}
    66  		for key, val := range pairs {
    67  			ak := models.AlertKey(key)
    68  
    69  			v, err := strconv.Atoi(val)
    70  			if err != nil {
    71  				slog.Errorf("Invalid counter value: %s", val)
    72  				continue
    73  			}
    74  			Add(&md, ak.Name(), v, ak.Group(), metadata.Counter, metadata.Count, "")
    75  		}
    76  		if cursor == "" || cursor == "0" {
    77  			break
    78  		}
    79  	}
    80  	return md, nil
    81  }