Skip to content

Commit 07aa5aa

Browse files
authored
Improve keyspace parsing with expired keys (#32)
1 parent cd0c4f3 commit 07aa5aa

File tree

3 files changed

+27
-15
lines changed

3 files changed

+27
-15
lines changed

exporter/exporter.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ func NewKvrocksExporter(kvrocksURI string, opts Options) (*Exporter, error) {
104104
"monitor_clients": "monitor_clients",
105105

106106
// # Memory
107-
108107
"used_memory": "memory_used_bytes",
109108
"used_memory_rss": "memory_used_rss_bytes",
110109
"used_memory_lua": "memory_used_lua_bytes",
@@ -186,6 +185,7 @@ func NewKvrocksExporter(kvrocksURI string, opts Options) (*Exporter, error) {
186185
"db_avg_ttl_seconds": {txt: "Avg TTL in seconds", lbls: []string{"db"}},
187186
"db_keys": {txt: "Total number of keys by DB", lbls: []string{"db"}},
188187
"db_keys_expiring": {txt: "Total number of expiring keys by DB", lbls: []string{"db"}},
188+
"db_keys_expired": {txt: "Total number of expired keys by DB", lbls: []string{"db"}},
189189
"exporter_last_scrape_error": {txt: "The last scrape error status.", lbls: []string{"err"}},
190190
"instance_info": {txt: "Information about the kvrocks instance", lbls: []string{"role", "version", "git_sha1", "os", "tcp_port", "gcc_version", "process_id"}},
191191
"last_slow_execution_duration_seconds": {txt: `The amount of time needed for last slow execution, in seconds`},

exporter/info.go

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ func (e *Exporter) extractInfoMetrics(ch chan<- prometheus.Metric, info string,
3636
line = strings.TrimSpace(line)
3737
log.Debugf("info: %s", line)
3838
if len(line) > 0 && strings.HasPrefix(line, "# ") {
39-
if strings.HasPrefix(line, "# Last scan db time") {
39+
if strings.HasPrefix(line, "# Last DBSIZE SCAN") {
4040
continue
4141
}
4242
fieldClass = line[2:]
@@ -77,11 +77,12 @@ func (e *Exporter) extractInfoMetrics(ch chan<- prometheus.Metric, info string,
7777
continue
7878

7979
case "Keyspace":
80-
if keysTotal, keysEx, avgTTL, ok := parseDBKeyspaceString(fieldKey, fieldValue); ok {
80+
if keysTotal, keysEx, avgTTL, keysExpired, ok := parseDBKeyspaceString(fieldKey, fieldValue); ok {
8181
dbName := fieldKey
8282

8383
e.registerConstMetricGauge(ch, "db_keys", keysTotal, dbName)
8484
e.registerConstMetricGauge(ch, "db_keys_expiring", keysEx, dbName)
85+
e.registerConstMetricGauge(ch, "db_keys_expired", keysExpired, dbName)
8586

8687
if avgTTL > -1 {
8788
e.registerConstMetricGauge(ch, "db_avg_ttl_seconds", avgTTL, dbName)
@@ -105,6 +106,7 @@ func (e *Exporter) extractInfoMetrics(ch chan<- prometheus.Metric, info string,
105106
if _, exists := handledDBs[dbName]; !exists {
106107
e.registerConstMetricGauge(ch, "db_keys", 0, dbName)
107108
e.registerConstMetricGauge(ch, "db_keys_expiring", 0, dbName)
109+
e.registerConstMetricGauge(ch, "db_keys_expired", 0, dbName)
108110
}
109111
}
110112

@@ -127,9 +129,11 @@ func (e *Exporter) extractInfoMetrics(ch chan<- prometheus.Metric, info string,
127129
}
128130

129131
/*
130-
valid example: db0:keys=1,expires=0,avg_ttl=0
132+
valid examples:
133+
- db0:keys=1,expires=0,avg_ttl=0
134+
- db0:keys=1,expires=10,avg_ttl=0,expired=2
131135
*/
132-
func parseDBKeyspaceString(inputKey string, inputVal string) (keysTotal float64, keysExpiringTotal float64, avgTTL float64, ok bool) {
136+
func parseDBKeyspaceString(inputKey string, inputVal string) (keysTotal float64, keysExpiringTotal float64, avgTTL float64, keysExpiredTotal float64, ok bool) {
133137
log.Debugf("parseDBKeyspaceString inputKey: [%s] inputVal: [%s]", inputKey, inputVal)
134138

135139
if !strings.HasPrefix(inputKey, "db") {
@@ -138,7 +142,7 @@ func parseDBKeyspaceString(inputKey string, inputVal string) (keysTotal float64,
138142
}
139143

140144
split := strings.Split(inputVal, ",")
141-
if len(split) != 3 {
145+
if len(split) < 2 || len(split) > 4 {
142146
log.Debugf("parseDBKeyspaceString strings.Split(inputVal) invalid: %#v", split)
143147
return
144148
}
@@ -162,6 +166,14 @@ func parseDBKeyspaceString(inputKey string, inputVal string) (keysTotal float64,
162166
avgTTL /= 1000
163167
}
164168

169+
keysExpiredTotal = 0
170+
if len(split) > 3 {
171+
if keysExpiredTotal, err = extractVal(split[3]); err != nil {
172+
log.Debugf("parseDBKeyspaceString extractVal(split[3]) invalid, err: %s", err)
173+
return
174+
}
175+
}
176+
165177
ok = true
166178
return
167179
}

exporter/info_test.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ import (
1414

1515
func TestKeyspaceStringParser(t *testing.T) {
1616
tsts := []struct {
17-
db string
18-
stats string
19-
keysTotal, keysEx, avgTTL float64
20-
ok bool
17+
db string
18+
stats string
19+
keysTotal, keysEx, avgTTL, keysExpired float64
20+
ok bool
2121
}{
2222
{db: "xxx", stats: "", ok: false},
2323
{db: "xxx", stats: "keys=1,expires=0,avg_ttl=0", ok: false},
@@ -28,20 +28,20 @@ func TestKeyspaceStringParser(t *testing.T) {
2828
{db: "db3", stats: "keys=abcde,expires=0", ok: false},
2929
{db: "db3", stats: "keys=213,expires=xxx", ok: false},
3030
{db: "db3", stats: "keys=123,expires=0,avg_ttl=zzz", ok: false},
31-
32-
{db: "db0", stats: "keys=1,expires=0,avg_ttl=0", keysTotal: 1, keysEx: 0, avgTTL: 0, ok: true},
31+
{db: "db0", stats: "keys=22113592,expires=21683101,avg_ttl=3816396,expired=340250", keysTotal: 22113592, keysEx: 21683101, avgTTL: 3816.396, keysExpired: 340250, ok: true},
32+
{db: "db0", stats: "keys=1,expires=0,avg_ttl=0", keysTotal: 1, keysEx: 0, avgTTL: 0, keysExpired: 0, ok: true},
3333
}
3434

3535
for _, tst := range tsts {
36-
if kt, kx, ttl, ok := parseDBKeyspaceString(tst.db, tst.stats); true {
36+
if kt, kx, ttl, kexp, ok := parseDBKeyspaceString(tst.db, tst.stats); true {
3737

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

43-
if ok && (kt != tst.keysTotal || kx != tst.keysEx || ttl != tst.avgTTL) {
44-
t.Errorf("values not matching, db:%s stats:%s %f %f %f", tst.db, tst.stats, kt, kx, ttl)
43+
if ok && (kt != tst.keysTotal || kx != tst.keysEx || ttl != tst.avgTTL || kexp != tst.keysExpired) {
44+
t.Errorf("values not matching, db:%s stats:%s %f %f %f", tst.db, tst.stats, kt, kx, ttl, kexp)
4545
}
4646
}
4747
}

0 commit comments

Comments
 (0)