关键词搜索

源码搜索 ×
×

漫话Redis源码之十五

发布2021-11-28浏览464次

详情内容

创建慢日志项,主要跟log相关:

  1. #include "server.h"
  2. #include "slowlog.h"
  3. /* Create a new slowlog entry.
  4. * Incrementing the ref count of all the objects retained is up to
  5. * this function. */
  6. slowlogEntry *slowlogCreateEntry(client *c, robj **argv, int argc, long long duration) {
  7. slowlogEntry *se = zmalloc(sizeof(*se));
  8. int j, slargc = argc;
  9. if (slargc > SLOWLOG_ENTRY_MAX_ARGC) slargc = SLOWLOG_ENTRY_MAX_ARGC;
  10. se->argc = slargc;
  11. se->argv = zmalloc(sizeof(robj*)*slargc);
  12. for (j = 0; j < slargc; j++) {
  13. /* Logging too many arguments is a useless memory waste, so we stop
  14. * at SLOWLOG_ENTRY_MAX_ARGC, but use the last argument to specify
  15. * how many remaining arguments there were in the original command. */
  16. if (slargc != argc && j == slargc-1) {
  17. se->argv[j] = createObject(OBJ_STRING,
  18. sdscatprintf(sdsempty(),"... (%d more arguments)",
  19. argc-slargc+1));
  20. } else {
  21. /* Trim too long strings as well... */
  22. if (argv[j]->type == OBJ_STRING &&
  23. sdsEncodedObject(argv[j]) &&
  24. sdslen(argv[j]->ptr) > SLOWLOG_ENTRY_MAX_STRING)
  25. {
  26. sds s = sdsnewlen(argv[j]->ptr, SLOWLOG_ENTRY_MAX_STRING);
  27. s = sdscatprintf(s,"... (%lu more bytes)",
  28. (unsigned long)
  29. sdslen(argv[j]->ptr) - SLOWLOG_ENTRY_MAX_STRING);
  30. se->argv[j] = createObject(OBJ_STRING,s);
  31. } else if (argv[j]->refcount == OBJ_SHARED_REFCOUNT) {
  32. se->argv[j] = argv[j];
  33. } else {
  34. /* Here we need to duplicate the string objects composing the
  35. * argument vector of the command, because those may otherwise
  36. * end shared with string objects stored into keys. Having
  37. * shared objects between any part of Redis, and the data
  38. * structure holding the data, is a problem: FLUSHALL ASYNC
  39. * may release the shared string object and create a race. */
  40. se->argv[j] = dupStringObject(argv[j]);
  41. }
  42. }
  43. }
  44. se->time = time(NULL);
  45. se->duration = duration;
  46. se->id = server.slowlog_entry_id++;
  47. se->peerid = sdsnew(getClientPeerId(c));
  48. se->cname = c->name ? sdsnew(c->name->ptr) : sdsempty();
  49. return se;
  50. }
  51. /* Free a slow log entry. The argument is void so that the prototype of this
  52. * function matches the one of the 'free' method of adlist.c.
  53. *
  54. * This function will take care to release all the retained object. */
  55. void slowlogFreeEntry(void *septr) {
  56. slowlogEntry *se = septr;
  57. int j;
  58. for (j = 0; j < se->argc; j++)
  59. decrRefCount(se->argv[j]);
  60. zfree(se->argv);
  61. sdsfree(se->peerid);
  62. sdsfree(se->cname);
  63. zfree(se);
  64. }
  65. /* Initialize the slow log. This function should be called a single time
  66. * at server startup. */
  67. void slowlogInit(void) {
  68. server.slowlog = listCreate();
  69. server.slowlog_entry_id = 0;
  70. listSetFreeMethod(server.slowlog,slowlogFreeEntry);
  71. }
  72. /* Push a new entry into the slow log.
  73. * This function will make sure to trim the slow log accordingly to the
  74. * configured max length. */
  75. void slowlogPushEntryIfNeeded(client *c, robj **argv, int argc, long long duration) {
  76. if (server.slowlog_log_slower_than < 0) return; /* Slowlog disabled */
  77. if (duration >= server.slowlog_log_slower_than)
  78. listAddNodeHead(server.slowlog,
  79. slowlogCreateEntry(c,argv,argc,duration));
  80. /* Remove old entries if needed. */
  81. while (listLength(server.slowlog) > server.slowlog_max_len)
  82. listDelNode(server.slowlog,listLast(server.slowlog));
  83. }
  84. /* Remove all the entries from the current slow log. */
  85. void slowlogReset(void) {
  86. while (listLength(server.slowlog) > 0)
  87. listDelNode(server.slowlog,listLast(server.slowlog));
  88. }
  89. /* The SLOWLOG command. Implements all the subcommands needed to handle the
  90. * Redis slow log. */
  91. void slowlogCommand(client *c) {
  92. if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"help")) {
  93. const char *help[] = {
  94. "GET [<count>]",
  95. " Return top <count> entries from the slowlog (default: 10). Entries are",
  96. " made of:",
  97. " id, timestamp, time in microseconds, arguments array, client IP and port,",
  98. " client name",
  99. "LEN",
  100. " Return the length of the slowlog.",
  101. "RESET",
  102. " Reset the slowlog.",
  103. NULL
  104. };
  105. addReplyHelp(c, help);
  106. } else if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"reset")) {
  107. slowlogReset();
  108. addReply(c,shared.ok);
  109. } else if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"len")) {
  110. addReplyLongLong(c,listLength(server.slowlog));
  111. } else if ((c->argc == 2 || c->argc == 3) &&
  112. !strcasecmp(c->argv[1]->ptr,"get"))
  113. {
  114. long count = 10, sent = 0;
  115. listIter li;
  116. void *totentries;
  117. listNode *ln;
  118. slowlogEntry *se;
  119. if (c->argc == 3 &&
  120. getLongFromObjectOrReply(c,c->argv[2],&count,NULL) != C_OK)
  121. return;
  122. listRewind(server.slowlog,&li);
  123. totentries = addReplyDeferredLen(c);
  124. while(count-- && (ln = listNext(&li))) {
  125. int j;
  126. se = ln->value;
  127. addReplyArrayLen(c,6);
  128. addReplyLongLong(c,se->id);
  129. addReplyLongLong(c,se->time);
  130. addReplyLongLong(c,se->duration);
  131. addReplyArrayLen(c,se->argc);
  132. for (j = 0; j < se->argc; j++)
  133. addReplyBulk(c,se->argv[j]);
  134. addReplyBulkCBuffer(c,se->peerid,sdslen(se->peerid));
  135. addReplyBulkCBuffer(c,se->cname,sdslen(se->cname));
  136. sent++;
  137. }
  138. setDeferredArrayLen(c,totentries,sent);
  139. } else {
  140. addReplySubcommandSyntaxError(c);
  141. }
  142. }

相关技术文章

点击QQ咨询
开通会员
返回顶部
×
微信扫码支付
微信扫码支付
确定支付下载
请使用微信描二维码支付
×

提示信息

×

选择支付方式

  • 微信支付
  • 支付宝付款
确定支付下载