本节重点介绍 :
源码解读
初始化redis-exporter对象
- 代码位置 D:\go_path\pkg\mod\github.com\oliver006\redis_exporter@v1.24.0\main.go
exp, err := exporter.NewRedisExporter()
NewRedisExporter中注册 /scrape handler
- 位置 D:\go_path\pkg\mod\github.com\oliver006\redis_exporter@v1.24.0\exporter\exporter.go
e.mux.HandleFunc("/scrape", e.scrapeHandler)
scrapeHandler 注册采集对象
- 位置 D:\go_path\pkg\mod\github.com\oliver006\redis_exporter@v1.24.0\exporter\http.go
- 解析target参数
- 创建RedisExporter
- 注册采集对象
target := r.URL.Query().Get("target")_, err = NewRedisExporter(target, opts)if err != nil {http.Error(w, "NewRedisExporter() err: err", http.StatusBadRequest)e.targetScrapeRequestErrors.Inc()return}promhttp.HandlerFor(registry, promhttp.HandlerOpts{ErrorHandling: promhttp.ContinueOnError},
执行采集
- 调用 RedisExporter绑定的Collect方法
- e.scrapeRedisHost(ch) 代表连接redis实例执行采集
func (e *Exporter) Collect(ch chan<- prometheus.Metric) {e.Lock()defer e.Unlock()e.totalScrapes.Inc()if e.redisAddr != "" {startTime := time.Now()var up float64if err := e.scrapeRedisHost(ch); err != nil {e.registerConstMetricGauge(ch, "exporter_last_scrape_error", 1.0, fmt.Sprintf("%s", err))} else {up = 1e.registerConstMetricGauge(ch, "exporter_last_scrape_error", 0, "")}e.registerConstMetricGauge(ch, "up", up)took := time.Since(startTime).Seconds()e.scrapeDuration.Observe(took)e.registerConstMetricGauge(ch, "exporter_last_scrape_duration_seconds", took)}ch <- e.totalScrapesch <- e.scrapeDurationch <- e.targetScrapeRequestErrors
}
最终的执行函数 scrapeRedisHost
- 连接redis获得 client对象c,对应的redis库 为 github.com/gomodule/redigo/redis
c, err := e.connectToRedis()
- 调用封装好的 doRedisCmd函数执行redis 命令
func doRedisCmd(c redis.Conn, cmd string, args ...interface{}) (interface{}, error) {log.Debugf("c.Do() - running command: %s %s", cmd, args)res, err := c.Do(cmd, args...)if err != nil {log.Debugf("c.Do() - err: %s", err)}log.Debugf("c.Do() - done")return res, err
}
- 执行redis命令 ,做结果转换,推送到ch中即可
本节重点总结 :