Skip to content

Commit 02b2548

Browse files
committed
Feature: add include-go-runtime-metrics flag to enable Go runtime metrics
* Add include-go-runtime-metrics flag to enable Go runtime metrics, default disabled * Add test suite for inclGoRuntimeMetrics to main_test.go * Fix description for redisMetricsOnly flag Fix #1034
1 parent 7632b7b commit 02b2548

File tree

3 files changed

+34
-21
lines changed

3 files changed

+34
-21
lines changed

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,8 @@ scrape_configs:
186186
| connection-timeout | REDIS_EXPORTER_CONNECTION_TIMEOUT | Timeout for connection to Redis instance, defaults to "15s" (in Golang duration format) |
187187
| web.listen-address | REDIS_EXPORTER_WEB_LISTEN_ADDRESS | Address to listen on for web interface and telemetry, defaults to `0.0.0.0:9121`. |
188188
| web.telemetry-path | REDIS_EXPORTER_WEB_TELEMETRY_PATH | Path under which to expose metrics, defaults to `/metrics`. |
189-
| redis-only-metrics | REDIS_EXPORTER_REDIS_ONLY_METRICS | Whether to also export go runtime metrics, defaults to false. |
189+
| redis-only-metrics | REDIS_EXPORTER_REDIS_ONLY_METRICS | Whether to export only Redis metrics (omit Go process+runtime metrics), defaults to false. |
190+
| include-go-runtime-metrics | REDIS_EXPORTER_INCLUDE_GO_RUNTIME_METRICS | Whether to include Go runtime metrics, defaults to false. |
190191
| include-config-metrics | REDIS_EXPORTER_INCL_CONFIG_METRICS | Whether to include all config settings as metrics, defaults to false. |
191192
| include-system-metrics | REDIS_EXPORTER_INCL_SYSTEM_METRICS | Whether to include system metrics like `total_system_memory_bytes`, defaults to false. |
192193
| include-modules-metrics | REDIS_EXPORTER_INCL_MODULES_METRICS | Whether to collect Redis Modules metrics, defaults to false. |
@@ -209,9 +210,9 @@ scrape_configs:
209210
| check-key-groups | REDIS_EXPORTER_CHECK_KEY_GROUPS | Comma separated list of [LUA regexes](https://www.lua.org/pil/20.1.html) for classifying keys into groups. The regexes are applied in specified order to individual keys, and the group name is generated by concatenating all capture groups of the first regex that matches a key. A key will be tracked under the `unclassified` group if none of the specified regexes matches it. |
210211
| max-distinct-key-groups | REDIS_EXPORTER_MAX_DISTINCT_KEY_GROUPS | Maximum number of distinct key groups that can be tracked independently *per Redis database*. If exceeded, only key groups with the highest memory consumption within the limit will be tracked separately, all remaining key groups will be tracked under a single `overflow` key group. |
211212
| config-command | REDIS_EXPORTER_CONFIG_COMMAND | What to use for the CONFIG command, defaults to `CONFIG`, , set to "-" to skip config metrics extraction. |
212-
| 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
213-
| 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
214-
| include-metrics-for-empty-databases | REDIS_EXPORTER_INCL_METRICS_FOR_EMPTY_DATABASES | Whether to emit db metrics (like db_keys) for empty databases
213+
| 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
214+
| 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
215+
| include-metrics-for-empty-databases | REDIS_EXPORTER_INCL_METRICS_FOR_EMPTY_DATABASES | Whether to emit db metrics (like db_keys) for empty databases
215216

216217
Redis instance addresses can be tcp addresses: `redis://localhost:6379`, `redis.example.com:6379` or e.g. unix sockets: `unix:///tmp/redis.sock`.\
217218
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).\
@@ -378,4 +379,3 @@ Or you can bring up the stack, run the tests, and then tear down the stack, all
378379
## Communal effort
379380

380381
Open an issue or PR if you have more suggestions, questions or ideas about what to add.
381-

main.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -124,15 +124,19 @@ func setupLogging(isDebug bool, logLevel, logFormat string) error {
124124
}
125125

126126
// createPrometheusRegistry creates and configures a Prometheus registry
127-
func createPrometheusRegistry(redisMetricsOnly bool) *prometheus.Registry {
127+
func createPrometheusRegistry(redisMetricsOnly, inclGoRuntimeMetrics bool) *prometheus.Registry {
128128
registry := prometheus.NewRegistry()
129129
if !redisMetricsOnly {
130130
registry.MustRegister(
131131
// expose process metrics like CPU, Memory, file descriptor usage etc.
132132
collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}),
133-
// expose all Go runtime metrics like GC stats, memory stats etc.
134-
collectors.NewGoCollector(collectors.WithGoCollectorRuntimeMetrics(collectors.MetricsAll)),
135133
)
134+
if inclGoRuntimeMetrics {
135+
registry.MustRegister(
136+
// expose all Go runtime metrics like GC stats, memory stats etc.
137+
collectors.NewGoCollector(collectors.WithGoCollectorRuntimeMetrics(collectors.MetricsAll)),
138+
)
139+
}
136140
}
137141
return registry
138142
}
@@ -174,7 +178,8 @@ func main() {
174178
exportClientList = flag.Bool("export-client-list", getEnvBool("REDIS_EXPORTER_EXPORT_CLIENT_LIST", false), "Whether to scrape Client List specific metrics")
175179
exportClientPort = flag.Bool("export-client-port", getEnvBool("REDIS_EXPORTER_EXPORT_CLIENT_PORT", false), "Whether to include the client's port when exporting the client list. Warning: including the port increases the number of metrics generated and will make your Prometheus server take up more memory")
176180
showVersion = flag.Bool("version", false, "Show version information and exit")
177-
redisMetricsOnly = flag.Bool("redis-only-metrics", getEnvBool("REDIS_EXPORTER_REDIS_ONLY_METRICS", false), "Whether to also export go runtime metrics")
181+
redisMetricsOnly = flag.Bool("redis-only-metrics", getEnvBool("REDIS_EXPORTER_REDIS_ONLY_METRICS", false), "Whether to export only Redis metrics (omit Go process+runtime metrics)")
182+
inclGoRuntimeMetrics = flag.Bool("include-go-runtime-metrics", getEnvBool("REDIS_EXPORTER_INCLUDE_GO_RUNTIME_METRICS", false), "Whether to include Go runtime metrics")
178183
pingOnConnect = flag.Bool("ping-on-connect", getEnvBool("REDIS_EXPORTER_PING_ON_CONNECT", false), "Whether to ping the redis instance after connecting")
179184
inclConfigMetrics = flag.Bool("include-config-metrics", getEnvBool("REDIS_EXPORTER_INCL_CONFIG_METRICS", false), "Whether to include all config settings as metrics")
180185
inclModulesMetrics = flag.Bool("include-modules-metrics", getEnvBool("REDIS_EXPORTER_INCL_MODULES_METRICS", false), "Whether to collect Redis Modules metrics")
@@ -229,7 +234,7 @@ func main() {
229234
log.Fatalf("Error loading script files: %s", err)
230235
}
231236

232-
registry := createPrometheusRegistry(*redisMetricsOnly)
237+
registry := createPrometheusRegistry(*redisMetricsOnly, *inclGoRuntimeMetrics)
233238

234239
exp, err := exporter.NewRedisExporter(
235240
*redisAddr,

main_test.go

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -402,34 +402,42 @@ func TestSetupLogging(t *testing.T) {
402402

403403
func TestCreatePrometheusRegistry(t *testing.T) {
404404
tests := []struct {
405-
name string
406-
redisMetricsOnly bool
407-
description string
405+
name string
406+
redisMetricsOnly bool
407+
inclGoRuntimeMetrics bool
408+
description string
408409
}{
409-
{"redis metrics only", true, "should create registry with only Redis metrics"},
410-
{"all metrics", false, "should create registry with process and Go metrics"},
410+
{"redis metrics only", true, false, "should create registry with only Redis metrics"},
411+
{"redis + process metrics", false, false, "should create registry with Redis and process metrics"},
412+
{"all metrics", false, true, "should create registry with process and Go metrics"},
411413
}
412414

413415
for _, tt := range tests {
414416
t.Run(tt.name, func(t *testing.T) {
415-
registry := createPrometheusRegistry(tt.redisMetricsOnly)
417+
registry := createPrometheusRegistry(tt.redisMetricsOnly, tt.inclGoRuntimeMetrics)
416418
if registry == nil {
417-
t.Errorf("createPrometheusRegistry(%v) returned nil registry", tt.redisMetricsOnly)
419+
t.Errorf("createPrometheusRegistry(%v, %v) returned nil registry", tt.redisMetricsOnly, tt.inclGoRuntimeMetrics)
418420
}
419421

420422
// Verify it's a valid Prometheus registry (it's already *prometheus.Registry)
421423

422424
// Basic functionality test - gather metrics
423425
metricFamilies, err := registry.Gather()
424426
if err != nil {
425-
t.Errorf("createPrometheusRegistry(%v) registry.Gather() error: %v", tt.redisMetricsOnly, err)
427+
t.Errorf("createPrometheusRegistry(%v, %v) registry.Gather() error: %v", tt.redisMetricsOnly, tt.inclGoRuntimeMetrics, err)
426428
}
427429

428-
// When redisMetricsOnly=false, we should have process/Go metrics
430+
// When redisMetricsOnly=false, inclGoRuntimeMetrics=false we should have process metrics
431+
// When redisMetricsOnly=false, inclGoRuntimeMetrics=true we should have Go process+runtime metrics
429432
// When redisMetricsOnly=true, we should have fewer (or no) built-in metrics
430433
if !tt.redisMetricsOnly {
431434
if len(metricFamilies) == 0 {
432-
t.Errorf("createPrometheusRegistry(false) expected process/Go metrics but got none")
435+
t.Errorf("createPrometheusRegistry(%v, %v) expected Go process+runtime metrics but got none", tt.redisMetricsOnly, tt.inclGoRuntimeMetrics)
436+
}
437+
if !tt.inclGoRuntimeMetrics {
438+
if len(metricFamilies) > 20 { // process metrics count is less than 10
439+
t.Errorf("createPrometheusRegistry(%v, %v) expected only process metrics but got %v metrics", tt.redisMetricsOnly, tt.inclGoRuntimeMetrics, len(metricFamilies))
440+
}
433441
}
434442
}
435443
})
@@ -484,7 +492,7 @@ func TestMainFunctionsIntegration(t *testing.T) {
484492
}
485493

486494
// Test registry creation
487-
registry := createPrometheusRegistry(true)
495+
registry := createPrometheusRegistry(true, false)
488496
if registry == nil {
489497
t.Error("Registry creation failed")
490498
}

0 commit comments

Comments
 (0)