1 /* logging functions */ 2 #ifndef LOGGER_H 3 #define LOGGER_H 4 5 #include "bipbuffer.h" 6 7 /* TODO: starttime tunable */ 8 #define LOGGER_BUF_SIZE 1024 * 64 9 #define LOGGER_WATCHER_BUF_SIZE 1024 * 256 10 #define LOGGER_ENTRY_MAX_SIZE 2048 11 #define GET_LOGGER() ((logger *) pthread_getspecific(logger_key)); 12 13 /* Inlined from memcached.h - should go into sub header */ 14 typedef unsigned int rel_time_t; 15 16 enum log_entry_type { 17 LOGGER_ASCII_CMD = 0, 18 LOGGER_EVICTION, 19 LOGGER_ITEM_GET, 20 LOGGER_ITEM_STORE, 21 LOGGER_CRAWLER_STATUS, 22 LOGGER_SLAB_MOVE, 23 LOGGER_CONNECTION_NEW, 24 LOGGER_CONNECTION_CLOSE, 25 LOGGER_CONNECTION_ERROR, 26 LOGGER_CONNECTION_TLSERROR, 27 LOGGER_DELETIONS, 28 #ifdef EXTSTORE 29 LOGGER_EXTSTORE_WRITE, 30 LOGGER_COMPACT_START, 31 LOGGER_COMPACT_ABORT, 32 LOGGER_COMPACT_READ_START, 33 LOGGER_COMPACT_READ_END, 34 LOGGER_COMPACT_END, 35 LOGGER_COMPACT_FRAGINFO, 36 #endif 37 #ifdef PROXY 38 LOGGER_PROXY_CONFIG, 39 LOGGER_PROXY_RAW, 40 LOGGER_PROXY_ERROR, 41 LOGGER_PROXY_USER, 42 LOGGER_PROXY_REQ, 43 LOGGER_PROXY_BE_ERROR, 44 #endif 45 }; 46 47 enum logger_ret_type { 48 LOGGER_RET_OK = 0, 49 LOGGER_RET_NOSPACE, 50 LOGGER_RET_ERR 51 }; 52 53 enum logger_parse_entry_ret { 54 LOGGER_PARSE_ENTRY_OK = 0, 55 LOGGER_PARSE_ENTRY_FULLBUF, 56 LOGGER_PARSE_ENTRY_FAILED 57 }; 58 59 typedef struct _logentry logentry; 60 typedef struct _entry_details entry_details; 61 62 typedef void (*entry_log_cb)(logentry *e, const entry_details *d, const void *entry, va_list ap); 63 typedef int (*entry_parse_cb)(logentry *e, char *scratch); 64 65 struct _entry_details { 66 int reqlen; 67 uint16_t eflags; 68 entry_log_cb log_cb; 69 entry_parse_cb parse_cb; 70 char *format; 71 }; 72 73 /* log entry intermediary structures */ 74 struct logentry_eviction { 75 long long int exptime; 76 int nbytes; 77 uint32_t latime; 78 uint16_t it_flags; 79 uint8_t nkey; 80 uint8_t clsid; 81 char key[]; 82 }; 83 #ifdef EXTSTORE 84 struct logentry_ext_write { 85 long long int exptime; 86 uint32_t latime; 87 uint16_t it_flags; 88 uint8_t nkey; 89 uint8_t clsid; 90 uint8_t bucket; 91 char key[]; 92 }; 93 #endif 94 struct logentry_item_get { 95 uint8_t was_found; 96 uint8_t nkey; 97 uint8_t clsid; 98 int nbytes; 99 int sfd; 100 char key[]; 101 }; 102 103 struct logentry_item_store { 104 int status; 105 int cmd; 106 rel_time_t ttl; 107 uint8_t nkey; 108 uint8_t clsid; 109 int nbytes; 110 int sfd; 111 char key[]; 112 }; 113 114 struct logentry_deletion { 115 int nbytes; 116 int cmd; 117 uint8_t nkey; 118 uint8_t clsid; 119 char key[]; 120 }; 121 122 struct logentry_conn_event { 123 int transport; 124 int reason; 125 int sfd; 126 struct sockaddr_in6 addr; 127 }; 128 #ifdef PROXY 129 struct logentry_proxy_req { 130 unsigned short type; 131 unsigned short code; 132 int status; 133 int conn_fd; 134 uint32_t reqlen; 135 size_t dlen; 136 size_t be_namelen; 137 size_t be_portlen; 138 long elapsed; 139 char data[]; 140 }; 141 142 struct logentry_proxy_errbe { 143 size_t errlen; 144 size_t be_namelen; 145 size_t be_portlen; 146 size_t be_labellen; 147 size_t be_rbuflen; 148 int be_depth; 149 int retry; 150 char data[]; 151 }; 152 #endif 153 /* end intermediary structures */ 154 155 /* WARNING: cuddled items aren't compatible with warm restart. more code 156 * necessary to ensure log streams are all flushed/processed before stopping 157 */ 158 struct _logentry { 159 enum log_entry_type event; 160 uint8_t pad; 161 uint16_t eflags; 162 uint64_t gid; 163 struct timeval tv; /* not monotonic! */ 164 int size; 165 union { 166 char end; 167 } data[]; 168 }; 169 170 #define LOG_SYSEVENTS (1<<1) /* threads start/stop/working */ 171 #define LOG_FETCHERS (1<<2) /* get/gets/etc */ 172 #define LOG_MUTATIONS (1<<3) /* set/append/incr/etc */ 173 #define LOG_SYSERRORS (1<<4) /* malloc/etc errors */ 174 #define LOG_CONNEVENTS (1<<5) /* new client, closed, etc */ 175 #define LOG_EVICTIONS (1<<6) /* details of evicted items */ 176 #define LOG_STRICT (1<<7) /* block worker instead of drop */ 177 #define LOG_RAWCMDS (1<<9) /* raw ascii commands */ 178 #define LOG_PROXYREQS (1<<10) /* command logs from proxy */ 179 #define LOG_PROXYEVENTS (1<<11) /* error log stream from proxy */ 180 #define LOG_PROXYUSER (1<<12) /* user generated logs from proxy */ 181 #define LOG_DELETIONS (1<<13) /* see whats deleted */ 182 183 typedef struct _logger { 184 struct _logger *prev; 185 struct _logger *next; 186 pthread_mutex_t mutex; /* guard for this + *buf */ 187 uint64_t written; /* entries written to the buffer */ 188 uint64_t dropped; /* entries dropped */ 189 uint64_t blocked; /* times blocked instead of dropped */ 190 uint16_t fetcher_ratio; /* log one out of every N fetches */ 191 uint16_t mutation_ratio; /* log one out of every N mutations */ 192 uint16_t eflags; /* flags this logger should log */ 193 bipbuf_t *buf; 194 const entry_details *entry_map; 195 } logger; 196 197 enum logger_watcher_type { 198 LOGGER_WATCHER_STDERR = 0, 199 LOGGER_WATCHER_CLIENT = 1 200 }; 201 202 typedef struct { 203 void *c; /* original connection structure. still with source thread attached */ 204 int sfd; /* client fd */ 205 int id; /* id number for watcher list */ 206 uint64_t skipped; /* lines skipped since last successful print */ 207 uint64_t min_gid; /* don't show log entries older than this GID */ 208 bool failed_flush; /* recently failed to write out (EAGAIN), wait before retry */ 209 enum logger_watcher_type t; /* stderr, client, syslog, etc */ 210 uint16_t eflags; /* flags we are interested in */ 211 bipbuf_t *buf; /* per-watcher output buffer */ 212 } logger_watcher; 213 214 215 struct logger_stats { 216 uint64_t worker_dropped; 217 uint64_t worker_written; 218 uint64_t watcher_skipped; 219 uint64_t watcher_sent; 220 uint64_t watcher_count; 221 }; 222 223 extern pthread_key_t logger_key; 224 225 /* public functions */ 226 227 void logger_init(void); 228 void logger_stop(void); 229 logger *logger_create(void); 230 231 #define LOGGER_LOG(l, flag, type, ...) \ 232 do { \ 233 logger *myl = l; \ 234 if (l == NULL) \ 235 myl = GET_LOGGER(); \ 236 if (myl->eflags & flag) \ 237 logger_log(myl, type, __VA_ARGS__); \ 238 } while (0) 239 240 enum logger_ret_type logger_log(logger *l, const enum log_entry_type event, const void *entry, ...); 241 242 enum logger_add_watcher_ret { 243 LOGGER_ADD_WATCHER_TOO_MANY = 0, 244 LOGGER_ADD_WATCHER_OK, 245 LOGGER_ADD_WATCHER_FAILED 246 }; 247 248 enum logger_add_watcher_ret logger_add_watcher(void *c, const int sfd, uint16_t f); 249 250 /* functions used by restart system */ 251 uint64_t logger_get_gid(void); 252 void logger_set_gid(uint64_t gid); 253 254 #endif 255