package collector import ( "context" "fmt" "strconv" "strings" "time" "github.com/redis/go-redis/v9" "datasource/config" "datasource/store" "datasource/types" ) type RedisCollector struct { rdb *redis.Client store *store.Store } func NewRedisCollector(cfg *config.RedisConfig, store *store.Store) *RedisCollector { rdb := redis.NewClient(&redis.Options{ Addr: fmt.Sprintf("%s:%d", cfg.Host, cfg.Port), Password: cfg.Password, }) return &RedisCollector{rdb: rdb, store: store} } func (c *RedisCollector) Close() error { return c.rdb.Close() } func (c *RedisCollector) Collect(ctx context.Context) error { metric := new(types.Metric) info, err := c.rdb.Info(ctx, "server", "memory").Result() if err != nil { // todo (david): log but don't return the error as we still need to save the metric } else { metric.Up = 1 for _, line := range strings.Split(info, "\r\n") { kv := strings.Split(line, ":") if len(kv) < 2 { continue } k, v := kv[0], kv[1] switch k { case "uptime_in_seconds": if uptimeSec, err := strconv.ParseInt(v, 10, 64); err != nil { return err } else { metric.UptimeSec = uptimeSec } case "used_memory": if memoryUsageBytes, err := strconv.ParseInt(v, 10, 64); err != nil { return err } else { metric.MemoryUsageBytes = memoryUsageBytes } } } } metric.Service = "redis" metric.TimestampSec = time.Now().Unix() if err := c.store.SaveMetric(ctx, metric); err != nil { return err } return nil }