]> git.saurik.com Git - redis.git/blobdiff - src/slowlog.c
Fix overflow in mstime() in redis-cli and benchmark.
[redis.git] / src / slowlog.c
index cfd66dc634d45dbc12bc9e1980fac40164374f25..fdc18e579dd2b2d3fe4cbe939fa90bc5a8393fbc 100644 (file)
@@ -1,6 +1,3 @@
-#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.
  *
@@ -9,20 +6,77 @@
  * 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;