diff options
author | dormando <dormando@rydia.net> | 2015-11-25 15:43:01 -0800 |
---|---|---|
committer | dormando <dormando@rydia.net> | 2016-06-08 10:17:55 -0700 |
commit | bb55beb20c3c692a0e77e2ef368d5831318b33d0 (patch) | |
tree | 13b4956706a9b85572544bfa0b35cae21b8c5b8b | |
parent | 1af3c22bba5abfd38b49840c63237a9a59cbbc4e (diff) | |
download | memcached-bb55beb20c3c692a0e77e2ef368d5831318b33d0.tar.gz |
manage logger watcher flags.
very temporary user control. allows to watch either fetchers or evictions, but
not both, and always with timestamps.
-rw-r--r-- | items.c | 2 | ||||
-rw-r--r-- | logger.c | 50 | ||||
-rw-r--r-- | logger.h | 25 | ||||
-rw-r--r-- | memcached.c | 19 | ||||
-rw-r--r-- | thread.c | 2 |
5 files changed, 78 insertions, 20 deletions
@@ -854,7 +854,7 @@ static int lru_pull_tail(const int orig_id, const int cur_lru, if ((search->it_flags & ITEM_FETCHED) == 0) { itemstats[id].evicted_unfetched++; } - if (l->log_evictions) + if (l->f.log_evictions) logger_log(l, LOGGER_EVICTION, search); do_item_unlink_nolock(search, hv); removed++; @@ -204,6 +204,41 @@ static void logger_chunk_release(logger_chunk *lc) { } /* Called with logger stack locked. + * Iterates over every watcher collecting enabled flags. + */ +static void logger_set_flags(void) { + logger *l = NULL; + int x = 0; + struct logger_eflags f; + memset(&f, 0, sizeof(struct logger_eflags)); + + /* Would love to | the fields together, but bitfields have intederminate + * sizing. Could use a union and some startup asserts to sniff out + * platforms where 8 bitfields take more than a uint64_t.. Some research + * is required though. For now an if/else tree will have to do. + */ + for (x = 0; x < WATCHER_LIMIT; x++) { + logger_watcher *w = watchers[x]; + if (w == NULL) + continue; + + if (w->f.log_evictions) + f.log_evictions = 1; + + if (w->f.log_fetchers) + f.log_fetchers = 1; + + if (w->f.log_time) + f.log_time = 1; + } + for (l = logger_stack_head; l != NULL; l=l->next) { + /* lock logger, call function to manipulate it */ + memcpy(&l->f, &f, sizeof(struct logger_eflags)); + } + return; +} + +/* Called with logger stack locked. * Releases every chunk associated with a watcher and closes the connection. * We can't presently send a connection back to the worker for further * processing. @@ -220,6 +255,7 @@ static void logger_close_watcher(logger_watcher *w) { sidethread_conn_close(w->c); watcher_count--; free(w); + logger_set_flags(); } /* Pick any number of "oldest" behind-watchers and kill them. */ @@ -502,11 +538,7 @@ logger *logger_create(void) { return NULL; } - /* FIXME: hardcoded defaults for testing stage */ l->entry_map = default_entries; - //l->log_fetchers = 1; - l->log_evictions = 1; - l->log_time = 1; pthread_mutex_init(&l->mutex, NULL); pthread_setspecific(logger_key, l); @@ -518,8 +550,11 @@ logger *logger_create(void) { #define SET_LOGGER_TIME() \ do { \ - if (l->log_time) { \ + if (l->f.log_time) { \ gettimeofday(&e->tv, NULL); \ + } else { \ + e->tv.tv_sec = 0; \ + e->tv.tv_usec = 0; \ } \ } while (0) @@ -597,7 +632,7 @@ enum logger_ret_type logger_log(logger *l, const enum log_entry_type event, cons * logger thread. Caller *must* event_del() the client before handing it over. * Presently there's no way to hand the client back to the worker thread. */ -enum logger_add_watcher_ret logger_add_watcher(void *c, int sfd) { +enum logger_add_watcher_ret logger_add_watcher(void *c, const int sfd, const struct logger_eflags f) { int x; logger_watcher *w = NULL; pthread_mutex_lock(&logger_stack_lock); @@ -621,6 +656,7 @@ enum logger_add_watcher_ret logger_add_watcher(void *c, int sfd) { w->t = LOGGER_WATCHER_CLIENT; } w->id = x; + memcpy(&w->f, &f, sizeof(struct logger_eflags)); /* Attach to an existing log chunk if there is one */ if (logger_thread_last_lc && !logger_thread_last_lc->filled) { logger_chunk *lc = logger_thread_last_lc; @@ -631,6 +667,8 @@ enum logger_add_watcher_ret logger_add_watcher(void *c, int sfd) { } watchers[x] = w; watcher_count++; + /* Update what flags the global logs will watch */ + logger_set_flags(); pthread_mutex_unlock(&logger_stack_lock); return LOGGER_ADD_WATCHER_OK; @@ -48,15 +48,7 @@ typedef struct _logentry { } data[]; } logentry; -typedef struct _logger { - struct _logger *prev; - struct _logger *next; - pthread_mutex_t mutex; /* guard for this + *buf */ - uint64_t logged; /* entries written to the buffer */ - uint64_t dropped; /* entries dropped */ - uint64_t blocked; /* times blocked instead of dropped */ - uint16_t fetcher_ratio; /* log one out of every N fetches */ - uint16_t mutation_ratio; /* log one out of every N mutations */ +struct logger_eflags { unsigned int log_sysevents :1; /* threads start/stop/working */ unsigned int log_fetchers :1; /* get/gets/etc */ unsigned int log_mutations :1; /* set/append/incr/etc */ @@ -66,6 +58,18 @@ typedef struct _logger { unsigned int log_evictions :1; /* log details of evicted items */ unsigned int log_strict :1; /* block instead of drop */ unsigned int log_time :1; /* log the time the entry is created */ +}; + +typedef struct _logger { + struct _logger *prev; + struct _logger *next; + pthread_mutex_t mutex; /* guard for this + *buf */ + uint64_t logged; /* entries written to the buffer */ + uint64_t dropped; /* entries dropped */ + uint64_t blocked; /* times blocked instead of dropped */ + uint16_t fetcher_ratio; /* log one out of every N fetches */ + uint16_t mutation_ratio; /* log one out of every N mutations */ + struct logger_eflags f; /* flags this logger should log */ bipbuf_t *buf; const entry_details *entry_map; } logger; @@ -92,6 +96,7 @@ typedef struct { int flushed; /* backlog data flushed so far from active chunk */ int id; /* id number for watcher list */ enum logger_watcher_type t; /* stderr, client, syslog, etc */ + struct logger_eflags f; /* flags we are interested in */ } logger_watcher; extern pthread_key_t logger_key; @@ -109,6 +114,6 @@ enum logger_add_watcher_ret { LOGGER_ADD_WATCHER_FAILED }; -enum logger_add_watcher_ret logger_add_watcher(void *c, int sfd); +enum logger_add_watcher_ret logger_add_watcher(void *c, const int sfd, const struct logger_eflags); #endif diff --git a/memcached.c b/memcached.c index 0125075..d4906ca 100644 --- a/memcached.c +++ b/memcached.c @@ -3445,7 +3445,7 @@ static void process_command(conn *c, char *command) { MEMCACHED_PROCESS_COMMAND_START(c->sfd, c->rcurr, c->rbytes); - if (c->thread->l->log_fetchers) + if (c->thread->l->f.log_fetchers) logger_log(c->thread->l, LOGGER_ASCII_CMD, NULL, c->sfd, command); /* @@ -3677,8 +3677,23 @@ static void process_command(conn *c, char *command) { out_string(c, "ERROR"); } } else if (ntokens > 1 && strcmp(tokens[COMMAND_TOKEN].value, "watch") == 0) { + struct logger_eflags f; + memset(&f, 0, sizeof(struct logger_eflags)); /* TODO: pass to function for full argument processing. */ - switch(logger_add_watcher(c, c->sfd)) { + /* This is very temporary... need to decide on a real flag parser. */ + if (ntokens == 3) { + if ((strcmp(tokens[COMMAND_TOKEN + 1].value, "fetchers") == 0)) { + f.log_fetchers = 1; + } else if ((strcmp(tokens[COMMAND_TOKEN + 1].value, "evictions") == 0)) { + f.log_evictions = 1; + } else { + out_string(c, "ERROR"); + } + } else { + f.log_fetchers = 1; + } + f.log_time = 1; /* not optional yet */ + switch(logger_add_watcher(c, c->sfd, f)) { case LOGGER_ADD_WATCHER_TOO_MANY: out_string(c, "WATCHER_TOO_MANY log watcher limit reached"); break; @@ -488,7 +488,7 @@ void redispatch_conn(conn *c) { } LIBEVENT_THREAD *thread = c->thread; item->sfd = sfd; - /* pass in the state somehow? + /* pass in the state somehow? item->init_state = conn_closing; */ item->event_flags = c->event_flags; item->conn = c; |