-
Notifications
You must be signed in to change notification settings - Fork 56
FEATURE: Add cmdlog optional filtering #935
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,6 +25,7 @@ | |
| #include <fcntl.h> | ||
| #include <assert.h> | ||
| #include <errno.h> | ||
| #include <ctype.h> | ||
|
|
||
| #include "memcached/util.h" | ||
|
|
||
|
|
@@ -38,6 +39,10 @@ | |
| #define CMDLOG_FILENAME_LENGTH CMDLOG_DIRPATH_LENGTH + 128 | ||
| #define CMDLOG_FILENAME_FORMAT "%s/command_%d_%d_%d_%d.log" | ||
|
|
||
| #define CMDLOG_FILTER_MAXNUM 10 | ||
| #define CMDLOG_FILTER_CMD_MAXLEN 15 | ||
| #define CMDLOG_FILTER_KEY_MAXLEN 16000 | ||
|
|
||
| /* cmdlog state */ | ||
| #define CMDLOG_NOT_STARTED 0 /* not started */ | ||
| #define CMDLOG_OVERFLOW_STOP 1 /* stop by command log overflow */ | ||
|
|
@@ -59,6 +64,12 @@ struct cmd_log_buffer { | |
| uint32_t last; | ||
| }; | ||
|
|
||
| /* command log filter structure */ | ||
| struct cmd_log_filter { | ||
| char command[CMDLOG_FILTER_CMD_MAXLEN + 1]; | ||
| char key[CMDLOG_FILTER_KEY_MAXLEN + 1]; | ||
| }; | ||
|
|
||
| /*command log flush structure */ | ||
| struct cmd_log_flush { | ||
| pthread_t tid; /* flush thread id */ | ||
|
|
@@ -85,6 +96,8 @@ struct cmd_log_global { | |
| struct cmd_log_buffer buffer; | ||
| struct cmd_log_flush flush; | ||
| struct cmd_log_stats stats; | ||
| struct cmd_log_filter filters[CMDLOG_FILTER_MAXNUM]; | ||
| int nfilters; | ||
| volatile bool reqstop; | ||
| }; | ||
| struct cmd_log_global cmdlog; | ||
|
|
@@ -397,25 +410,42 @@ char *cmdlog_stats(void) | |
| return str; | ||
| } | ||
|
|
||
| void cmdlog_write(char *client_ip, char *command) | ||
| void cmdlog_write(char *client_ip, char *command, int cmdlen) | ||
| { | ||
| struct tm *ptm; | ||
| struct timeval val; | ||
| struct cmd_log_buffer *buffer = &cmdlog.buffer; | ||
| char inputstr[CMDLOG_INPUT_SIZE]; | ||
| char *ptr = command; | ||
| int inputlen; | ||
| int nwritten; | ||
| int seglen; | ||
|
|
||
| gettimeofday(&val, NULL); | ||
| ptm = localtime(&val.tv_sec); | ||
|
|
||
| nwritten = snprintf(inputstr, CMDLOG_INPUT_SIZE, "%02d:%02d:%02d.%06ld %s %s\n", | ||
| ptm->tm_hour, ptm->tm_min, ptm->tm_sec, (long)val.tv_usec, client_ip, command); | ||
| nwritten = snprintf(inputstr, CMDLOG_INPUT_SIZE, "%02d:%02d:%02d.%06ld %s ", | ||
| ptm->tm_hour, ptm->tm_min, ptm->tm_sec, (long)val.tv_usec, client_ip); | ||
|
|
||
| while (ptr < command + cmdlen && nwritten < CMDLOG_INPUT_SIZE) { | ||
| seglen = snprintf(inputstr + nwritten, CMDLOG_INPUT_SIZE - nwritten, "%s", ptr); | ||
| nwritten += seglen; | ||
| ptr += seglen; | ||
|
|
||
| if (ptr < command + cmdlen && nwritten < CMDLOG_INPUT_SIZE) { | ||
| inputstr[nwritten++] = ' '; | ||
| ptr++; | ||
| } | ||
| } | ||
|
|
||
| /* truncated ? */ | ||
| if (nwritten > CMDLOG_INPUT_SIZE) { | ||
| if (nwritten >= CMDLOG_INPUT_SIZE) { | ||
| inputstr[CMDLOG_INPUT_SIZE-4] = '.'; | ||
| inputstr[CMDLOG_INPUT_SIZE-3] = '.'; | ||
| inputstr[CMDLOG_INPUT_SIZE-2] = '\n'; | ||
| } else { | ||
| inputstr[nwritten++] = '\n'; | ||
| inputstr[nwritten] = '\0'; | ||
| } | ||
| inputlen = strlen(inputstr); | ||
|
|
||
|
|
@@ -447,3 +477,152 @@ void cmdlog_write(char *client_ip, char *command) | |
| } | ||
| pthread_mutex_unlock(&buffer->lock); | ||
| } | ||
|
|
||
| static int get_key_idx_by_command(const char *command) | ||
| { | ||
| assert(command); | ||
| int cmdlen = strlen(command); | ||
|
|
||
| if (cmdlen < 3) { | ||
| return -1; | ||
| } | ||
|
|
||
| if ((cmdlen == 3 && memcmp(command, "gat", 3) == 0) || | ||
| (cmdlen == 4 && memcmp(command, "gats", 4) == 0) || | ||
| ((command[0] == 'l' || command[0] == 's' || command[0] == 'm' || command[0] == 'b') && | ||
| strcmp(command + 1, "op") == 0)) { | ||
| if ((cmdlen == 8 && memcmp(command, "bop_mget", 8) == 0) || | ||
| (cmdlen == 9 && memcmp(command, "bop_smget", 9) == 0)) { | ||
| return -1; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. -1 ๋ฆฌํดํ๋ ์ด์ ๋ ๋ฌด์์ธ๊ฐ์?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| } | ||
| return 2; | ||
| } else if ((cmdlen == 3 && memcmp(command, "get", 3) == 0) || | ||
| (cmdlen == 4 && memcmp(command, "gets", 4) == 0) || | ||
| (cmdlen == 3 && memcmp(command, "add", 3) == 0) || | ||
| (cmdlen == 3 && memcmp(command, "set", 3) == 0) || | ||
| (cmdlen == 7 && memcmp(command, "replace", 7) == 0) || | ||
| (cmdlen == 7 && memcmp(command, "prepend", 7) == 0) || | ||
| (cmdlen == 6 && memcmp(command, "append", 6) == 0) || | ||
| (cmdlen == 3 && memcmp(command, "cas", 3) == 0) || | ||
| (cmdlen == 4 && memcmp(command, "incr", 4) == 0) || | ||
| (cmdlen == 4 && memcmp(command, "decr", 4) == 0) || | ||
| (cmdlen == 6 && memcmp(command, "delete", 6) == 0) || | ||
| (cmdlen == 7 && memcmp(command, "getattr", 7) == 0) || | ||
| (cmdlen == 7 && memcmp(command, "setattr", 7) == 0) || | ||
| (cmdlen == 5 && memcmp(command, "touch", 5) == 0)) { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ๊ธฐ์กด์๋ ๋ชจ๋ ๋ช
๋ น์ ๋ก๊น
ํ ์ ์์์ง๋ง,
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ๋ก๊น ๊ฐ๋ฅํฉ๋๋ค. |
||
| return 1; | ||
| } | ||
|
|
||
| return -1; | ||
| } | ||
|
|
||
| bool is_cmdlog_filter_match(token_t *tokens, size_t ntokens) | ||
| { | ||
| char command[CMDLOG_FILTER_CMD_MAXLEN + 1] = ""; | ||
| char *key = ""; | ||
| int key_idx = -1; | ||
| bool matched = false; | ||
|
|
||
| if (cmdlog.nfilters == 0) { | ||
| return true; | ||
| } | ||
|
|
||
| if (ntokens < 2) { | ||
| return false; | ||
| } | ||
|
|
||
| if (ntokens >= 3 && strcmp(tokens[0].value + 1, "op") == 0) { | ||
| snprintf(command, CMDLOG_FILTER_CMD_MAXLEN + 1, "%3s_%s", tokens[0].value, tokens[1].value); | ||
| } else { | ||
| snprintf(command, CMDLOG_FILTER_CMD_MAXLEN + 1, "%s", tokens[0].value); | ||
| } | ||
|
|
||
| key_idx = get_key_idx_by_command(command); | ||
| if ((key_idx == 2 && ntokens >= 4) || (key_idx == 1 && ntokens >= 3)) { | ||
| key = tokens[key_idx].value; | ||
| } | ||
|
|
||
| pthread_mutex_lock(&cmdlog.lock); | ||
| for (int i = 0; i < cmdlog.nfilters; ++i) { | ||
| if (cmdlog.filters[i].command[0] == '\0' || strcmp(command, cmdlog.filters[i].command) == 0) { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. lop ๋ช ๋ น ์ ์ฒด๋ฅผ ๋ก๊น ํ๋ ๊ฒ์ ์ ๋๋์?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. collection type์ ๋ํด ๋ถ๋ถ ๋งค์นญ์ ํ์ฉํ๋ฉด ๋ค๋ฅธ ๋ช ๋ น์ด์ ๋ํด์๋ ๋์ผํ ๋์์ ๊ธฐ๋ํ ๊ฒ ๊ฐ์๋ฐ, ํด๋น ๋ถ๋ถ์ ๊ณ ๋ คํด์ผ ํ ๊ฒ ๊ฐ์ต๋๋ค. |
||
| if (cmdlog.filters[i].key[0] == '\0' || strcmp(key, cmdlog.filters[i].key) == 0) { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. exact match๋ง ํ์ฉ๋๋์?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ๋ค ๋ง์ต๋๋ค |
||
| matched = true; | ||
| break; | ||
| } | ||
| } | ||
| } | ||
| pthread_mutex_unlock(&cmdlog.lock); | ||
| return matched; | ||
| } | ||
|
|
||
| int cmdlog_filter_add(const char *command, int command_len, const char *key, int key_len) | ||
| { | ||
| int success; | ||
|
|
||
| if (command_len > CMDLOG_FILTER_CMD_MAXLEN || key_len > CMDLOG_FILTER_KEY_MAXLEN) { | ||
| return -1; | ||
| } | ||
|
|
||
| if (key_len > 0) { | ||
| for (int i = 0; key[i] != '\0' && i < CMDLOG_FILTER_KEY_MAXLEN; ++i) { | ||
| if (!isgraph(key[i])) { | ||
| return -1; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| success = 0; | ||
| pthread_mutex_lock(&cmdlog.lock); | ||
| if (cmdlog.nfilters < CMDLOG_FILTER_MAXNUM) { | ||
| strcpy(cmdlog.filters[cmdlog.nfilters].command, command); | ||
| strcpy(cmdlog.filters[cmdlog.nfilters].key, key); | ||
| cmdlog.nfilters++; | ||
| success++; | ||
| } | ||
| pthread_mutex_unlock(&cmdlog.lock); | ||
| return success; | ||
| } | ||
|
|
||
| int cmdlog_filter_remove(int idx, bool remove_all) | ||
| { | ||
| int nremove; | ||
|
|
||
| if (remove_all == false && (idx < 0 || idx >= cmdlog.nfilters)) { | ||
| return -1; | ||
| } | ||
|
|
||
| nremove = 0; | ||
| pthread_mutex_lock(&cmdlog.lock); | ||
| if (remove_all) { | ||
| nremove += cmdlog.nfilters; | ||
| cmdlog.nfilters = 0; | ||
| } else { | ||
| for (int i = idx; i < cmdlog.nfilters - 1; ++i) { | ||
| cmdlog.filters[i] = cmdlog.filters[i + 1]; | ||
| } | ||
| cmdlog.nfilters--; | ||
| nremove++; | ||
| } | ||
| pthread_mutex_unlock(&cmdlog.lock); | ||
| return nremove; | ||
| } | ||
|
|
||
| char *cmdlog_filter_list(void) | ||
| { | ||
| char *buf = (char *)malloc((cmdlog.nfilters + 1) * CMDLOG_INPUT_SIZE); | ||
| int nwritten; | ||
|
|
||
| if (!buf) { | ||
| return NULL; | ||
| } | ||
|
|
||
| nwritten = 0; | ||
| pthread_mutex_lock(&cmdlog.lock); | ||
| nwritten = snprintf(buf, CMDLOG_INPUT_SIZE, "\t(%d / %d)\n", cmdlog.nfilters, CMDLOG_FILTER_MAXNUM); | ||
| for (int i = 0; i < cmdlog.nfilters; ++i) { | ||
| nwritten += snprintf(buf + nwritten, CMDLOG_INPUT_SIZE, "\t%d. command = %s, key = %s\n", | ||
| i, cmdlog.filters[i].command, cmdlog.filters[i].key); | ||
| } | ||
| pthread_mutex_unlock(&cmdlog.lock); | ||
| return buf; | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@6unYoung
์ฌ๊ธฐ ์ฝ๋ ์์ ์ ๋ฒ๊ทธ๋ฅผ ์ ๊ฑฐํ๊ธฐ ์ํ ๊ฒ์ธ๊ฐ์?
๊ธฐ์กด ์ฝ๋๋ฅผ ์กฐ๊ธ ์์ ํด์๋ ํด๊ฒฐํ ์ ์์ ๊ฒ ๊ฐ์ ๋ฐ์. ์ด๋ค๊ฐ์?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ํด๋น ์ฝ๋๋
cmdlog_write()ํธ์ถ ์ ์tokenize_command()๋ฅผ ๋จผ์ ํธ์ถํ๊ฒ ์์ ํ๊ธฐ ๋๋ฌธ์ ์ถ๊ฐ๋์์ต๋๋ค. command๊ฐ tokenized๋ ์ํ์ด๋ฏ๋ก ๋ ๋ฌธ์๋ฅผ ๊ฑด๋๋ฐ๋ฉด์ ์ปค๋งจ๋ ๋ผ์ธ ์ ์ฒด๋ฅผ ์ ๋ ฅ๋ฐ๊ฒ ํ์ต๋๋ค.