src/server/daemon/log.c

changeset 415
d938228c382e
parent 392
0aef555055ee
child 434
ff576305ae6e
equal deleted inserted replaced
414:99a34860c105 415:d938228c382e
41 #include "log.h" 41 #include "log.h"
42 #include "../util/strbuf.h" 42 #include "../util/strbuf.h"
43 #include "../util/io.h" 43 #include "../util/io.h"
44 #include "../util/atomic.h" 44 #include "../util/atomic.h"
45 45
46 #include <ucx/map.h> 46 #include <cx/hash_map.h>
47 #include <ucx/list.h> 47 #include <cx/linked_list.h>
48 #include <cx/compare.h>
48 49
49 static int is_initialized = 0; 50 static int is_initialized = 0;
50 51
51 static int log_file_fd; 52 static int log_file_fd;
52 static int log_level = 0; 53 static int log_level = 0;
53 54
54 static uint32_t log_dup_count = 0; 55 static uint32_t log_dup_count = 0;
55 static UcxList *log_dup_list = NULL; 56 static CxList *log_dup_list = NULL;
56 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 57 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
57 58
58 WSBool main_is_daemon(void); 59 WSBool main_is_daemon(void);
59 60
60 /* 61 /*
63 static sbuf_t *ui_buffer = NULL; 64 static sbuf_t *ui_buffer = NULL;
64 65
65 /* 66 /*
66 * access log file map 67 * access log file map
67 */ 68 */
68 static UcxMap *access_log_files; // map of LogFile* 69 static CxMap *access_log_files; // map of LogFile*
69 70
70 71
71 static char *log_date_month[] = { 72 static char *log_date_month[] = {
72 "Jan", 73 "Jan",
73 "Feb", 74 "Feb",
108 int init_log_file(LogConfig *cfg) { 109 int init_log_file(LogConfig *cfg) {
109 if(is_initialized) { 110 if(is_initialized) {
110 return 0; 111 return 0;
111 } 112 }
112 113
114 log_dup_list = cxPointerLinkedListCreate(cxDefaultAllocator, cx_cmp_ptr);
115
113 /* open the log file */ 116 /* open the log file */
114 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; 117 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
115 log_file_fd = open(cfg->file, O_WRONLY | O_CREAT | O_APPEND, mode); 118 log_file_fd = open(cfg->file, O_WRONLY | O_CREAT | O_APPEND, mode);
116 if(log_file_fd == -1) { 119 if(log_file_fd == -1) {
117 log_ereport(LOG_FAILURE, "Cannot open log file %s: %s", cfg->file, strerror(errno)); 120 log_ereport(LOG_FAILURE, "Cannot open log file %s: %s", cfg->file, strerror(errno));
163 if(ui_buffer == NULL) { 166 if(ui_buffer == NULL) {
164 return; /* TODO: critical error, exit */ 167 return; /* TODO: critical error, exit */
165 } 168 }
166 } 169 }
167 170
168 sstr_t s; 171 cxstring s;
169 s.ptr = str; 172 s.ptr = str;
170 s.length = len; 173 s.length = len;
171 174
172 sbuf_append(ui_buffer, s); 175 sbuf_append(ui_buffer, s);
173 sbuf_put(ui_buffer, '\n'); 176 sbuf_put(ui_buffer, '\n');
193 char *msg = malloc(len + 1); 196 char *msg = malloc(len + 1);
194 memcpy(msg, str, len); 197 memcpy(msg, str, len);
195 msg[len] = '\n'; 198 msg[len] = '\n';
196 199
197 pthread_mutex_lock(&mutex); 200 pthread_mutex_lock(&mutex);
198 UCX_FOREACH(elm, log_dup_list) { 201 CxIterator i = cxListIterator(log_dup_list, 0);
199 LogDup *dup = elm->data; 202 cx_foreach(LogDup *, dup, i) {
200 dup->write(dup->cookie, msg, len + 1); 203 dup->write(dup->cookie, msg, len + 1);
201 } 204 }
202 pthread_mutex_unlock(&mutex); 205 pthread_mutex_unlock(&mutex);
203 206
204 free(msg); 207 free(msg);
205 } 208 }
206 } 209 }
207 210
208 sstr_t log_get_prefix(int level) { 211 cxmutstr log_get_prefix(int level) {
209 time_t t = time(NULL); 212 time_t t = time(NULL);
210 213
211 sstr_t d; 214 cxmutstr d;
212 d.ptr = NULL; 215 d.ptr = NULL;
213 d.length = 0; 216 d.length = 0;
214 217
215 struct tm date; 218 struct tm date;
216 localtime_r(&t, &date); 219 localtime_r(&t, &date);
236 return d; 239 return d;
237 } 240 }
238 241
239 void log_add_logdup(LogDup *dup) { 242 void log_add_logdup(LogDup *dup) {
240 pthread_mutex_lock(&mutex); 243 pthread_mutex_lock(&mutex);
241 log_dup_list = ucx_list_append(log_dup_list, dup); 244 cxListAdd(log_dup_list, dup);
242 ws_atomic_inc32(&log_dup_count); 245 ws_atomic_inc32(&log_dup_count);
243 pthread_mutex_unlock(&mutex); 246 pthread_mutex_unlock(&mutex);
244 } 247 }
245 248
246 void log_remove_logdup(LogDup *ldup) { 249 void log_remove_logdup(LogDup *ldup) {
247 pthread_mutex_lock(&mutex); 250 pthread_mutex_lock(&mutex);
248 UcxList *elm = log_dup_list; 251 CxIterator i = cxListIterator(log_dup_list, 0);
249 while(elm) { 252 WSBool finished = 0;
250 if(elm->data == ldup) { 253 cx_foreach(LogDup *, dup, i) {
251 log_dup_list = ucx_list_remove(log_dup_list, elm); 254 if(finished) break;
255 if(dup == ldup) {
256 i.remove = 1;
257 finished = 1;
252 ws_atomic_dec32(&log_dup_count); 258 ws_atomic_dec32(&log_dup_count);
253 break;
254 } 259 }
255 elm = elm->next;
256 } 260 }
257 pthread_mutex_unlock(&mutex); 261 pthread_mutex_unlock(&mutex);
258 } 262 }
259 263
260 264
276 } 280 }
277 if(!can_log[degree]) { 281 if(!can_log[degree]) {
278 return 0; 282 return 0;
279 } 283 }
280 284
281 sstr_t lmsg; 285 cxmutstr lmsg;
282 lmsg.ptr = NULL; 286 lmsg.ptr = NULL;
283 287
284 /* create log message prefix */ 288 /* create log message prefix */
285 sstr_t lpre = log_get_prefix(degree); 289 cxmutstr lpre = log_get_prefix(degree);
286 290
287 /* format message */ 291 /* format message */
288 int len = vasprintf(&lmsg.ptr, format, args); 292 int len = vasprintf(&lmsg.ptr, format, args);
289 lmsg.length = len; 293 lmsg.length = len;
290 294
291 /* create message string */ 295 /* create message string */
292 sstr_t message = sstrcat(2, lpre, lmsg); 296 cxmutstr message = cx_strcat(2, lpre, lmsg);
293 297
294 /* write message to the log file */ 298 /* write message to the log file */
295 log_file_writeln(message.ptr, message.length); 299 log_file_writeln(message.ptr, message.length);
296 300
297 /* cleanup */ 301 /* cleanup */
334 /* 338 /*
335 * access log 339 * access log
336 * This source file only manages access log files. IO is performed directly 340 * This source file only manages access log files. IO is performed directly
337 * by AddLog safs. 341 * by AddLog safs.
338 */ 342 */
339 LogFile* get_access_log_file(scstr_t file) { 343 LogFile* get_access_log_file(cxstring file) {
340 // TODO: this looks dubious 344 // TODO: this looks dubious
341 345
342 if(!access_log_files) { 346 if(!access_log_files) {
343 access_log_files = ucx_map_new(4); 347 access_log_files = cxHashMapCreate(cxDefaultAllocator, 4);
344 } 348 }
345 349
346 if(file.ptr == NULL || file.length == 0) { 350 if(file.ptr == NULL || file.length == 0) {
347 return NULL; 351 return NULL;
348 } 352 }
349 353
350 LogFile *log = ucx_map_sstr_get(access_log_files, file); 354 CxHashKey key = cx_hash_key_bytes((unsigned const char*)file.ptr, file.length);
355 LogFile *log = cxMapGet(access_log_files, key);
351 if(log != NULL) { 356 if(log != NULL) {
352 ws_atomic_inc32(&log->ref); 357 ws_atomic_inc32(&log->ref);
353 return log; 358 return log;
354 } 359 }
355 360
364 log = calloc(1, sizeof(LogFile)); 369 log = calloc(1, sizeof(LogFile));
365 log->file = out; 370 log->file = out;
366 log->ref = 1; 371 log->ref = 1;
367 372
368 // add access log to the map 373 // add access log to the map
369 ucx_map_sstr_put(access_log_files, file, log); 374 cxMapPut(access_log_files, key, log);
370 375
371 return log; 376 return log;
372 } 377 }
373 378

mercurial