Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,8 @@ scrape_configs:
| connection-timeout | REDIS_EXPORTER_CONNECTION_TIMEOUT | Timeout for connection to Redis instance, defaults to "15s" (in Golang duration format) |
| web.listen-address | REDIS_EXPORTER_WEB_LISTEN_ADDRESS | Address to listen on for web interface and telemetry, defaults to `0.0.0.0:9121`. |
| web.telemetry-path | REDIS_EXPORTER_WEB_TELEMETRY_PATH | Path under which to expose metrics, defaults to `/metrics`. |
| redis-only-metrics | REDIS_EXPORTER_REDIS_ONLY_METRICS | Whether to also export go runtime metrics, defaults to false. |
| redis-only-metrics | REDIS_EXPORTER_REDIS_ONLY_METRICS | Whether to export only Redis metrics (omit Go process+runtime metrics), defaults to false. |
| include-go-runtime-metrics | REDIS_EXPORTER_INCLUDE_GO_RUNTIME_METRICS | Whether to include Go runtime metrics, defaults to false. |
| include-config-metrics | REDIS_EXPORTER_INCL_CONFIG_METRICS | Whether to include all config settings as metrics, defaults to false. |
| include-system-metrics | REDIS_EXPORTER_INCL_SYSTEM_METRICS | Whether to include system metrics like `total_system_memory_bytes`, defaults to false. |
| include-modules-metrics | REDIS_EXPORTER_INCL_MODULES_METRICS | Whether to collect Redis Modules metrics, defaults to false. |
Expand All @@ -209,9 +210,9 @@ scrape_configs:
| 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. |
| 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. |
| config-command | REDIS_EXPORTER_CONFIG_COMMAND | What to use for the CONFIG command, defaults to `CONFIG`, , set to "-" to skip config metrics extraction. |
| 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
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is related to trailing spaces I think. My editor automatically removed them.
Can rollback this one if needed.

| 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
| include-metrics-for-empty-databases | REDIS_EXPORTER_INCL_METRICS_FOR_EMPTY_DATABASES | Whether to emit db metrics (like db_keys) for empty databases
| 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
| 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
| include-metrics-for-empty-databases | REDIS_EXPORTER_INCL_METRICS_FOR_EMPTY_DATABASES | Whether to emit db metrics (like db_keys) for empty databases

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

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

15 changes: 10 additions & 5 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,15 +124,19 @@ func setupLogging(isDebug bool, logLevel, logFormat string) error {
}

// createPrometheusRegistry creates and configures a Prometheus registry
func createPrometheusRegistry(redisMetricsOnly bool) *prometheus.Registry {
func createPrometheusRegistry(redisMetricsOnly, inclGoRuntimeMetrics bool) *prometheus.Registry {
registry := prometheus.NewRegistry()
if !redisMetricsOnly {
registry.MustRegister(
// expose process metrics like CPU, Memory, file descriptor usage etc.
collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}),
// expose all Go runtime metrics like GC stats, memory stats etc.
collectors.NewGoCollector(collectors.WithGoCollectorRuntimeMetrics(collectors.MetricsAll)),
)
if inclGoRuntimeMetrics {
registry.MustRegister(
// expose all Go runtime metrics like GC stats, memory stats etc.
collectors.NewGoCollector(collectors.WithGoCollectorRuntimeMetrics(collectors.MetricsAll)),
)
}
}
return registry
}
Expand Down Expand Up @@ -174,7 +178,8 @@ func main() {
exportClientList = flag.Bool("export-client-list", getEnvBool("REDIS_EXPORTER_EXPORT_CLIENT_LIST", false), "Whether to scrape Client List specific metrics")
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")
showVersion = flag.Bool("version", false, "Show version information and exit")
redisMetricsOnly = flag.Bool("redis-only-metrics", getEnvBool("REDIS_EXPORTER_REDIS_ONLY_METRICS", false), "Whether to also export go runtime metrics")
redisMetricsOnly = flag.Bool("redis-only-metrics", getEnvBool("REDIS_EXPORTER_REDIS_ONLY_METRICS", false), "Whether to export only Redis metrics (omit Go process+runtime metrics)")
inclGoRuntimeMetrics = flag.Bool("include-go-runtime-metrics", getEnvBool("REDIS_EXPORTER_INCLUDE_GO_RUNTIME_METRICS", false), "Whether to include Go runtime metrics")
pingOnConnect = flag.Bool("ping-on-connect", getEnvBool("REDIS_EXPORTER_PING_ON_CONNECT", false), "Whether to ping the redis instance after connecting")
inclConfigMetrics = flag.Bool("include-config-metrics", getEnvBool("REDIS_EXPORTER_INCL_CONFIG_METRICS", false), "Whether to include all config settings as metrics")
inclModulesMetrics = flag.Bool("include-modules-metrics", getEnvBool("REDIS_EXPORTER_INCL_MODULES_METRICS", false), "Whether to collect Redis Modules metrics")
Expand Down Expand Up @@ -229,7 +234,7 @@ func main() {
log.Fatalf("Error loading script files: %s", err)
}

registry := createPrometheusRegistry(*redisMetricsOnly)
registry := createPrometheusRegistry(*redisMetricsOnly, *inclGoRuntimeMetrics)

exp, err := exporter.NewRedisExporter(
*redisAddr,
Expand Down
30 changes: 19 additions & 11 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -402,34 +402,42 @@ func TestSetupLogging(t *testing.T) {

func TestCreatePrometheusRegistry(t *testing.T) {
tests := []struct {
name string
redisMetricsOnly bool
description string
name string
redisMetricsOnly bool
inclGoRuntimeMetrics bool
description string
}{
{"redis metrics only", true, "should create registry with only Redis metrics"},
{"all metrics", false, "should create registry with process and Go metrics"},
{"redis metrics only", true, false, "should create registry with only Redis metrics"},
{"redis + process metrics", false, false, "should create registry with Redis and process metrics"},
{"all metrics", false, true, "should create registry with process and Go metrics"},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
registry := createPrometheusRegistry(tt.redisMetricsOnly)
registry := createPrometheusRegistry(tt.redisMetricsOnly, tt.inclGoRuntimeMetrics)
if registry == nil {
t.Errorf("createPrometheusRegistry(%v) returned nil registry", tt.redisMetricsOnly)
t.Errorf("createPrometheusRegistry(%v, %v) returned nil registry", tt.redisMetricsOnly, tt.inclGoRuntimeMetrics)
}

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

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

// When redisMetricsOnly=false, we should have process/Go metrics
// When redisMetricsOnly=false, inclGoRuntimeMetrics=false we should have process metrics
// When redisMetricsOnly=false, inclGoRuntimeMetrics=true we should have Go process+runtime metrics
// When redisMetricsOnly=true, we should have fewer (or no) built-in metrics
if !tt.redisMetricsOnly {
if len(metricFamilies) == 0 {
t.Errorf("createPrometheusRegistry(false) expected process/Go metrics but got none")
t.Errorf("createPrometheusRegistry(%v, %v) expected Go process+runtime metrics but got none", tt.redisMetricsOnly, tt.inclGoRuntimeMetrics)
}
if !tt.inclGoRuntimeMetrics {
if len(metricFamilies) > 20 { // process metrics count is less than 10
t.Errorf("createPrometheusRegistry(%v, %v) expected only process metrics but got %v metrics", tt.redisMetricsOnly, tt.inclGoRuntimeMetrics, len(metricFamilies))
}
}
}
})
Expand Down Expand Up @@ -484,7 +492,7 @@ func TestMainFunctionsIntegration(t *testing.T) {
}

// Test registry creation
registry := createPrometheusRegistry(true)
registry := createPrometheusRegistry(true, false)
if registry == nil {
t.Error("Registry creation failed")
}
Expand Down
Loading