174 |
174 |
175 sbuf_append(ui_buffer, s); |
175 sbuf_append(ui_buffer, s); |
176 sbuf_put(ui_buffer, '\n'); |
176 sbuf_put(ui_buffer, '\n'); |
177 } |
177 } |
178 |
178 |
179 void log_file_writeln(char *str, size_t len) { |
179 void log_file_writeln(char *str, size_t len) { |
180 if(!is_initialized) { |
|
181 log_uninitialized_writeln(str, len); |
|
182 return; |
|
183 } |
|
184 |
|
185 struct iovec io[] = { |
180 struct iovec io[] = { |
186 { str, len }, |
181 { str, len }, |
187 { "\n", 1} |
182 { "\n", 1} |
188 }; |
183 }; |
189 |
184 |
190 writev(log_file_fd, io, 2); /* TODO: aio? */ |
185 WSBool write_to_stdout = !main_is_daemon(); |
191 if(!main_is_daemon()) { |
186 if(is_initialized) { |
|
187 writev(log_file_fd, io, 2); /* TODO: aio? */ |
|
188 } else { |
|
189 write_to_stdout = TRUE; |
|
190 log_uninitialized_writeln(str, len); |
|
191 } |
|
192 |
|
193 if(write_to_stdout) { |
192 writev(STDOUT_FILENO, io, 2); |
194 writev(STDOUT_FILENO, io, 2); |
193 } |
195 } |
194 |
196 |
195 if(log_dup_count > 0) { |
197 if(log_dup_count > 0) { |
196 char *msg = malloc(len + 1); |
198 char *msg = malloc(len + 1); |
227 log_date_month[date.tm_mon], |
229 log_date_month[date.tm_mon], |
228 1900 + date.tm_year, |
230 1900 + date.tm_year, |
229 date.tm_hour, |
231 date.tm_hour, |
230 date.tm_min, |
232 date.tm_min, |
231 date.tm_sec, |
233 date.tm_sec, |
232 log_levels[level]); |
234 level); |
233 |
235 |
234 if(len > 0) { |
236 if(len > 0) { |
235 d.ptr = buf; |
237 d.ptr = buf; |
236 d.length = len; |
238 d.length = len; |
237 } |
239 } |
238 |
240 |
239 return d; |
241 return d; |
|
242 } |
|
243 |
|
244 cxmutstr log_get_prefix(int level) { |
|
245 return log_get_prefix_str(log_levels[level]); |
240 } |
246 } |
241 |
247 |
242 void log_add_logdup(LogDup *dup) { |
248 void log_add_logdup(LogDup *dup) { |
243 pthread_mutex_lock(&mutex); |
249 pthread_mutex_lock(&mutex); |
244 cxListAdd(log_dup_list, dup); |
250 cxListAdd(log_dup_list, dup); |
321 { |
327 { |
322 // TODO: implement |
328 // TODO: implement |
323 return log_ereport(degree, format, args); |
329 return log_ereport(degree, format, args); |
324 } |
330 } |
325 |
331 |
|
332 int log_message(const char *degree, const char *format, ...) { |
|
333 va_list args; |
|
334 va_start(args, format); |
|
335 int ret = log_message_v(degree, format, args); |
|
336 va_end(args); |
|
337 return ret; |
|
338 } |
|
339 |
|
340 int log_message_v(const char *degree, const char *format, va_list args) { |
|
341 cxmutstr lmsg; |
|
342 lmsg.ptr = NULL; |
|
343 |
|
344 cxmutstr lpre = log_get_prefix_str(degree); |
|
345 |
|
346 /* format message */ |
|
347 int len = vasprintf(&lmsg.ptr, format, args); |
|
348 lmsg.length = len; |
|
349 |
|
350 /* create message string */ |
|
351 cxmutstr message = cx_strcat(2, lpre, lmsg); |
|
352 |
|
353 /* write message to the log file */ |
|
354 log_file_writeln(message.ptr, message.length); |
|
355 |
|
356 /* cleanup */ |
|
357 free(lmsg.ptr); |
|
358 free(lpre.ptr); |
|
359 free(message.ptr); |
|
360 |
|
361 return 0; |
|
362 } |
|
363 |
326 |
364 |
327 void ws_log_assert(const char *file, const char *func, int line) { |
365 void ws_log_assert(const char *file, const char *func, int line) { |
328 log_ereport( |
366 log_ereport( |
329 LOG_CATASTROPHE, |
367 LOG_CATASTROPHE, |
330 "assertion failed: %s: %s:%d", |
368 "assertion failed: %s: %s:%d", |