Create a new slowlog entry. * Incrementing the ref count of all the objects retained is up to * this function. */
| 46 | * Incrementing the ref count of all the objects retained is up to |
| 47 | * this function. */ |
| 48 | slowlogEntry *slowlogCreateEntry(client *c, robj **argv, int argc, long long duration) { |
| 49 | slowlogEntry *se = (slowlogEntry*)zmalloc(sizeof(*se), MALLOC_LOCAL); |
| 50 | int j, slargc = argc; |
| 51 | |
| 52 | if (slargc > SLOWLOG_ENTRY_MAX_ARGC) slargc = SLOWLOG_ENTRY_MAX_ARGC; |
| 53 | se->argc = slargc; |
| 54 | se->argv = (robj**)zmalloc(sizeof(robj*)*slargc, MALLOC_LOCAL); |
| 55 | for (j = 0; j < slargc; j++) { |
| 56 | /* Logging too many arguments is a useless memory waste, so we stop |
| 57 | * at SLOWLOG_ENTRY_MAX_ARGC, but use the last argument to specify |
| 58 | * how many remaining arguments there were in the original command. */ |
| 59 | if (slargc != argc && j == slargc-1) { |
| 60 | se->argv[j] = createObject(OBJ_STRING, |
| 61 | sdscatprintf(sdsempty(),"... (%d more arguments)", |
| 62 | argc-slargc+1)); |
| 63 | } else { |
| 64 | /* Trim too long strings as well... */ |
| 65 | if (argv[j]->type == OBJ_STRING && |
| 66 | sdsEncodedObject(argv[j]) && |
| 67 | sdslen(szFromObj(argv[j])) > SLOWLOG_ENTRY_MAX_STRING) |
| 68 | { |
| 69 | sds s = sdsnewlen(ptrFromObj(argv[j]), SLOWLOG_ENTRY_MAX_STRING); |
| 70 | |
| 71 | s = sdscatprintf(s,"... (%lu more bytes)", |
| 72 | (unsigned long) |
| 73 | sdslen(szFromObj(argv[j])) - SLOWLOG_ENTRY_MAX_STRING); |
| 74 | se->argv[j] = createObject(OBJ_STRING,s); |
| 75 | } else if (argv[j]->getrefcount(std::memory_order_relaxed) == OBJ_SHARED_REFCOUNT) { |
| 76 | se->argv[j] = argv[j]; |
| 77 | } else { |
| 78 | /* Here we need to duplicate the string objects composing the |
| 79 | * argument vector of the command, because those may otherwise |
| 80 | * end shared with string objects stored into keys. Having |
| 81 | * shared objects between any part of Redis, and the data |
| 82 | * structure holding the data, is a problem: FLUSHALL ASYNC |
| 83 | * may release the shared string object and create a race. */ |
| 84 | se->argv[j] = dupStringObject(argv[j]); |
| 85 | } |
| 86 | } |
| 87 | } |
| 88 | se->time = time(NULL); |
| 89 | se->duration = duration; |
| 90 | se->id = g_pserver->slowlog_entry_id++; |
| 91 | se->peerid = sdsnew(getClientPeerId(c)); |
| 92 | se->cname = c->name ? sdsnew(szFromObj(c->name)) : sdsempty(); |
| 93 | return se; |
| 94 | } |
| 95 | |
| 96 | /* Free a slow log entry. The argument is void so that the prototype of this |
| 97 | * function matches the one of the 'free' method of adlist.c. |
no test coverage detected