summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2012-04-21 19:20:03 +0200
committerantirez <antirez@gmail.com>2012-04-21 21:50:25 +0200
commitdf10c797e0827f7feff22f2efdb566edb6606cb1 (patch)
treecfbd9f49fd696e56eb2e9b9654c520fef2141d12
parentf743cacc85ec5b41d4d5c32432e4151e262918e9 (diff)
downloadredis-df10c797e0827f7feff22f2efdb566edb6606cb1.tar.gz
Limit memory used by big SLOWLOG entries.
Two limits are added: 1) Up to SLOWLOG_ENTRY_MAX_ARGV arguments are logged. 2) Up to SLOWLOG_ENTRY_MAX_STRING bytes per argument are logged. 3) slowlog-max-len is set to 128 by default (was 1024). The number of remaining arguments / bytes is logged in the entry so that the user can understand better the nature of the logged command.
-rw-r--r--redis.conf2
-rw-r--r--src/redis.h2
-rw-r--r--src/slowlog.c35
-rw-r--r--src/slowlog.h3
-rw-r--r--tests/unit/slowlog.tcl17
5 files changed, 51 insertions, 8 deletions
diff --git a/redis.conf b/redis.conf
index 58ea6fccc..d407ea23d 100644
--- a/redis.conf
+++ b/redis.conf
@@ -356,7 +356,7 @@ slowlog-log-slower-than 10000
# There is no limit to this length. Just be aware that it will consume memory.
# You can reclaim memory used by the slow log with SLOWLOG RESET.
-slowlog-max-len 1024
+slowlog-max-len 128
################################ VIRTUAL MEMORY ###############################
diff --git a/src/redis.h b/src/redis.h
index 0c3d7b49b..f5e55f3a6 100644
--- a/src/redis.h
+++ b/src/redis.h
@@ -55,7 +55,7 @@
#define REDIS_AUTO_AOFREWRITE_PERC 100
#define REDIS_AUTO_AOFREWRITE_MIN_SIZE (1024*1024)
#define REDIS_SLOWLOG_LOG_SLOWER_THAN 10000
-#define REDIS_SLOWLOG_MAX_LEN 64
+#define REDIS_SLOWLOG_MAX_LEN 128
#define REDIS_REPL_TIMEOUT 60
#define REDIS_REPL_PING_SLAVE_PERIOD 10
diff --git a/src/slowlog.c b/src/slowlog.c
index cfd66dc63..53c44a017 100644
--- a/src/slowlog.c
+++ b/src/slowlog.c
@@ -16,13 +16,36 @@
* this function. */
slowlogEntry *slowlogCreateEntry(robj **argv, int argc, long long duration) {
slowlogEntry *se = zmalloc(sizeof(*se));
- int j;
+ int j, slargc = argc;
+
+ if (slargc > SLOWLOG_ENTRY_MAX_ARGC) slargc = SLOWLOG_ENTRY_MAX_ARGC;
+ se->argc = slargc;
+ se->argv = zmalloc(sizeof(robj*)*slargc);
+ for (j = 0; j < slargc; j++) {
+ /* Logging too many arguments is a useless memory waste, so we stop
+ * at SLOWLOG_ENTRY_MAX_ARGC, but use the last argument to specify
+ * how many remaining arguments there were in the original command. */
+ if (slargc != argc && j == slargc-1) {
+ se->argv[j] = createObject(REDIS_STRING,
+ sdscatprintf(sdsempty(),"... (%d more arguments)",
+ argc-slargc+1));
+ } else {
+ /* Trim too long strings as well... */
+ if (argv[j]->type == REDIS_STRING &&
+ argv[j]->encoding == REDIS_ENCODING_RAW &&
+ sdslen(argv[j]->ptr) > SLOWLOG_ENTRY_MAX_STRING)
+ {
+ sds s = sdsnewlen(argv[j]->ptr, SLOWLOG_ENTRY_MAX_STRING);
- se->argc = argc;
- se->argv = zmalloc(sizeof(robj*)*argc);
- for (j = 0; j < argc; j++) {
- se->argv[j] = argv[j];
- incrRefCount(argv[j]);
+ s = sdscatprintf(s,"... (%lu more bytes)",
+ (unsigned long)
+ sdslen(argv[j]->ptr) - SLOWLOG_ENTRY_MAX_STRING);
+ se->argv[j] = createObject(REDIS_STRING,s);
+ } else {
+ se->argv[j] = argv[j];
+ incrRefCount(argv[j]);
+ }
+ }
}
se->time = time(NULL);
se->duration = duration;
diff --git a/src/slowlog.h b/src/slowlog.h
index bad770db4..bcc961cc9 100644
--- a/src/slowlog.h
+++ b/src/slowlog.h
@@ -1,3 +1,6 @@
+#define SLOWLOG_ENTRY_MAX_ARGC 32
+#define SLOWLOG_ENTRY_MAX_STRING 128
+
/* This structure defines an entry inside the slow log list */
typedef struct slowlogEntry {
robj **argv;
diff --git a/tests/unit/slowlog.tcl b/tests/unit/slowlog.tcl
index 55a71e985..2216e925a 100644
--- a/tests/unit/slowlog.tcl
+++ b/tests/unit/slowlog.tcl
@@ -38,4 +38,21 @@ start_server {tags {"slowlog"} overrides {slowlog-log-slower-than 1000000}} {
assert_equal [expr {[lindex $e 2] > 100000}] 1
assert_equal [lindex $e 3] {debug sleep 0.2}
}
+
+ 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)}}
}