Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix #650, add db_keys_cached gauge. #656

Merged
merged 11 commits into from
Jun 9, 2022
4 changes: 2 additions & 2 deletions .drone.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,15 @@ services:
- 6381

- name: keydb-01
image: "eqalpha/keydb:x86_64_v5.3.0"
image: "eqalpha/keydb:x86_64_v6.3.1"
pull: if-not-exists
commands:
- "keydb-server --protected-mode no --port 6401 --dbfilename dump-keydb-01.rdb"
ports:
- 6401

- name: keydb-02
image: "eqalpha/keydb:x86_64_v5.3.0"
image: "eqalpha/keydb:x86_64_v6.3.1"
pull: if-not-exists
commands:
- "keydb-server --protected-mode no --port 6402 --active-replica yes --replicaof keydb-01 6401 --dbfilename dump-keydb-02.rdb"
Expand Down
4 changes: 2 additions & 2 deletions contrib/docker-compose-for-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ services:
- "6381"

keydb-01:
image: "eqalpha/keydb:x86_64_v5.3.0"
image: "eqalpha/keydb:x86_64_v6.3.1"
command: "keydb-server --protected-mode no --port 6401 --dbfilename dump-keydb-01.rdb"
ports:
- "6401"

keydb-02:
image: "eqalpha/keydb:x86_64_v5.3.0"
image: "eqalpha/keydb:x86_64_v6.3.1"
command: "keydb-server --protected-mode no --port 6402 --active-replica yes --replicaof keydb-01 6401 --dbfilename dump-keydb-02.rdb"
ports:
- "6402"
Expand Down
2 changes: 2 additions & 0 deletions exporter/exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ func NewRedisExporter(redisURI string, opts Options) (*Exporter, error) {
"total_net_output_bytes": "net_output_bytes_total",

"expired_keys": "expired_keys_total",
"cached_keys": "cached_keys_total",
"evicted_keys": "evicted_keys_total",
"keyspace_hits": "keyspace_hits_total",
"keyspace_misses": "keyspace_misses_total",
Expand Down Expand Up @@ -351,6 +352,7 @@ func NewRedisExporter(redisURI string, opts Options) (*Exporter, error) {
"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"}},
"db_keys_cached": {txt: "Total number of cached 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"}},
Expand Down
20 changes: 15 additions & 5 deletions exporter/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,14 @@ func (e *Exporter) extractInfoMetrics(ch chan<- prometheus.Metric, info string,
continue

case "Keyspace":
if keysTotal, keysEx, avgTTL, ok := parseDBKeyspaceString(fieldKey, fieldValue); ok {
if keysTotal, keysEx, avgTTL, keysCached, ok := parseDBKeyspaceString(fieldKey, fieldValue); ok {
dbName := fieldKey

e.registerConstMetricGauge(ch, "db_keys", keysTotal, dbName)
e.registerConstMetricGauge(ch, "db_keys_expiring", keysEx, dbName)

if keysCached > -1 {
e.registerConstMetricGauge(ch, "db_keys_cached", keysCached, dbName)
}
if avgTTL > -1 {
e.registerConstMetricGauge(ch, "db_avg_ttl_seconds", avgTTL, dbName)
}
Expand Down Expand Up @@ -185,9 +187,9 @@ func (e *Exporter) extractClusterInfoMetrics(ch chan<- prometheus.Metric, info s
}

/*
valid example: db0:keys=1,expires=0,avg_ttl=0
valid example: db0:keys=1,expires=0,avg_ttl=0,cached_keys=0
*/
func parseDBKeyspaceString(inputKey string, inputVal string) (keysTotal float64, keysExpiringTotal float64, avgTTL float64, ok bool) {
func parseDBKeyspaceString(inputKey string, inputVal string) (keysTotal float64, keysExpiringTotal float64, avgTTL float64, keysCachedTotal float64, ok bool) {
log.Debugf("parseDBKeyspaceString inputKey: [%s] inputVal: [%s]", inputKey, inputVal)

if !strings.HasPrefix(inputKey, "db") {
Expand All @@ -196,7 +198,7 @@ func parseDBKeyspaceString(inputKey string, inputVal string) (keysTotal float64,
}

split := strings.Split(inputVal, ",")
if len(split) != 3 && len(split) != 2 {
if len(split) < 2 || len(split) > 4 {
log.Debugf("parseDBKeyspaceString strings.Split(inputVal) invalid: %#v", split)
return
}
Expand All @@ -220,6 +222,14 @@ func parseDBKeyspaceString(inputKey string, inputVal string) (keysTotal float64,
avgTTL /= 1000
}

keysCachedTotal = -1
if len(split) > 3 {
if keysCachedTotal, err = extractVal(split[3]); err != nil {
log.Debugf("parseDBKeyspaceString extractVal(split[3]) invalid, err: %s", err)
return
}
}

ok = true
return
}
Expand Down
20 changes: 12 additions & 8 deletions exporter/info_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ import (

func TestKeyspaceStringParser(t *testing.T) {
tsts := []struct {
db string
stats string
keysTotal, keysEx, avgTTL float64
ok bool
db string
stats string
keysTotal, keysEx, keysCached, avgTTL float64
vixns marked this conversation as resolved.
Show resolved Hide resolved
ok bool
}{
{db: "xxx", stats: "", ok: false},
{db: "xxx", stats: "keys=1,expires=0,avg_ttl=0", ok: false},
Expand All @@ -29,20 +29,24 @@ func TestKeyspaceStringParser(t *testing.T) {
{db: "db3", stats: "keys=abcde,expires=0", ok: false},
{db: "db3", stats: "keys=213,expires=xxx", ok: false},
{db: "db3", stats: "keys=123,expires=0,avg_ttl=zzz", ok: false},
{db: "db3", stats: "keys=1,expires=0,avg_ttl=zzz,cached_keys=0", ok: false},
{db: "db3", stats: "keys=1,expires=0,avg_ttl=0,cached_keys=zzz", ok: false},
{db: "db3", stats: "keys=1,expires=0,avg_ttl=0,cached_keys=0,extra=0", ok: false},

{db: "db0", stats: "keys=1,expires=0,avg_ttl=0", keysTotal: 1, keysEx: 0, avgTTL: 0, ok: true},
{db: "db0", stats: "keys=1,expires=0,avg_ttl=0", keysTotal: 1, keysEx: 0, avgTTL: 0, keysCached: -1, ok: true},
{db: "db0", stats: "keys=1,expires=0,avg_ttl=0,cached_keys=0", keysTotal: 1, keysEx: 0, avgTTL: 0, keysCached: 0, ok: true},
}

for _, tst := range tsts {
if kt, kx, ttl, ok := parseDBKeyspaceString(tst.db, tst.stats); true {
if kt, kx, ttl, kc, ok := parseDBKeyspaceString(tst.db, tst.stats); true {

if ok != tst.ok {
t.Errorf("failed for: db:%s stats:%s", tst.db, tst.stats)
continue
}

if ok && (kt != tst.keysTotal || kx != tst.keysEx || ttl != tst.avgTTL) {
t.Errorf("values not matching, db:%s stats:%s %f %f %f", tst.db, tst.stats, kt, kx, ttl)
if ok && (kt != tst.keysTotal || kx != tst.keysEx || kc != tst.keysCached || ttl != tst.avgTTL) {
t.Errorf("values not matching, db:%s stats:%s %f %f %f %f", tst.db, tst.stats, kt, kx, kc, ttl)
}
}
}
Expand Down