redict/tests/unit/slowlog.tcl
Oran Agra 497351ad07
Fix SLOWLOG for blocked commands (#8632)
* SLOWLOG didn't record anything for blocked commands because the client
  was reset and argv was already empty. there was a fix for this issue
  specifically for modules, now it works for all blocked clients.
* The original command argv (before being re-written) was also reset
  before adding the slowlog on behalf of the blocked command.
* Latency monitor is now updated regardless of the slowlog flags of the
  command or its execution (their purpose is to hide sensitive info from
  the slowlog, not hide the fact the latency happened).
* Latency monitor now uses real_cmd rather than c->cmd (which may be
  different if the command got re-written, e.g. GEOADD)

Changes:
* Unify shared code between slowlog insertion in call() and
  updateStatsOnUnblock(), hopefully prevent future bugs from happening
  due to the later being overlooked.
* Reset CLIENT_PREVENT_LOGGING in resetClient rather than after command
  processing.
* Add a test for SLOWLOG and BLPOP

Notes:
- real_cmd == c->lastcmd, except inside MULTI and Lua.
- blocked commands never happen in these cases (MULTI / Lua)
- real_cmd == c->cmd, except for when the command is rewritten (e.g.
  GEOADD)
- blocked commands (currently) are never rewritten
- other than the command's CLIENT_PREVENT_LOGGING, and the
  execution flag CLIENT_PREVENT_LOGGING, other cases that we want to
  avoid slowlog are on AOF loading (specifically CMD_CALL_SLOWLOG will
  be off when executed from execCommand that runs from an AOF)
2021-03-25 10:20:27 +02:00

161 lines
5.4 KiB
Tcl

start_server {tags {"slowlog"} overrides {slowlog-log-slower-than 1000000}} {
test {SLOWLOG - check that it starts with an empty log} {
r slowlog len
} {0}
test {SLOWLOG - only logs commands taking more time than specified} {
r config set slowlog-log-slower-than 100000
r ping
assert_equal [r slowlog len] 0
r debug sleep 0.2
assert_equal [r slowlog len] 1
}
test {SLOWLOG - max entries is correctly handled} {
r config set slowlog-log-slower-than 0
r config set slowlog-max-len 10
for {set i 0} {$i < 100} {incr i} {
r ping
}
r slowlog len
} {10}
test {SLOWLOG - GET optional argument to limit output len works} {
llength [r slowlog get 5]
} {5}
test {SLOWLOG - RESET subcommand works} {
r config set slowlog-log-slower-than 100000
r slowlog reset
r slowlog len
} {0}
test {SLOWLOG - logged entry sanity check} {
r client setname foobar
r debug sleep 0.2
set e [lindex [r slowlog get] 0]
assert_equal [llength $e] 6
assert_equal [lindex $e 0] 105
assert_equal [expr {[lindex $e 2] > 100000}] 1
assert_equal [lindex $e 3] {debug sleep 0.2}
assert_equal {foobar} [lindex $e 5]
}
test {SLOWLOG - Certain commands are omitted that contain sensitive information} {
r config set slowlog-log-slower-than 0
r slowlog reset
r config set masterauth ""
r acl setuser slowlog-test-user
r config set slowlog-log-slower-than 0
r config set slowlog-log-slower-than 10000
set slowlog_resp [r slowlog get]
# Make sure normal configs work, but the two sensitive
# commands are omitted
assert_equal 2 [llength $slowlog_resp]
assert_equal {slowlog reset} [lindex [lindex [r slowlog get] 1] 3]
assert_equal {config set slowlog-log-slower-than 0} [lindex [lindex [r slowlog get] 0] 3]
}
test {SLOWLOG - Rewritten commands are logged as their original command} {
r config set slowlog-log-slower-than 0
# Test rewriting client arguments
r sadd set a b c d e
r slowlog reset
# SPOP is rewritten as DEL when all keys are removed
r spop set 10
assert_equal {spop set 10} [lindex [lindex [r slowlog get] 0] 3]
# Test replacing client arguments
r slowlog reset
# GEOADD is replicated as ZADD
r geoadd cool-cities -122.33207 47.60621 Seattle
assert_equal {geoadd cool-cities -122.33207 47.60621 Seattle} [lindex [lindex [r slowlog get] 0] 3]
# Test replacing a single command argument
r set A 5
r slowlog reset
# GETSET is replicated as SET
r getset a 5
assert_equal {getset a 5} [lindex [lindex [r slowlog get] 0] 3]
# INCRBYFLOAT calls rewrite multiple times, so it's a special case
r set A 0
r slowlog reset
# INCRBYFLOAT is replicated as SET
r INCRBYFLOAT A 1.0
assert_equal {INCRBYFLOAT A 1.0} [lindex [lindex [r slowlog get] 0] 3]
# blocked BLPOP is replicated as LPOP
set rd [redis_deferring_client]
$rd blpop l 0
wait_for_condition 50 100 {
[s blocked_clients] eq {1}
} else {
fail "Clients are not blocked"
}
r multi
r lpush l foo
r slowlog reset
r exec
$rd read
$rd close
assert_equal {blpop l 0} [lindex [lindex [r slowlog get] 0] 3]
}
test {SLOWLOG - commands with too many arguments are trimmed} {
r config set slowlog-log-slower-than 0
r slowlog reset
r sadd set 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
set e [lindex [r slowlog get] 0]
lindex $e 3
} {sadd set 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 {... (2 more arguments)}}
test {SLOWLOG - too long arguments are trimmed} {
r config set slowlog-log-slower-than 0
r slowlog reset
set arg [string repeat A 129]
r sadd set foo $arg
set e [lindex [r slowlog get] 0]
lindex $e 3
} {sadd set foo {AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA... (1 more bytes)}}
test {SLOWLOG - EXEC is not logged, just executed commands} {
r config set slowlog-log-slower-than 100000
r slowlog reset
assert_equal [r slowlog len] 0
r multi
r debug sleep 0.2
r exec
assert_equal [r slowlog len] 1
set e [lindex [r slowlog get] 0]
assert_equal [lindex $e 3] {debug sleep 0.2}
}
test {SLOWLOG - can clean older entries} {
r client setname lastentry_client
r config set slowlog-max-len 1
r debug sleep 0.2
assert {[llength [r slowlog get]] == 1}
set e [lindex [r slowlog get] 0]
assert_equal {lastentry_client} [lindex $e 5]
}
test {SLOWLOG - can be disabled} {
r config set slowlog-max-len 1
r config set slowlog-log-slower-than 1
r slowlog reset
r debug sleep 0.2
assert_equal [r slowlog len] 1
r config set slowlog-log-slower-than -1
r slowlog reset
r debug sleep 0.2
assert_equal [r slowlog len] 0
}
}