-#include "redis.h"
-#include "slowlog.h"
-
/* Slowlog implements a system that is able to remember the latest N
* queries that took more than M microseconds to execute.
*
* readable and writable using the CONFIG SET/GET command.
*
* The slow queries log is actually not "logged" in the Redis log file
- * but is accessible thanks to the SLOWLOG command. */
+ * but is accessible thanks to the SLOWLOG command.
+ *
+ * ----------------------------------------------------------------------------
+ *
+ * Copyright (c) 2009-2012, Salvatore Sanfilippo <antirez at gmail dot com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Redis nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "redis.h"
+#include "slowlog.h"
/* Create a new slowlog entry.
* Incrementing the ref count of all the objects retained is up to
* 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;
+ se->id = server.slowlog_entry_id++;
return se;
}
* at server startup. */
void slowlogInit(void) {
server.slowlog = listCreate();
+ server.slowlog_entry_id = 0;
listSetFreeMethod(server.slowlog,slowlogFreeEntry);
}
* configured max length. */
void slowlogPushEntryIfNeeded(robj **argv, int argc, long long duration) {
if (server.slowlog_log_slower_than < 0) return; /* Slowlog disabled */
- if (duration > server.slowlog_log_slower_than)
+ if (duration >= server.slowlog_log_slower_than)
listAddNodeHead(server.slowlog,slowlogCreateEntry(argv,argc,duration));
/* Remove old entries if needed. */
int j;
se = ln->value;
- addReplyMultiBulkLen(c,3);
+ addReplyMultiBulkLen(c,4);
+ addReplyLongLong(c,se->id);
addReplyLongLong(c,se->time);
addReplyLongLong(c,se->duration);
addReplyMultiBulkLen(c,se->argc);