46 #include <qb/qbdefs.h>
47 #include <qb/qbutil.h>
65 {
"alert", LOG_ALERT },
67 {
"debug", LOG_DEBUG },
68 {
"emerg", LOG_EMERG },
72 {
"notice", LOG_NOTICE },
73 {
"warning", LOG_WARNING },
77 #define MAX_FILES_PER_SUBSYS 32
78 #ifdef HAVE_SMALL_MEMORY_FOOTPRINT
79 #define IPC_LOGSYS_SIZE 8192*64
81 #define IPC_LOGSYS_SIZE 8192*1024
103 #define LOGSYS_LOGGER_INIT_DONE 0
104 #define LOGSYS_LOGGER_NEEDS_INIT 1
110 static pthread_mutex_t logsys_config_mutex = PTHREAD_MUTEX_INITIALIZER;
112 static int32_t _logsys_config_mode_set_unlocked(int32_t subsysid, uint32_t new_mode);
113 static void _logsys_config_apply_per_file(int32_t s,
const char *filename);
114 static void _logsys_config_apply_per_subsys(int32_t s);
115 static void _logsys_subsys_filename_add (int32_t s,
const char *filename);
116 static void logsys_file_format_get(
char* file_format,
int buf_len);
118 static char *format_buffer=NULL;
120 static int logsys_thread_started = 0;
122 static int logsys_blackbox_enabled = 1;
124 static int _logsys_config_subsys_get_unlocked (
const char *
subsys)
133 if (strcmp (logsys_loggers[i].subsys, subsys) == 0) {
146 static int logsys_config_file_set_unlocked (
148 const char **error_string,
151 static char error_string_response[512];
153 char file_format[128];
155 if (logsys_loggers[subsysid].
target_id > 0) {
157 for (f = 0; f < logsys_loggers[subsysid].
file_idx; f++) {
158 qb_log_filter_ctl(logsys_loggers[subsysid].
target_id,
159 QB_LOG_FILTER_REMOVE,
161 logsys_loggers[subsysid].
files[f],
166 logsys_loggers[subsysid].
dirty = QB_TRUE;
171 if (logsys_loggers[subsysid].
target_id > 0 &&
172 logsys_loggers[subsysid].
logfile != NULL &&
173 strcmp(file, logsys_loggers[subsysid].
logfile) == 0) {
177 if (strlen(file) >= PATH_MAX) {
178 snprintf (error_string_response,
179 sizeof(error_string_response),
180 "%s: logfile name exceed maximum system filename length",
181 logsys_loggers[subsysid].subsys);
182 *error_string = error_string_response;
186 if (logsys_loggers[subsysid].logfile != NULL) {
187 free(logsys_loggers[subsysid].logfile);
188 logsys_loggers[subsysid].
logfile = NULL;
191 logsys_loggers[subsysid].
logfile = strdup(file);
193 if (logsys_loggers[subsysid].logfile == NULL) {
194 snprintf (error_string_response,
195 sizeof(error_string_response),
196 "Unable to allocate memory for logfile '%s'",
198 *error_string = error_string_response;
203 if ((logsys_loggers[i].logfile != NULL) &&
204 (strcmp (logsys_loggers[i].logfile, file) == 0) &&
214 if (logsys_loggers[subsysid].
target_id > 0) {
215 int num_using_current = 0;
217 if (logsys_loggers[subsysid].
target_id ==
222 if (num_using_current == 1) {
224 qb_log_file_close(logsys_loggers[subsysid].
target_id);
228 logsys_loggers[subsysid].
target_id = qb_log_file_open(file);
229 if (logsys_loggers[subsysid].
target_id < 0) {
230 int err = -logsys_loggers[subsysid].
target_id;
232 const char *error_ptr;
233 error_ptr = qb_strerror_r(err, error_str,
sizeof(error_str));
235 free(logsys_loggers[subsysid].logfile);
236 logsys_loggers[subsysid].
logfile = NULL;
237 snprintf (error_string_response,
238 sizeof(error_string_response),
239 "Can't open logfile '%s' for reason: %s (%d)",
240 file, error_ptr, err);
241 *error_string = error_string_response;
244 logsys_file_format_get(file_format, 128);
245 qb_log_format_set(logsys_loggers[subsysid].
target_id, file_format);
247 qb_log_ctl(logsys_loggers[subsysid].
target_id,
250 if (logsys_thread_started) {
251 qb_log_ctl(logsys_loggers[subsysid].target_id, QB_LOG_CONF_THREADED, QB_TRUE);
257 static void logsys_subsys_init (
271 strncpy (logsys_loggers[subsysid].subsys, subsys,
272 sizeof (logsys_loggers[subsysid].subsys));
273 logsys_loggers[subsysid].
subsys[
274 sizeof (logsys_loggers[subsysid].
subsys) - 1] =
'\0';
275 logsys_loggers[subsysid].
file_idx = 0;
278 static const char *_logsys_tags_stringify(uint32_t tags)
280 if (tags == QB_LOG_TAG_LIBQB_MSG) {
283 return logsys_loggers[tags].
subsys;
292 free(logsys_loggers[i].logfile);
293 for (f = 0; f < logsys_loggers[i].
file_idx; f++) {
294 free(logsys_loggers[i].
files[f]);
306 const char *mainsystem,
315 if ((mainsystem == NULL) ||
324 "log_file.c,log_dcs.c,log_thread.c,ipc_shm.c,ipcs.c,ipc_us.c,loop.c,"
325 "loop_poll_epoll.c,loop_job.c,loop_poll_poll.c,loop_poll_kqueue.c,"
326 "loop_timerlist.c,loop_poll.c,ringbuffer.c,ringbuffer_helper.c,trie.c,"
327 "map.c,skiplist.c,rpl_sem.c,hdb.c,unix.c,hashtable.c,strlcpy.c,ipc_socket.c,"
328 "strchrnul.c,ipc_setup.c,strlcat.c");
342 _logsys_subsys_filename_add (i,
"logsys.c");
346 pthread_mutex_lock (&logsys_config_mutex);
348 snprintf(logsys_loggers[i].subsys,
358 qb_log_init(mainsystem, syslog_facility, syslog_priority);
360 qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_TRUE);
362 qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_FALSE);
365 qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_TRUE);
367 qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_FALSE);
369 qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_PRIORITY_BUMP, LOG_INFO - LOG_DEBUG);
371 qb_log_filter_ctl(QB_LOG_BLACKBOX, QB_LOG_FILTER_ADD,
372 QB_LOG_FILTER_FILE,
"*", LOG_TRACE);
374 qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_THREADED, QB_FALSE);
380 qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_FALSE);
386 qb_log_tags_stringify_fn_set(_logsys_tags_stringify);
392 if ((strcmp (logsys_loggers[i].subsys,
"") != 0) &&
396 strncpy (tempsubsys, logsys_loggers[i].subsys,
397 sizeof (tempsubsys));
398 tempsubsys[
sizeof (tempsubsys) - 1] =
'\0';
399 logsys_subsys_init(tempsubsys, i);
401 _logsys_config_mode_set_unlocked(i, logsys_loggers[i].mode);
402 _logsys_config_apply_per_subsys(i);
406 pthread_mutex_unlock (&logsys_config_mutex);
412 static void _logsys_subsys_filename_add (int32_t s,
const char *filename)
416 if (filename == NULL) {
420 assert(logsys_loggers[s].
file_idx >= 0);
422 for (i = 0; i < logsys_loggers[s].
file_idx; i++) {
423 if (strcmp(logsys_loggers[s].
files[i], filename) == 0) {
427 logsys_loggers[s].
files[logsys_loggers[s].
file_idx++] = strdup(filename);
430 _logsys_config_apply_per_file(s, filename);
438 if ((subsys == NULL) ||
443 pthread_mutex_lock (&logsys_config_mutex);
445 i = _logsys_config_subsys_get_unlocked (subsys);
447 _logsys_subsys_filename_add(i, filename);
448 pthread_mutex_unlock (&logsys_config_mutex);
453 if (strcmp (logsys_loggers[i].subsys,
"") == 0) {
454 logsys_subsys_init(subsys, i);
455 _logsys_subsys_filename_add(i, filename);
460 if (i >= LOGSYS_MAX_SUBSYS_COUNT) {
464 pthread_mutex_unlock (&logsys_config_mutex);
472 pthread_mutex_lock (&logsys_config_mutex);
474 i = _logsys_config_subsys_get_unlocked (subsys);
476 pthread_mutex_unlock (&logsys_config_mutex);
481 static int32_t _logsys_config_mode_set_unlocked(int32_t subsysid, uint32_t new_mode)
483 if ( logsys_loggers[subsysid].
mode == new_mode) {
486 if (logsys_loggers[subsysid].target_id > 0) {
487 qb_log_ctl(logsys_loggers[subsysid].target_id,
493 qb_log_ctl(QB_LOG_STDERR,
496 qb_log_ctl(QB_LOG_SYSLOG,
500 logsys_loggers[subsysid].
mode = new_mode;
508 pthread_mutex_lock (&logsys_config_mutex);
509 if (subsys != NULL) {
510 i = _logsys_config_subsys_get_unlocked (subsys);
512 i = _logsys_config_mode_set_unlocked(i, mode);
516 _logsys_config_mode_set_unlocked(i, mode);
521 pthread_mutex_unlock (&logsys_config_mutex);
535 return logsys_loggers[i].
mode;
540 const char **error_string,
546 pthread_mutex_lock (&logsys_config_mutex);
548 if (subsys != NULL) {
549 i = _logsys_config_subsys_get_unlocked (subsys);
553 res = logsys_config_file_set_unlocked(i, error_string, file);
557 res = logsys_config_file_set_unlocked(i, error_string, file);
564 pthread_mutex_unlock (&logsys_config_mutex);
569 logsys_file_format_get(
char* file_format,
int buf_len)
572 file_format[0] =
'\0';
573 per_t = strstr(format_buffer,
"%t");
575 strcpy(file_format,
"%t [%P] %H %N");
577 strncat(file_format, per_t, buf_len - strlen(
"%t [%P] %H %N"));
579 strcpy(file_format,
"[%P] %H %N");
580 strncat(file_format, format_buffer, buf_len - strlen(
"[%P] %H %N"));
590 char syslog_format[128];
591 char file_format[128];
595 format_buffer = NULL;
598 format_buffer = strdup(format ? format :
"%7p [%6g] %b");
599 if (format_buffer == NULL) {
603 qb_log_format_set(QB_LOG_STDERR, format_buffer);
605 logsys_file_format_get(file_format, 128);
607 if (logsys_loggers[i].target_id > 0) {
608 qb_log_format_set(logsys_loggers[i].target_id, file_format);
617 memset(syslog_format,
'\0',
sizeof(syslog_format));
618 for (c = 0; c < strlen(format_buffer); c++) {
619 if (format_buffer[c] ==
'%') {
621 for (c++; c < strlen(format_buffer); c++) {
622 if (isdigit(format_buffer[c])) {
625 if (format_buffer[c] ==
't' ||
626 format_buffer[c] ==
'p') {
634 syslog_format[w] = format_buffer[c];
637 qb_log_format_set(QB_LOG_SYSLOG, syslog_format);
644 return format_buffer;
649 unsigned int facility)
651 return qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_FACILITY, facility);
656 unsigned int priority)
660 pthread_mutex_lock (&logsys_config_mutex);
661 if (subsys != NULL) {
662 i = _logsys_config_subsys_get_unlocked (subsys);
665 logsys_loggers[i].
dirty = QB_TRUE;
672 logsys_loggers[i].
dirty = QB_TRUE;
676 pthread_mutex_unlock (&logsys_config_mutex);
683 unsigned int priority)
687 pthread_mutex_lock (&logsys_config_mutex);
688 if (subsys != NULL) {
689 i = _logsys_config_subsys_get_unlocked (subsys);
692 logsys_loggers[i].
dirty = QB_TRUE;
698 logsys_loggers[i].
dirty = QB_TRUE;
702 pthread_mutex_unlock (&logsys_config_mutex);
708 static void _logsys_config_apply_per_file(int32_t s,
const char *filename)
713 qb_log_filter_ctl(s, QB_LOG_TAG_SET, QB_LOG_FILTER_FILE,
714 filename, LOG_TRACE);
716 qb_log_filter_ctl(QB_LOG_SYSLOG, QB_LOG_FILTER_REMOVE,
717 QB_LOG_FILTER_FILE, filename, LOG_TRACE);
718 qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_REMOVE,
719 QB_LOG_FILTER_FILE, filename, LOG_TRACE);
720 if (logsys_loggers[s].target_id > 0) {
721 qb_log_filter_ctl(logsys_loggers[s].target_id,
722 QB_LOG_FILTER_REMOVE,
723 QB_LOG_FILTER_FILE, filename, LOG_TRACE);
727 switch (logsys_loggers[s].
debug) {
729 syslog_priority = LOG_DEBUG;
730 logfile_priority = LOG_DEBUG;
733 syslog_priority = LOG_TRACE;
734 logfile_priority = LOG_TRACE;
740 qb_log_filter_ctl(QB_LOG_SYSLOG, QB_LOG_FILTER_ADD,
741 QB_LOG_FILTER_FILE, filename,
743 qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD,
744 QB_LOG_FILTER_FILE, filename,
746 if (logsys_loggers[s].target_id > 0) {
747 qb_log_filter_ctl(logsys_loggers[s].target_id,
749 QB_LOG_FILTER_FILE, filename,
754 static void _logsys_config_apply_per_subsys(int32_t s)
757 for (f = 0; f < logsys_loggers[s].
file_idx; f++) {
758 _logsys_config_apply_per_file(s, logsys_loggers[s].
files[f]);
760 if (logsys_loggers[s].target_id > 0) {
761 qb_log_ctl(logsys_loggers[s].target_id,
765 logsys_loggers[s].
dirty = QB_FALSE;
768 static void _logsys_config_apply_blackbox(
void) {
769 int blackbox_enable_res;
771 blackbox_enable_res = qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, logsys_blackbox_enabled);
773 if (blackbox_enable_res < 0) {
775 "Unable to initialize log flight recorder. "\
776 "The most common cause of this error is " \
777 "not enough space on /dev/shm. Corosync will continue work, " \
778 "but blackbox will not be available");
786 _logsys_config_apply_blackbox();
789 if (strcmp(logsys_loggers[s].subsys,
"") == 0) {
792 _logsys_config_apply_per_subsys(s);
802 pthread_mutex_lock (&logsys_config_mutex);
803 if (subsys != NULL) {
804 i = _logsys_config_subsys_get_unlocked (subsys);
806 logsys_loggers[i].
dirty = QB_TRUE;
813 logsys_loggers[i].
dirty = QB_TRUE;
817 pthread_mutex_unlock (&logsys_config_mutex);
826 for (i = 0; prioritynames[i].
c_name != NULL; i++) {
827 if (strcasecmp(name, prioritynames[i].c_name) == 0) {
828 return (prioritynames[i].c_val);
839 err = qb_log_thread_start();
844 qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_THREADED, QB_TRUE);
846 if (logsys_loggers[i].target_id > 0) {
847 qb_log_ctl(logsys_loggers[i].target_id, QB_LOG_CONF_THREADED, QB_TRUE);
851 logsys_thread_started = 1;
859 pthread_mutex_lock (&logsys_config_mutex);
861 logsys_blackbox_enabled = enable;
863 pthread_mutex_unlock (&logsys_config_mutex);
873 (void)qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_FALSE);
879 _logsys_config_apply_blackbox();