Skip to content

Commit a37ff02

Browse files
authored
feat: Add config metrics for Sentinel instances (#1058)
* feat: Add config metrics for Sentinel instances * update sentinel test case
1 parent 02ad204 commit a37ff02

File tree

3 files changed

+73
-0
lines changed

3 files changed

+73
-0
lines changed

exporter/exporter.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,8 @@ func NewRedisExporter(uri string, opts Options) (*Exporter, error) {
563563
"sentinel_scripts_queue_length": {txt: "Queue of user scripts to execute"},
564564
"sentinel_simulate_failure_flags": {txt: "Failures simulations"},
565565
"sentinel_tilt": {txt: "Sentinel is in TILT mode"},
566+
"sentinel_config_key_value": {txt: `Sentinel global config key and value`, lbls: []string{"key", "value"}},
567+
"sentinel_config_value": {txt: `Sentinel global config key and value as metric`, lbls: []string{"key"}},
566568
"slave_info": {txt: "Information about the Redis slave", lbls: []string{"master_host", "master_port", "read_only"}},
567569
"slave_repl_offset": {txt: "Slave replication offset", lbls: []string{"master_host", "master_port"}},
568570
"slowlog_last_id": {txt: `Last id of slowlog`},
@@ -882,6 +884,8 @@ func (e *Exporter) scrapeRedisHost(ch chan<- prometheus.Metric) error {
882884

883885
if strings.Contains(infoAll, "# Sentinel") {
884886
e.extractSentinelMetrics(ch, c)
887+
888+
e.extractSentinelConfig(ch, c)
885889
}
886890

887891
if e.options.ExportClientList {

exporter/sentinels.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,43 @@ func (e *Exporter) extractSentinelMetrics(ch chan<- prometheus.Metric, c redis.C
9696
}
9797
}
9898

99+
func (e *Exporter) extractSentinelConfig(ch chan<- prometheus.Metric, c redis.Conn) {
100+
if !e.options.InclConfigMetrics {
101+
return
102+
}
103+
sentinelConfig, err := redis.Values(doRedisCmd(c, "SENTINEL", "config", "get", "*"))
104+
if err != nil {
105+
log.Errorf("Error getting sentinel config: %s", err)
106+
return
107+
}
108+
109+
if len(sentinelConfig)%2 != 0 {
110+
log.Errorf("Invalid sentinel config, got: %#v", sentinelConfig)
111+
return
112+
}
113+
114+
log.Debugf("Sentinel config: %v", sentinelConfig)
115+
116+
for pos := 0; pos < len(sentinelConfig)/2; pos++ {
117+
strKey, err := redis.String(sentinelConfig[pos*2], nil)
118+
if err != nil {
119+
log.Errorf("invalid sentinel config key name, err: %s, skipped", err)
120+
continue
121+
}
122+
123+
strVal, err := redis.String(sentinelConfig[pos*2+1], nil)
124+
if err != nil {
125+
log.Debugf("invalid sentinel config value for key name %s, err: %s, skipped", strKey, err)
126+
continue
127+
}
128+
129+
e.registerConstMetricGauge(ch, "sentinel_config_key_value", 1.0, strKey, strVal)
130+
if val, err := strconv.ParseFloat(strVal, 64); err == nil {
131+
e.registerConstMetricGauge(ch, "sentinel_config_value", val, strKey)
132+
}
133+
}
134+
}
135+
99136
func (e *Exporter) processSentinelSentinels(ch chan<- prometheus.Metric, sentinelDetails []interface{}, labels ...string) {
100137

101138
// If we are here then this master is in ok state

exporter/sentinels_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package exporter
22

33
import (
44
"fmt"
5+
"net/http/httptest"
56
"os"
67
"strings"
78
"testing"
@@ -356,3 +357,34 @@ func TestSentinelScrapeRedisHostSentinelPath(t *testing.T) {
356357
t.Error("Expected to find sentinel metrics when scraping sentinel host via scrapeRedisHost()")
357358
}
358359
}
360+
361+
func TestSentinelScrapeAllConfig(t *testing.T) {
362+
if os.Getenv("TEST_VALKEY_SENTINEL_URI") == "" {
363+
t.Skipf("TEST_VALKEY_SENTINEL_URI not set - skipping")
364+
}
365+
addr := os.Getenv("TEST_VALKEY_SENTINEL_URI")
366+
for _, inc := range []bool{false, true} {
367+
e, _ := NewRedisExporter(
368+
addr,
369+
Options{Namespace: "test",
370+
InclConfigMetrics: inc,
371+
},
372+
)
373+
374+
ts := httptest.NewServer(e)
375+
defer ts.Close()
376+
377+
body := downloadURL(t, ts.URL+"/metrics")
378+
for _, want := range []string{
379+
"sentinel_config_key_value",
380+
"sentinel_config_value",
381+
} {
382+
if inc && !strings.Contains(body, want) {
383+
t.Fatalf("didn't find metrics with sentinel_config, want: %s, body: %s", want, body)
384+
return
385+
} else if !inc && strings.Contains(body, want) {
386+
t.Errorf("did NOT want metrics to include sentinel_config, have:\n%s", body)
387+
}
388+
}
389+
}
390+
}

0 commit comments

Comments
 (0)