github.com/netdata/go.d.plugin@v0.58.1/modules/redis/redis.go (about)

     1  // SPDX-License-Identifier: GPL-3.0-or-later
     2  
     3  package redis
     4  
     5  import (
     6  	"context"
     7  	_ "embed"
     8  	"sync"
     9  	"time"
    10  
    11  	"github.com/netdata/go.d.plugin/agent/module"
    12  	"github.com/netdata/go.d.plugin/pkg/metrics"
    13  	"github.com/netdata/go.d.plugin/pkg/tlscfg"
    14  	"github.com/netdata/go.d.plugin/pkg/web"
    15  
    16  	"github.com/blang/semver/v4"
    17  	"github.com/go-redis/redis/v8"
    18  )
    19  
    20  //go:embed "config_schema.json"
    21  var configSchema string
    22  
    23  func init() {
    24  	module.Register("redis", module.Creator{
    25  		Create:          func() module.Module { return New() },
    26  		JobConfigSchema: configSchema,
    27  	})
    28  }
    29  
    30  func New() *Redis {
    31  	return &Redis{
    32  		Config: Config{
    33  			Address:     "redis://@localhost:6379",
    34  			Timeout:     web.Duration{Duration: time.Second},
    35  			PingSamples: 5,
    36  		},
    37  
    38  		addAOFChartsOnce:       &sync.Once{},
    39  		addReplSlaveChartsOnce: &sync.Once{},
    40  		pingSummary:            metrics.NewSummary(),
    41  		collectedCommands:      make(map[string]bool),
    42  		collectedDbs:           make(map[string]bool),
    43  	}
    44  }
    45  
    46  type Config struct {
    47  	Address          string       `yaml:"address"`
    48  	Password         string       `yaml:"password"`
    49  	Username         string       `yaml:"username"`
    50  	Timeout          web.Duration `yaml:"timeout"`
    51  	PingSamples      int          `yaml:"ping_samples"`
    52  	tlscfg.TLSConfig `yaml:",inline"`
    53  }
    54  
    55  type (
    56  	Redis struct {
    57  		module.Base
    58  		Config `yaml:",inline"`
    59  
    60  		charts *module.Charts
    61  
    62  		rdb redisClient
    63  
    64  		server  string
    65  		version *semver.Version
    66  
    67  		addAOFChartsOnce       *sync.Once
    68  		addReplSlaveChartsOnce *sync.Once
    69  
    70  		pingSummary metrics.Summary
    71  
    72  		collectedCommands map[string]bool
    73  		collectedDbs      map[string]bool
    74  	}
    75  	redisClient interface {
    76  		Info(ctx context.Context, section ...string) *redis.StringCmd
    77  		Ping(context.Context) *redis.StatusCmd
    78  		Close() error
    79  	}
    80  )
    81  
    82  func (r *Redis) Init() bool {
    83  	err := r.validateConfig()
    84  	if err != nil {
    85  		r.Errorf("config validation: %v", err)
    86  		return false
    87  	}
    88  
    89  	rdb, err := r.initRedisClient()
    90  	if err != nil {
    91  		r.Errorf("init redis client: %v", err)
    92  		return false
    93  	}
    94  	r.rdb = rdb
    95  
    96  	charts, err := r.initCharts()
    97  	if err != nil {
    98  		r.Errorf("init charts: %v", err)
    99  		return false
   100  	}
   101  	r.charts = charts
   102  
   103  	return true
   104  }
   105  
   106  func (r *Redis) Check() bool {
   107  	return len(r.Collect()) > 0
   108  }
   109  
   110  func (r *Redis) Charts() *module.Charts {
   111  	return r.charts
   112  }
   113  
   114  func (r *Redis) Collect() map[string]int64 {
   115  	ms, err := r.collect()
   116  	if err != nil {
   117  		r.Error(err)
   118  	}
   119  
   120  	if len(ms) == 0 {
   121  		return nil
   122  	}
   123  	return ms
   124  }
   125  
   126  func (r *Redis) Cleanup() {
   127  	if r.rdb == nil {
   128  		return
   129  	}
   130  	err := r.rdb.Close()
   131  	if err != nil {
   132  		r.Warningf("cleanup: error on closing redis client [%s]: %v", r.Address, err)
   133  	}
   134  	r.rdb = nil
   135  }