From 8bfc4e0b741010e6a609b6b363e9bedd5f0da9c2 Mon Sep 17 00:00:00 2001 From: Oliver Date: Tue, 1 Feb 2022 22:08:20 -0500 Subject: [PATCH] Config metrics and check keys as strings (#607) * go mod tidy * include config metrics * record string check keys as labels --- README.md | 5 ++- exporter/exporter.go | 64 +++++++++++++++++++++---------------- exporter/exporter_test.go | 40 ++++++++++++++++++----- exporter/key_groups_test.go | 6 ++-- exporter/keys.go | 13 +++++--- exporter/keys_test.go | 58 ++++++++++++++++++++++++++------- go.mod | 2 +- go.sum | 20 ++---------- main.go | 2 ++ 9 files changed, 136 insertions(+), 74 deletions(-) diff --git a/README.md b/README.md index 37298732..5f99e79a 100644 --- a/README.md +++ b/README.md @@ -151,6 +151,7 @@ connection-timeout | REDIS_EXPORTER_CONNECTION_TIMEOUT | Timeo 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. +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. ping-on-connect | REDIS_EXPORTER_PING_ON_CONNECT | Whether to ping the redis instance after connecting and record the duration as a metric, defaults to false. is-tile38 | REDIS_EXPORTER_IS_TILE38 | Whether to scrape Tile38 specific metrics, defaults to false. @@ -243,7 +244,9 @@ To enable Tile38 support, run the exporter with `--is-tile38=true`. Most items from the INFO command are exported, see [Redis documentation](https://redis.io/commands/info) for details.\ In addition, for every database there are metrics for total keys, expiring keys and the average TTL for keys in the database.\ -You can also export values of keys if they're in numeric format by using the `-check-keys` flag. The exporter will also export the size (or, depending on the data type, the length) of the key. This can be used to export the number of elements in (sorted) sets, hashes, lists, streams, etc. +You can also export values of keys by using the `-check-keys` (or related) flag. The exporter will also export the size (or, depending on the data type, the length) of the key. +This can be used to export the number of elements in (sorted) sets, hashes, lists, streams, etc. +If a key is in string format and matches with `--check-keys` (or related) then its string value will be exported as a label in the `key_value_as_string` metric. If you require custom metric collection, you can provide a [Redis Lua script](https://redis.io/commands/eval) using the `-script` flag. An example can be found [in the contrib folder](./contrib/sample_collect_script.lua). diff --git a/exporter/exporter.go b/exporter/exporter.go index 29327698..c56281bd 100644 --- a/exporter/exporter.go +++ b/exporter/exporter.go @@ -62,6 +62,7 @@ type Options struct { ClientCertFile string ClientKeyFile string CaCertFile string + InclConfigMetrics bool InclSystemMetrics bool SkipTLSVerification bool SetClientName bool @@ -321,58 +322,61 @@ func NewRedisExporter(redisURI string, opts Options) (*Exporter, error) { lbls []string }{ "commands_duration_seconds_total": {txt: `Total amount of time in seconds spent per command`, lbls: []string{"cmd"}}, - "commands_total": {txt: `Total number of calls per command`, lbls: []string{"cmd"}}, "commands_failed_calls_total": {txt: `Total number of errors prior command execution per command`, lbls: []string{"cmd"}}, "commands_rejected_calls_total": {txt: `Total number of errors within command execution per command`, lbls: []string{"cmd"}}, - "errors_total": {txt: `Total number of errors per error type`, lbls: []string{"err"}}, + "commands_total": {txt: `Total number of calls per command`, lbls: []string{"cmd"}}, + "config_key_value": {txt: `Config key and value`, lbls: []string{"key", "value"}}, + "config_value": {txt: `Config key and value as metric`, lbls: []string{"key"}}, + "connected_clients_details": {txt: "Details about connected clients", lbls: connectedClientsLabels}, "connected_slave_lag_seconds": {txt: "Lag of connected slave", lbls: []string{"slave_ip", "slave_port", "slave_state"}}, "connected_slave_offset_bytes": {txt: "Offset of connected slave", lbls: []string{"slave_ip", "slave_port", "slave_state"}}, "db_avg_ttl_seconds": {txt: "Avg TTL in seconds", lbls: []string{"db"}}, "db_keys": {txt: "Total number of keys by DB", lbls: []string{"db"}}, "db_keys_expiring": {txt: "Total number of expiring keys by DB", lbls: []string{"db"}}, + "errors_total": {txt: `Total number of errors per error type`, lbls: []string{"err"}}, "exporter_last_scrape_error": {txt: "The last scrape error status.", lbls: []string{"err"}}, "instance_info": {txt: "Information about the Redis instance", lbls: []string{"role", "redis_version", "redis_build_id", "redis_mode", "os", "maxmemory_policy", "tcp_port", "run_id", "process_id"}}, "key_group_count": {txt: `Count of keys in key group`, lbls: []string{"db", "key_group"}}, "key_group_memory_usage_bytes": {txt: `Total memory usage of key group in bytes`, lbls: []string{"db", "key_group"}}, "key_size": {txt: `The length or size of "key"`, lbls: []string{"db", "key"}}, "key_value": {txt: `The value of "key"`, lbls: []string{"db", "key"}}, + "key_value_as_string": {txt: `The value of "key" as a string`, lbls: []string{"db", "key", "val"}}, "keys_count": {txt: `Count of keys`, lbls: []string{"db", "key"}}, - "number_of_distinct_key_groups": {txt: `Number of distinct key groups`, lbls: []string{"db"}}, "last_key_groups_scrape_duration_milliseconds": {txt: `Duration of the last key group metrics scrape in milliseconds`}, "last_slow_execution_duration_seconds": {txt: `The amount of time needed for last slow execution, in seconds`}, - "latency_spike_last": {txt: `When the latency spike last occurred`, lbls: []string{"event_name"}}, "latency_spike_duration_seconds": {txt: `Length of the last latency spike in seconds`, lbls: []string{"event_name"}}, + "latency_spike_last": {txt: `When the latency spike last occurred`, lbls: []string{"event_name"}}, + "master_last_io_seconds_ago": {txt: "Master last io seconds ago", lbls: []string{"master_host", "master_port"}}, "master_link_up": {txt: "Master link status on Redis slave", lbls: []string{"master_host", "master_port"}}, "master_sync_in_progress": {txt: "Master sync in progress", lbls: []string{"master_host", "master_port"}}, - "master_last_io_seconds_ago": {txt: "Master last io seconds ago", lbls: []string{"master_host", "master_port"}}, + "number_of_distinct_key_groups": {txt: `Number of distinct key groups`, lbls: []string{"db"}}, "script_values": {txt: "Values returned by the collect script", lbls: []string{"key"}}, - "sentinel_tilt": {txt: "Sentinel is in TILT mode"}, + "sentinel_master_ok_sentinels": {txt: "The number of okay sentinels monitoring this master", lbls: []string{"master_name", "master_address"}}, + "sentinel_master_ok_slaves": {txt: "The number of okay slaves of the master", lbls: []string{"master_name", "master_address"}}, + "sentinel_master_sentinels": {txt: "The number of sentinels monitoring this master", lbls: []string{"master_name", "master_address"}}, + "sentinel_master_slaves": {txt: "The number of slaves of the master", lbls: []string{"master_name", "master_address"}}, + "sentinel_master_status": {txt: "Master status on Sentinel", lbls: []string{"master_name", "master_address", "master_status"}}, "sentinel_masters": {txt: "The number of masters this sentinel is watching"}, "sentinel_running_scripts": {txt: "Number of scripts in execution right now"}, "sentinel_scripts_queue_length": {txt: "Queue of user scripts to execute"}, "sentinel_simulate_failure_flags": {txt: "Failures simulations"}, - "sentinel_master_status": {txt: "Master status on Sentinel", lbls: []string{"master_name", "master_address", "master_status"}}, - "sentinel_master_slaves": {txt: "The number of slaves of the master", lbls: []string{"master_name", "master_address"}}, - "sentinel_master_ok_slaves": {txt: "The number of okay slaves of the master", lbls: []string{"master_name", "master_address"}}, - "sentinel_master_sentinels": {txt: "The number of sentinels monitoring this master", lbls: []string{"master_name", "master_address"}}, - "sentinel_master_ok_sentinels": {txt: "The number of okay sentinels monitoring this master", lbls: []string{"master_name", "master_address"}}, - "slave_repl_offset": {txt: "Slave replication offset", lbls: []string{"master_host", "master_port"}}, + "sentinel_tilt": {txt: "Sentinel is in TILT mode"}, "slave_info": {txt: "Information about the Redis slave", lbls: []string{"master_host", "master_port", "read_only"}}, + "slave_repl_offset": {txt: "Slave replication offset", lbls: []string{"master_host", "master_port"}}, "slowlog_last_id": {txt: `Last id of slowlog`}, "slowlog_length": {txt: `Total slowlog`}, "start_time_seconds": {txt: "Start time of the Redis instance since unix epoch in seconds."}, + "stream_group_consumer_idle_seconds": {txt: `Consumer idle time in seconds`, lbls: []string{"db", "stream", "group", "consumer"}}, + "stream_group_consumer_messages_pending": {txt: `Pending number of messages for this specific consumer`, lbls: []string{"db", "stream", "group", "consumer"}}, + "stream_group_consumers": {txt: `Consumers count of stream group`, lbls: []string{"db", "stream", "group"}}, + "stream_group_last_delivered_id": {txt: `The epoch timestamp (ms) of the last delivered message`, lbls: []string{"db", "stream", "group"}}, + "stream_group_messages_pending": {txt: `Pending number of messages in that stream group`, lbls: []string{"db", "stream", "group"}}, + "stream_groups": {txt: `Groups count of stream`, lbls: []string{"db", "stream"}}, + "stream_last_generated_id": {txt: `The epoch timestamp (ms) of the latest message on the stream`, lbls: []string{"db", "stream"}}, "stream_length": {txt: `The number of elements of the stream`, lbls: []string{"db", "stream"}}, "stream_radix_tree_keys": {txt: `Radix tree keys count"`, lbls: []string{"db", "stream"}}, "stream_radix_tree_nodes": {txt: `Radix tree nodes count`, lbls: []string{"db", "stream"}}, - "stream_last_generated_id": {txt: `The epoch timestamp (ms) of the latest message on the stream`, lbls: []string{"db", "stream"}}, - "stream_groups": {txt: `Groups count of stream`, lbls: []string{"db", "stream"}}, - "stream_group_consumers": {txt: `Consumers count of stream group`, lbls: []string{"db", "stream", "group"}}, - "stream_group_messages_pending": {txt: `Pending number of messages in that stream group`, lbls: []string{"db", "stream", "group"}}, - "stream_group_last_delivered_id": {txt: `The epoch timestamp (ms) of the last delivered message`, lbls: []string{"db", "stream", "group"}}, - "stream_group_consumer_messages_pending": {txt: `Pending number of messages for this specific consumer`, lbls: []string{"db", "stream", "group", "consumer"}}, - "stream_group_consumer_idle_seconds": {txt: `Consumer idle time in seconds`, lbls: []string{"db", "stream", "group", "consumer"}}, "up": {txt: "Information about the Redis instance"}, - "connected_clients_details": {txt: "Details about connected clients", lbls: connectedClientsLabels}, } { e.metricDescriptions[k] = newMetricDescr(opts.Namespace, k, desc.txt, desc.lbls) } @@ -469,18 +473,22 @@ func (e *Exporter) extractConfigMetrics(ch chan<- prometheus.Metric, config []st } } - // todo: we can add more configs to this map if there's interest - if !map[string]bool{ + if e.options.InclConfigMetrics { + e.registerConstMetricGauge(ch, "config_key_value", 1.0, strKey, strVal) + if val, err := strconv.ParseFloat(strVal, 64); err == nil { + e.registerConstMetricGauge(ch, "config_value", val, strKey) + } + } + + if map[string]bool{ "io-threads": true, "maxclients": true, "maxmemory": true, }[strKey] { - continue - } - - if val, err := strconv.ParseFloat(strVal, 64); err == nil { - strKey = strings.ReplaceAll(strKey, "-", "_") - e.registerConstMetricGauge(ch, fmt.Sprintf("config_%s", strKey), val) + if val, err := strconv.ParseFloat(strVal, 64); err == nil { + strKey = strings.ReplaceAll(strKey, "-", "_") + e.registerConstMetricGauge(ch, fmt.Sprintf("config_%s", strKey), val) + } } } return diff --git a/exporter/exporter_test.go b/exporter/exporter_test.go index 1b05bbb9..5e7f5491 100644 --- a/exporter/exporter_test.go +++ b/exporter/exporter_test.go @@ -30,10 +30,11 @@ const ( ) var ( - keys = []string{} - keysExpiring = []string{} - listKeys = []string{} - ts = int32(time.Now().Unix()) + keys = []string{} + keysExpiring = []string{} + listKeys = []string{} + singleStringKey string + ts = int32(time.Now().Unix()) dbNumStr = "11" altDBNumStr = "12" @@ -102,6 +103,8 @@ func setupKeys(t *testing.T, c redis.Conn, dbNumStr string) error { c.Do("SADD", TestSetName, "test-val-1") c.Do("SADD", TestSetName, "test-val-2") + c.Do("SET", singleStringKey, "this-is-a-string") + // Create test streams c.Do("XGROUP", "CREATE", TestStreamName, "test_group_1", "$", "MKSTREAM") c.Do("XGROUP", "CREATE", TestStreamName, "test_group_2", "$", "MKSTREAM") @@ -135,6 +138,7 @@ func deleteKeys(c redis.Conn, dbNumStr string) { c.Do("DEL", TestSetName) c.Do("DEL", TestStreamName) + c.Do("DEL", singleStringKey) } func setupDBKeys(t *testing.T, uri string) error { @@ -221,6 +225,26 @@ func TestIncludeSystemMemoryMetric(t *testing.T) { } } +func TestIncludeConfigMetrics(t *testing.T) { + for _, inc := range []bool{false, true} { + r := prometheus.NewRegistry() + ts := httptest.NewServer(promhttp.HandlerFor(r, promhttp.HandlerOpts{})) + e, _ := NewRedisExporter(os.Getenv("TEST_REDIS_URI"), Options{Namespace: "test", InclConfigMetrics: inc}) + r.Register(e) + + what := `test_config_key_value{key="appendonly",value="no"}` + + body := downloadURL(t, ts.URL+"/metrics") + if inc && !strings.Contains(body, what) { + t.Errorf("want metrics to include test_config_key_value, have:\n%s", body) + } else if !inc && strings.Contains(body, what) { + t.Errorf("did NOT want metrics to include test_config_key_value, have:\n%s", body) + } + + ts.Close() + } +} + func TestNonExistingHost(t *testing.T) { e, _ := NewRedisExporter("unix:///tmp/doesnt.exist", Options{Namespace: "test"}) @@ -345,14 +369,14 @@ func init() { } for _, n := range []string{"john", "paul", "ringo", "george"} { - key := fmt.Sprintf("key_%s_%d", n, ts) - keys = append(keys, key) + keys = append(keys, fmt.Sprintf("key_%s_%d", n, ts)) } + singleStringKey = fmt.Sprintf("key_string_%d", ts) + listKeys = append(listKeys, "beatles_list") for _, n := range []string{"A.J.", "Howie", "Nick", "Kevin", "Brian"} { - key := fmt.Sprintf("key_exp_%s_%d", n, ts) - keysExpiring = append(keysExpiring, key) + keysExpiring = append(keysExpiring, fmt.Sprintf("key_exp_%s_%d", n, ts)) } } diff --git a/exporter/key_groups_test.go b/exporter/key_groups_test.go index 8569524f..155cac4f 100644 --- a/exporter/key_groups_test.go +++ b/exporter/key_groups_test.go @@ -71,7 +71,7 @@ func TestKeyGroupMetrics(t *testing.T) { wantedCount: map[string]int{ "key_ringo": 1, "key_paul": 1, - "unclassified": 5, + "unclassified": 6, "key_exp": 5, }, wantedMemory: map[string]bool{ @@ -92,13 +92,13 @@ func TestKeyGroupMetrics(t *testing.T) { // updates of the init() function wantedCount: map[string]int{ "test-stream": 1, - "overflow": 11, + "overflow": 12, }, wantedMemory: map[string]bool{ "test-stream": true, "overflow": true, }, - wantedDistintKeyGroups: 12, + wantedDistintKeyGroups: 13, }, } diff --git a/exporter/keys.go b/exporter/keys.go index f5c99297..3d5d676a 100644 --- a/exporter/keys.go +++ b/exporter/keys.go @@ -96,7 +96,7 @@ func (e *Exporter) extractCheckKeyMetrics(ch chan<- prometheus.Metric, c redis.C log.Debugf("allKeys: %#v", allKeys) for _, k := range allKeys { if e.options.IsCluster { - //Cluster mode only has one db + // Cluster mode only has one db k.db = "0" } else { if _, err := doRedisCmd(c, "SELECT", k.db); err != nil { @@ -116,9 +116,14 @@ func (e *Exporter) extractCheckKeyMetrics(ch chan<- prometheus.Metric, c redis.C // Only run on single value strings if info.keyType == "string" { - // Only record value metric if value is float-y - if val, err := redis.Float64(doRedisCmd(c, "GET", k.key)); err == nil { - e.registerConstMetricGauge(ch, "key_value", val, dbLabel, k.key) + if strVal, err := redis.String(doRedisCmd(c, "GET", k.key)); err == nil { + if val, err := strconv.ParseFloat(strVal, 64); err == nil { + // Only record value metric if value is float-y + e.registerConstMetricGauge(ch, "key_value", val, dbLabel, k.key) + } else { + // if it's not float-y then we'll record the value as a string label + e.registerConstMetricGauge(ch, "key_value_as_string", 1.0, dbLabel, k.key, strVal) + } } } default: diff --git a/exporter/keys_test.go b/exporter/keys_test.go index c7b13232..4ec8ba84 100644 --- a/exporter/keys_test.go +++ b/exporter/keys_test.go @@ -24,30 +24,64 @@ const ( func TestKeyValuesAndSizes(t *testing.T) { e, _ := NewRedisExporter( os.Getenv("TEST_REDIS_URI"), - Options{Namespace: "test", CheckSingleKeys: dbNumStrFull + "=" + url.QueryEscape(keys[0])}, + Options{ + Namespace: "test", + CheckSingleKeys: dbNumStrFull + "=" + url.QueryEscape(keys[0]), + Registry: prometheus.NewRegistry()}, ) + ts := httptest.NewServer(e) + defer ts.Close() setupDBKeys(t, os.Getenv("TEST_REDIS_URI")) defer deleteKeysFromDB(t, os.Getenv("TEST_REDIS_URI")) - chM := make(chan prometheus.Metric) + chM := make(chan prometheus.Metric, 10000) go func() { e.Collect(chM) close(chM) }() - want := map[string]bool{"test_key_size": false, "test_key_value": false} - - for m := range chM { - for k := range want { - if strings.Contains(m.Desc().String(), k) { - want[k] = true - } + body := downloadURL(t, ts.URL+"/metrics") + for _, want := range []string{ + "test_key_size", + "test_key_value", + } { + if !strings.Contains(body, want) { + t.Fatalf("didn't find %s, body: %s", want, body) + return } } - for k, found := range want { - if !found { - t.Errorf("didn't find %s", k) +} + +func TestKeyValuesAsLabel(t *testing.T) { + e, _ := NewRedisExporter( + os.Getenv("TEST_REDIS_URI"), + Options{ + Namespace: "test", + CheckSingleKeys: dbNumStrFull + "=" + url.QueryEscape(singleStringKey), + Registry: prometheus.NewRegistry()}, + ) + ts := httptest.NewServer(e) + defer ts.Close() + + setupDBKeys(t, os.Getenv("TEST_REDIS_URI")) + defer deleteKeysFromDB(t, os.Getenv("TEST_REDIS_URI")) + + chM := make(chan prometheus.Metric, 10000) + go func() { + e.Collect(chM) + close(chM) + }() + + body := downloadURL(t, ts.URL+"/metrics") + for _, want := range []string{ + "test_key_size", + "test_key_value", + "key_value_as_string", + } { + if !strings.Contains(body, want) { + t.Fatalf("didn't find %s, body: %s", want, body) + return } } } diff --git a/go.mod b/go.mod index a1d34704..eafb63a8 100644 --- a/go.mod +++ b/go.mod @@ -4,8 +4,8 @@ go 1.13 require ( github.com/gomodule/redigo v1.8.8 - github.com/prometheus/client_golang v1.12.1 github.com/mna/redisc v1.3.2 + github.com/prometheus/client_golang v1.12.1 github.com/prometheus/client_model v0.2.0 github.com/sirupsen/logrus v1.8.1 ) diff --git a/go.sum b/go.sum index 13418d1e..f5f8da8e 100644 --- a/go.sum +++ b/go.sum @@ -43,7 +43,6 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -94,15 +93,11 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/gomodule/redigo v1.8.5 h1:nRAxCa+SVsyjSBrtZmG/cqb6VbTmuRzpg/PoTFlpumc= github.com/gomodule/redigo v1.8.5/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0= -github.com/gomodule/redigo v1.8.6 h1:h7kHSqUl2kxeaQtVslsfUCPJ1oz2pxcyzLy4zezIzPw= -github.com/gomodule/redigo v1.8.6/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0= github.com/gomodule/redigo v1.8.8 h1:f6cXq6RRfiyrOJEV7p3JhLDlmawGBVBBP1MggY8Mo4E= github.com/gomodule/redigo v1.8.8/go.mod h1:7ArFNvsTjH8GMMzB4uy1snslv2BwmginuMs06a1uzZE= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -153,8 +148,6 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/mna/redisc v1.1.7 h1:FdmtJsfTjoIjNXiQf4ozgNjuE+zxWH+fJSe+I/dD4vc= -github.com/mna/redisc v1.1.7/go.mod h1:GXeOb7zyYKiT+K8MKdIiJvuv7MfhDoQGcuzfiJQmqQI= github.com/mna/redisc v1.3.2 h1:sc9C+nj6qmrTFnsXb70xkjAHpXKtjjBuE6v2UcQV0ZE= github.com/mna/redisc v1.3.2/go.mod h1:CplIoaSTDi5h9icnj4FLbRgHoNKCHDNJDVRztWDGeSQ= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -172,10 +165,7 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.0 h1:C+UIj/QWtmqY13Arb8kwMt5j34/0Z2iKamrJ+ryC0Gg= -github.com/prometheus/client_golang v1.12.0/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= @@ -185,14 +175,12 @@ github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2 github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= @@ -207,8 +195,8 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -333,7 +321,6 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40 h1:JWgyZ1qgdTaF3N3oxC+MdTV7qvEEgHo3otj+HB5CM7Q= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -389,8 +376,8 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= @@ -465,7 +452,6 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.26.0-rc.1 h1:7QnIQpGRHE5RnLKnESfDoxm2dTapTZua5a0kS0A+VXQ= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= @@ -479,9 +465,9 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/main.go b/main.go index 22f6bcb2..8dbed30f 100644 --- a/main.go +++ b/main.go @@ -87,6 +87,7 @@ func main() { 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") 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") 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") skipTLSVerification = flag.Bool("skip-tls-verification", getEnvBool("REDIS_EXPORTER_SKIP_TLS_VERIFICATION", false), "Whether to to skip TLS verification") ) @@ -158,6 +159,7 @@ func main() { CountKeys: *countKeys, LuaScript: ls, InclSystemMetrics: *inclSystemMetrics, + InclConfigMetrics: *inclConfigMetrics, SetClientName: *setClientName, IsTile38: *isTile38, IsCluster: *isCluster,