Skip to content

Commit ac3d6f3

Browse files
oliver006寇天龙
andauthored
InclMetricsForEmptyDatabases (continuation of #988) (#1001)
* add InclMetricsForEmptyDatabases * add test --------- Co-authored-by: 寇天龙 <[email protected]>
1 parent c4f5e8b commit ac3d6f3

File tree

6 files changed

+51
-15
lines changed

6 files changed

+51
-15
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ scrape_configs:
210210
| config-command | REDIS_EXPORTER_CONFIG_COMMAND | What to use for the CONFIG command, defaults to `CONFIG`, , set to "-" to skip config metrics extraction. |
211211
| basic-auth-username | REDIS_EXPORTER_BASIC_AUTH_USERNAME | Username for Basic Authentication with the redis exporter needs to be set together with basic-auth-password to be effective
212212
| basic-auth-password | REDIS_EXPORTER_BASIC_AUTH_PASSWORD | Password for Basic Authentication with the redis exporter needs to be set together with basic-auth-username to be effective
213+
| include-metrics-for-empty-databases | REDIS_EXPORTER_INCL_METRICS_FOR_EMPTY_DATABASES | Whether to emit db metrics (like db_keys) for empty databases
213214

214215
Redis instance addresses can be tcp addresses: `redis://localhost:6379`, `redis.example.com:6379` or e.g. unix sockets: `unix:///tmp/redis.sock`.\
215216
SSL is supported by using the `rediss://` schema, for example: `rediss://azure-ssl-enabled-host.redis.cache.windows.net:6380` (note that the port is required when connecting to a non-standard 6379 port, e.g. with Azure Redis instances).\

exporter/exporter.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ type Options struct {
8888
BasicAuthUsername string
8989
BasicAuthPassword string
9090
SkipCheckKeysForRoleMaster bool
91+
InclMetricsForEmptyDatabases bool
9192
}
9293

9394
// NewRedisExporter returns a new exporter of Redis metrics.
@@ -714,13 +715,13 @@ func (e *Exporter) scrapeRedisHost(ch chan<- prometheus.Metric) error {
714715
if clusterInfo, err := redis.String(doRedisCmd(c, "CLUSTER", "INFO")); err == nil {
715716
e.extractClusterInfoMetrics(ch, clusterInfo)
716717

717-
// in cluster mode Redis only supports one database so no extra DB number padding needed
718+
// in cluster mode Redis only supports one database, so no extra DB number padding needed
718719
dbCount = 1
719720
} else {
720721
log.Errorf("Redis CLUSTER INFO err: %s", err)
721722
}
722723
} else if dbCount == 0 {
723-
// in non-cluster mode, if dbCount is zero then "CONFIG" failed to retrieve a valid
724+
// in non-cluster mode, if dbCount is zero, then "CONFIG" failed to retrieve a valid
724725
// number of databases, and we use the Redis config default which is 16
725726

726727
dbCount = 16

exporter/info.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,13 @@ func (e *Exporter) extractInfoMetrics(ch chan<- prometheus.Metric, info string,
159159
// from #Commandstats processing and the percentile info that we get from the #Latencystats processing
160160
e.generateCommandLatencySummaries(ch, cmdLatencyMap, cmdCount, cmdSum)
161161

162-
for dbIndex := 0; dbIndex < dbCount; dbIndex++ {
163-
dbName := "db" + strconv.Itoa(dbIndex)
164-
if _, exists := handledDBs[dbName]; !exists {
165-
e.registerConstMetricGauge(ch, "db_keys", 0, dbName)
166-
e.registerConstMetricGauge(ch, "db_keys_expiring", 0, dbName)
162+
if e.options.InclMetricsForEmptyDatabases {
163+
for dbIndex := 0; dbIndex < dbCount; dbIndex++ {
164+
dbName := "db" + strconv.Itoa(dbIndex)
165+
if _, exists := handledDBs[dbName]; !exists {
166+
e.registerConstMetricGauge(ch, "db_keys", 0, dbName)
167+
e.registerConstMetricGauge(ch, "db_keys_expiring", 0, dbName)
168+
}
167169
}
168170
}
169171

exporter/info_test.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,36 @@ func commandStatsCheck(t *testing.T, e *Exporter, want map[string]bool) {
131131
}
132132
}
133133

134+
func TestInclMetricsForEmptyDatabases(t *testing.T) {
135+
addr := os.Getenv("TEST_REDIS_URI")
136+
if addr == "" {
137+
t.Skipf("TEST_REDIS_URI not set - skipping")
138+
}
139+
140+
for _, inclMetrics := range []bool{true, false} {
141+
t.Run(fmt.Sprintf("inclMetrics:%t", inclMetrics), func(t *testing.T) {
142+
e, _ := NewRedisExporter(addr,
143+
Options{
144+
Namespace: "test", Registry: prometheus.NewRegistry(),
145+
InclMetricsForEmptyDatabases: inclMetrics,
146+
})
147+
ts := httptest.NewServer(e)
148+
defer ts.Close()
149+
150+
body := downloadURL(t, ts.URL+"/metrics")
151+
if inclMetrics {
152+
if !strings.Contains(body, `test_db_keys{db="db10"} 0`) {
153+
t.Errorf("Expected to find test_db_keys")
154+
}
155+
} else {
156+
if strings.Contains(body, `test_db_keys{db="db10"} 0`) {
157+
t.Errorf("Expected to not find test_db_keys")
158+
}
159+
}
160+
})
161+
}
162+
}
163+
134164
func TestClusterMaster(t *testing.T) {
135165
if os.Getenv("TEST_REDIS_CLUSTER_MASTER_URI") == "" {
136166
t.Skipf("TEST_REDIS_CLUSTER_MASTER_URI not set - skipping")

exporter/keys.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ func (e *Exporter) extractCheckKeyMetrics(ch chan<- prometheus.Metric, redisClie
8989
if e.options.IsCluster {
9090
cc, err := e.connectToRedisCluster()
9191
if err != nil {
92-
return fmt.Errorf("Couldn't connect to redis cluster, err: %s", err)
92+
return fmt.Errorf("couldn't connect to redis cluster, err: %s", err)
9393
}
9494
defer cc.Close()
9595

@@ -98,13 +98,13 @@ func (e *Exporter) extractCheckKeyMetrics(ch chan<- prometheus.Metric, redisClie
9898

9999
keys, err := parseKeyArg(e.options.CheckKeys)
100100
if err != nil {
101-
return fmt.Errorf("Couldn't parse check-keys: %w", err)
101+
return fmt.Errorf("couldn't parse check-keys: %w", err)
102102
}
103103
log.Debugf("keys: %#v", keys)
104104

105105
singleKeys, err := parseKeyArg(e.options.CheckSingleKeys)
106106
if err != nil {
107-
return fmt.Errorf("Couldn't parse check-single-keys: %w", err)
107+
return fmt.Errorf("couldn't parse check-single-keys: %w", err)
108108
}
109109
log.Debugf("e.singleKeys: %#v", singleKeys)
110110

@@ -243,13 +243,13 @@ func (e *Exporter) getKeyInfoPipelined(ch chan<- prometheus.Metric, c redis.Conn
243243

244244
log.Debugf("c.Send() STRLEN args: [%v]", keyName)
245245
if err := c.Send("STRLEN", keyName); err != nil {
246-
log.Errorf("PFCOUNT err: %s", err)
246+
log.Errorf("STRLEN err: %s", err)
247247
return
248248
}
249249

250250
log.Debugf("c.Send() GET args: [%v]", keyName)
251251
if err := c.Send("GET", keyName); err != nil {
252-
log.Errorf("PFCOUNT err: %s", err)
252+
log.Errorf("GET err: %s", err)
253253
return
254254
}
255255

main.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,11 @@ func main() {
9999
excludeLatencyHistogramMetrics = flag.Bool("exclude-latency-histogram-metrics", getEnvBool("REDIS_EXPORTER_EXCLUDE_LATENCY_HISTOGRAM_METRICS", false), "Do not try to collect latency histogram metrics")
100100
redactConfigMetrics = flag.Bool("redact-config-metrics", getEnvBool("REDIS_EXPORTER_REDACT_CONFIG_METRICS", true), "Whether to redact config settings that include potentially sensitive information like passwords")
101101
inclSystemMetrics = flag.Bool("include-system-metrics", getEnvBool("REDIS_EXPORTER_INCL_SYSTEM_METRICS", false), "Whether to include system metrics like e.g. redis_total_system_memory_bytes")
102-
skipTLSVerification = flag.Bool("skip-tls-verification", getEnvBool("REDIS_EXPORTER_SKIP_TLS_VERIFICATION", false), "Whether to skip TLS verification")
102+
skipTLSVerification = flag.Bool("skip-tls-verification", getEnvBool("REDIS_EXPORTER_SKIP_TLS_VERIFICATION", false), "Whether to to skip TLS verification")
103103
skipCheckKeysForRoleMaster = flag.Bool("skip-checkkeys-for-role-master", getEnvBool("REDIS_EXPORTER_SKIP_CHECKKEYS_FOR_ROLE_MASTER", false), "Whether to skip gathering the check-keys metrics (size, val) when the instance is of type master (reduce load on master nodes)")
104104
basicAuthUsername = flag.String("basic-auth-username", getEnv("REDIS_EXPORTER_BASIC_AUTH_USERNAME", ""), "Username for basic authentication")
105105
basicAuthPassword = flag.String("basic-auth-password", getEnv("REDIS_EXPORTER_BASIC_AUTH_PASSWORD", ""), "Password for basic authentication")
106+
inclMetricsForEmptyDatabases = flag.Bool("include-metrics-for-empty-databases", getEnvBool("REDIS_EXPORTER_INCL_METRICS_FOR_EMPTY_DATABASES", true), "Whether to emit db metrics (like db_keys) for empty databases")
106107
)
107108
flag.Parse()
108109

@@ -205,8 +206,9 @@ func main() {
205206
CommitSha: BuildCommitSha,
206207
Date: BuildDate,
207208
},
208-
BasicAuthUsername: *basicAuthUsername,
209-
BasicAuthPassword: *basicAuthPassword,
209+
BasicAuthUsername: *basicAuthUsername,
210+
BasicAuthPassword: *basicAuthPassword,
211+
InclMetricsForEmptyDatabases: *inclMetricsForEmptyDatabases,
210212
},
211213
)
212214
if err != nil {

0 commit comments

Comments
 (0)