diff --git a/src/server.c b/src/server.c index 239434a2..821d24b3 100644 --- a/src/server.c +++ b/src/server.c @@ -2408,6 +2408,7 @@ void preventCommandReplication(client *c) { void call(client *c, int flags) { long long dirty, start, duration; int client_old_flags = c->flags; + struct redisCommand *real_cmd = c->cmd; /* Sent the command to clients in MONITOR mode, only if the commands are * not generated from reading an AOF. */ @@ -2456,8 +2457,11 @@ void call(client *c, int flags) { slowlogPushEntryIfNeeded(c,c->argv,c->argc,duration); } if (flags & CMD_CALL_STATS) { - c->lastcmd->microseconds += duration; - c->lastcmd->calls++; + /* use the real command that was executed (cmd and lastamc) may be + * different, in case of MULTI-EXEC or re-written commands such as + * EXPIRE, GEOADD, etc. */ + real_cmd->microseconds += duration; + real_cmd->calls++; } /* Propagate the command into the AOF and replication link */ diff --git a/tests/unit/introspection-2.tcl b/tests/unit/introspection-2.tcl index 350a8a01..55f65695 100644 --- a/tests/unit/introspection-2.tcl +++ b/tests/unit/introspection-2.tcl @@ -1,3 +1,9 @@ +proc cmdstat {cmd} { + if {[regexp "\r\ncmdstat_$cmd:(.*?)\r\n" [r info commandstats] _ value]} { + set _ $value + } +} + start_server {tags {"introspection"}} { test {TTL and TYPYE do not alter the last access time of a key} { r set foo bar @@ -20,4 +26,55 @@ start_server {tags {"introspection"}} { r set key2 2 r touch key0 key1 key2 key3 } 2 + + test {command stats for GEOADD} { + r config resetstat + r GEOADD foo 0 0 bar + assert_match {*calls=1,*} [cmdstat geoadd] + assert_match {} [cmdstat zadd] + } + + test {command stats for EXPIRE} { + r config resetstat + r SET foo bar + r EXPIRE foo 0 + assert_match {*calls=1,*} [cmdstat expire] + assert_match {} [cmdstat del] + } + + test {command stats for BRPOP} { + r config resetstat + r LPUSH list foo + r BRPOP list 0 + assert_match {*calls=1,*} [cmdstat brpop] + assert_match {} [cmdstat rpop] + } + + test {command stats for MULTI} { + r config resetstat + r MULTI + r set foo bar + r GEOADD foo2 0 0 bar + r EXPIRE foo2 0 + r EXEC + assert_match {*calls=1,*} [cmdstat multi] + assert_match {*calls=1,*} [cmdstat exec] + assert_match {*calls=1,*} [cmdstat set] + assert_match {*calls=1,*} [cmdstat expire] + assert_match {*calls=1,*} [cmdstat geoadd] + } + + test {command stats for scripts} { + r config resetstat + r set mykey myval + r eval { + redis.call('set', KEYS[1], 0) + redis.call('expire', KEYS[1], 0) + redis.call('geoadd', KEYS[1], 0, 0, "bar") + } 1 mykey + assert_match {*calls=1,*} [cmdstat eval] + assert_match {*calls=2,*} [cmdstat set] + assert_match {*calls=1,*} [cmdstat expire] + assert_match {*calls=1,*} [cmdstat geoadd] + } }