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 }