12 #include <sys/param.h>
13 #include <sys/types.h>
16 #include <sys/utsname.h>
31 #include <qb/qbdefs.h>
38 static gboolean crm_tracing_enabled(
void);
45 crm_glib_handler(
const gchar * log_domain, GLogLevelFlags
flags,
const gchar * message,
48 int log_level = LOG_WARNING;
49 GLogLevelFlags msg_level = (
flags & G_LOG_LEVEL_MASK);
50 static struct qb_log_callsite *glib_cs = NULL;
52 if (glib_cs == NULL) {
53 glib_cs = qb_log_callsite_get(__FUNCTION__, __FILE__,
"glib-handler", LOG_DEBUG, __LINE__,
crm_trace_nonlog);
58 case G_LOG_LEVEL_CRITICAL:
63 crm_abort(__FILE__, __FUNCTION__, __LINE__, message, TRUE, TRUE);
67 case G_LOG_LEVEL_ERROR:
70 case G_LOG_LEVEL_MESSAGE:
71 log_level = LOG_NOTICE;
73 case G_LOG_LEVEL_INFO:
76 case G_LOG_LEVEL_DEBUG:
77 log_level = LOG_DEBUG;
80 case G_LOG_LEVEL_WARNING:
81 case G_LOG_FLAG_RECURSION:
82 case G_LOG_FLAG_FATAL:
83 case G_LOG_LEVEL_MASK:
84 log_level = LOG_WARNING;
88 do_crm_log(log_level,
"%s: %s", log_domain, message);
104 crm_trigger_blackbox(
int nsig)
106 if(nsig == SIGTRAP) {
117 const char *value = NULL;
119 snprintf(env_name,
NAME_MAX,
"PCMK_%s", option);
120 value = getenv(env_name);
122 crm_trace(
"Found %s = %s", env_name, value);
126 snprintf(env_name,
NAME_MAX,
"HA_%s", option);
127 value = getenv(env_name);
129 crm_trace(
"Found %s = %s", env_name, value);
133 crm_trace(
"Nothing found for %s", option);
142 snprintf(env_name,
NAME_MAX,
"PCMK_%s", option);
144 crm_trace(
"Setting %s to %s", env_name, value);
145 setenv(env_name, value, 1);
151 snprintf(env_name,
NAME_MAX,
"HA_%s", option);
153 crm_trace(
"Setting %s to %s", env_name, value);
154 setenv(env_name, value, 1);
169 }
else if (value != NULL && strstr(value,
daemon)) {
185 set_format_string(
int method,
const char *
daemon)
187 if (method == QB_LOG_SYSLOG) {
189 crm_extended_logging(method, QB_FALSE);
190 qb_log_format_set(method,
"%g %p: %b");
198 if (method > QB_LOG_STDERR) {
200 const char *nodename =
"localhost";
202 if (
uname(&res) == 0) {
203 nodename = res.nodename;
207 offset += snprintf(fmt + offset,
FMT_MAX - offset,
208 "%%t %s %-20s[%lu] ",
209 nodename,
daemon, (
unsigned long) getpid());
213 offset += snprintf(fmt + offset,
FMT_MAX - offset,
"(%%n");
214 if (crm_tracing_enabled()) {
216 offset += snprintf(fmt + offset,
FMT_MAX - offset,
"@%%f:%%l");
218 offset += snprintf(fmt + offset,
FMT_MAX - offset,
")");
221 offset += snprintf(fmt + offset,
FMT_MAX - offset,
" %%g\t%%p: %%b");
224 qb_log_format_set(method, fmt);
231 bool is_default =
false;
232 static int default_fd = -1;
233 static gboolean have_logfile = FALSE;
234 const char *default_logfile =
CRM_LOG_DIR "/pacemaker.log";
238 FILE *logfile = NULL;
239 char *parent_dir = NULL;
242 if (filename == NULL && have_logfile == FALSE) {
243 filename = default_logfile;
246 if (filename == NULL) {
252 }
else if(
safe_str_eq(filename, default_logfile)) {
256 if(is_default && default_fd >= 0) {
261 filename_cp = strdup(filename);
262 parent_dir = dirname(filename_cp);
263 rc = stat(parent_dir, &parent);
266 crm_err(
"Directory '%s' does not exist: logging to '%s' is disabled", parent_dir, filename);
273 logfile = fopen(filename,
"a");
274 if(logfile == NULL) {
275 crm_err(
"%s (%d): Logging to '%s' as uid=%u, gid=%u is disabled",
276 pcmk_strerror(errno), errno, filename, geteuid(), getegid());
281 if (geteuid() == 0) {
285 gboolean fix = FALSE;
286 int logfd = fileno(logfile);
288 rc = fstat(logfd, &st);
290 crm_perror(LOG_WARNING,
"Cannot stat %s", filename);
296 if (st.st_gid != pcmk_gid) {
299 }
else if ((st.st_mode & S_IRWXG) != (S_IRGRP | S_IWGRP)) {
306 rc = fchown(logfd, pcmk_uid, pcmk_gid);
308 crm_warn(
"Cannot change the ownership of %s to user %s and gid %d",
312 rc = fchmod(logfd, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
314 crm_warn(
"Cannot change the mode of %s to rw-rw----", filename);
317 fprintf(logfile,
"Set r/w permissions for uid=%d, gid=%d on %s\n",
318 pcmk_uid, pcmk_gid, filename);
319 if (fflush(logfile) < 0 || fsync(logfd) < 0) {
320 crm_err(
"Couldn't write out logfile: %s", filename);
327 fd = qb_log_file_open(filename);
330 crm_perror(LOG_WARNING,
"Couldn't send additional logging to %s", filename);
342 }
else if(default_fd >= 0) {
344 qb_log_ctl(default_fd, QB_LOG_CONF_ENABLED, QB_FALSE);
347 crm_notice(
"Additional logging available in %s", filename);
348 qb_log_ctl(fd, QB_LOG_CONF_ENABLED, QB_TRUE);
351 #ifdef HAVE_qb_log_conf_QB_LOG_CONF_MAX_LINE_LEN
353 qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_MAX_LINE_LEN, 800);
363 static int blackbox_trigger = 0;
364 static volatile char *blackbox_file_prefix = NULL;
366 #ifdef QB_FEATURE_LOG_HIRES_TIMESTAMPS
373 blackbox_logger(int32_t t,
struct qb_log_callsite *cs,
log_time_t timestamp,
376 if(cs && cs->priority < LOG_ERR) {
384 crm_control_blackbox(
int nsig,
bool enable)
388 if (blackbox_file_prefix == NULL) {
389 pid_t
pid = getpid();
394 (
unsigned long)
pid);
397 if (enable && qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_STATE_GET, 0) != QB_LOG_STATE_ENABLED) {
398 qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_SIZE, 5 * 1024 * 1024);
399 qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_TRUE);
402 for (lpc = QB_LOG_BLACKBOX; lpc < QB_LOG_TARGET_MAX; lpc++) {
403 qb_log_ctl(lpc, QB_LOG_CONF_FILE_SYNC, QB_TRUE);
406 crm_notice(
"Initiated blackbox recorder: %s", blackbox_file_prefix);
417 blackbox_trigger = qb_log_custom_open(blackbox_logger, NULL, NULL, NULL);
418 qb_log_ctl(blackbox_trigger, QB_LOG_CONF_ENABLED, QB_TRUE);
419 crm_trace(
"Trigger: %d is %d %d", blackbox_trigger,
420 qb_log_ctl(blackbox_trigger, QB_LOG_CONF_STATE_GET, 0), QB_LOG_STATE_ENABLED);
424 }
else if (!enable && qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_STATE_GET, 0) == QB_LOG_STATE_ENABLED) {
425 qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_FALSE);
428 for (lpc = QB_LOG_BLACKBOX; lpc < QB_LOG_TARGET_MAX; lpc++) {
429 qb_log_ctl(lpc, QB_LOG_CONF_FILE_SYNC, QB_FALSE);
437 crm_control_blackbox(nsig, TRUE);
443 crm_control_blackbox(nsig, FALSE);
459 static volatile int counter = 1;
460 static volatile time_t last = 0;
463 time_t now = time(NULL);
465 if (blackbox_file_prefix == NULL) {
474 if (nsig == 0 && now == last) {
479 snprintf(buffer,
NAME_MAX,
"%s.%d", blackbox_file_prefix, counter++);
480 if (nsig == SIGTRAP) {
481 crm_notice(
"Blackbox dump requested, please see %s for contents", buffer);
485 "Problem detected at %s:%d (%s), please see %s for additional details",
486 cs->function, cs->lineno, cs->filename, buffer);
488 crm_notice(
"Problem detected, please see %s for additional details", buffer);
492 qb_log_blackbox_write_to_file(buffer);
497 qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_FALSE);
498 qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_TRUE);
506 qb_log_blackbox_write_to_file((
const char *)blackbox_file_prefix);
507 qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_FALSE);
516 return crm_log_init(entity, LOG_ERR, FALSE, FALSE, 0, NULL, TRUE);
520 crm_quark_to_string(uint32_t tag)
522 const char *text = g_quark_to_string(tag);
531 crm_log_filter_source(
int source,
const char *trace_files,
const char *trace_fns,
532 const char *trace_fmts,
const char *trace_tags,
const char *trace_blackbox,
533 struct qb_log_callsite *cs)
535 if (qb_log_ctl(source, QB_LOG_CONF_STATE_GET, 0) != QB_LOG_STATE_ENABLED) {
539 qb_bit_set(cs->targets, source);
541 }
else if (source == blackbox_trigger && blackbox_trigger > 0) {
543 if (cs->priority <= LOG_ERR) {
544 qb_bit_set(cs->targets, source);
546 }
else if (trace_blackbox) {
549 if (strstr(trace_blackbox, key) != NULL) {
550 qb_bit_set(cs->targets, source);
555 }
else if (source == QB_LOG_SYSLOG) {
557 qb_bit_set(cs->targets, source);
561 qb_bit_set(cs->targets, source);
562 }
else if (trace_files && strstr(trace_files, cs->filename) != NULL) {
563 qb_bit_set(cs->targets, source);
564 }
else if (trace_fns && strstr(trace_fns, cs->function) != NULL) {
565 qb_bit_set(cs->targets, source);
566 }
else if (trace_fmts && strstr(trace_fmts, cs->format) != NULL) {
567 qb_bit_set(cs->targets, source);
568 }
else if (trace_tags
571 qb_bit_set(cs->targets, source);
576 crm_log_filter(
struct qb_log_callsite *cs)
579 static int need_init = 1;
580 static const char *trace_fns = NULL;
581 static const char *trace_tags = NULL;
582 static const char *trace_fmts = NULL;
583 static const char *trace_files = NULL;
584 static const char *trace_blackbox = NULL;
588 trace_fns = getenv(
"PCMK_trace_functions");
589 trace_fmts = getenv(
"PCMK_trace_formats");
590 trace_tags = getenv(
"PCMK_trace_tags");
591 trace_files = getenv(
"PCMK_trace_files");
592 trace_blackbox = getenv(
"PCMK_trace_blackbox");
594 if (trace_tags != NULL) {
597 const char *offset = NULL;
598 const char *next = trace_tags;
603 snprintf(token,
sizeof(token),
"%.*s", (
int)(next - offset), offset);
605 tag = g_quark_from_string(token);
606 crm_info(
"Created GQuark %u from token '%s' in '%s'", tag, token, trace_tags);
612 }
while (next != NULL && next[0] != 0);
617 for (lpc = QB_LOG_SYSLOG; lpc < QB_LOG_TARGET_MAX; lpc++) {
618 crm_log_filter_source(lpc, trace_files, trace_fns, trace_fmts, trace_tags, trace_blackbox,
626 gboolean refilter = FALSE;
632 if (cs->priority != level) {
633 cs->priority = level;
637 if (cs->tags != tags) {
646 if (cs->targets == 0) {
655 static gboolean log = TRUE;
660 (
"Enabling callsites based on priority=%d, files=%s, functions=%s, formats=%s, tags=%s",
661 crm_log_level, getenv(
"PCMK_trace_files"), getenv(
"PCMK_trace_functions"),
662 getenv(
"PCMK_trace_formats"), getenv(
"PCMK_trace_tags"));
664 qb_log_filter_fn_set(crm_log_filter);
668 crm_tracing_enabled(
void)
672 }
else if (getenv(
"PCMK_trace_files") || getenv(
"PCMK_trace_functions")
673 || getenv(
"PCMK_trace_formats") || getenv(
"PCMK_trace_tags")) {
680 crm_priority2int(
const char *name)
682 struct syslog_names {
686 static struct syslog_names p_names[] = {
687 {
"emerg", LOG_EMERG},
688 {
"alert", LOG_ALERT},
691 {
"warning", LOG_WARNING},
692 {
"notice", LOG_NOTICE},
694 {
"debug", LOG_DEBUG},
699 for (lpc = 0; name != NULL && p_names[lpc].name != NULL; lpc++) {
700 if (
crm_str_eq(p_names[lpc].name, name, TRUE)) {
701 return p_names[lpc].priority;
709 crm_identity(
const char *entity,
int argc,
char **argv)
718 }
else if (argc > 0 && argv != NULL) {
719 char *
mutable = strdup(argv[0]);
720 char *modified = basename(
mutable);
722 if (strstr(modified,
"lt-") == modified) {
744 int32_t qb_facility = 0;
746 static bool have_logging = FALSE;
748 if(have_logging == FALSE) {
754 crm_trace_nonlog = g_quark_from_static_string(
"Pacemaker non-logging tracepoint");
757 umask(S_IWGRP | S_IWOTH | S_IROTH);
763 g_log_set_always_fatal((GLogLevelFlags) 0);
766 crm_identity(entity, argc, argv);
768 qb_facility = qb_log_facility2int(
"local0");
773 qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_FALSE);
774 #ifdef HAVE_qb_log_conf_QB_LOG_CONF_MAX_LINE_LEN
776 qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_MAX_LINE_LEN, 256);
782 qb_log_tags_stringify_fn_set(crm_quark_to_string);
783 for (lpc = QB_LOG_SYSLOG; lpc < QB_LOG_TARGET_MAX; lpc++) {
784 qb_log_ctl(lpc, QB_LOG_CONF_THREADED, QB_FALSE);
785 #ifdef HAVE_qb_log_conf_QB_LOG_CONF_ELLIPSIS
787 qb_log_ctl(lpc, QB_LOG_CONF_ELLIPSIS, QB_TRUE);
796 int argc,
char **argv, gboolean quiet)
798 const char *syslog_priority = NULL;
801 const char *f_copy = facility;
811 if (facility == NULL) {
825 qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_FACILITY, qb_log_facility2int(facility));
835 if(syslog_priority) {
836 int priority = crm_priority2int(syslog_priority);
838 qb_log_filter_ctl(QB_LOG_SYSLOG, QB_LOG_FILTER_ADD, QB_LOG_FILTER_FILE,
"*", priority);
840 qb_log_filter_ctl(QB_LOG_SYSLOG, QB_LOG_FILTER_ADD, QB_LOG_FILTER_FILE,
"*", LOG_NOTICE);
845 qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_TRUE);
870 crm_trace(
"Quiet: %d, facility %s", quiet, f_copy);
882 const char *user = getenv(
"USER");
885 crm_trace(
"Not switching to corefile directory for %s", user);
893 struct passwd *pwent = getpwuid(user);
896 crm_perror(LOG_ERR,
"Cannot get name for uid: %d", user);
900 crm_trace(
"Don't change active directory for regular user: %s", pwent->pw_name);
902 }
else if (chdir(base) < 0) {
903 crm_perror(LOG_INFO,
"Cannot change active directory to %s", base);
906 crm_info(
"Changed active directory to %s", base);
911 snprintf(path, 512,
"%s-%lu",
crm_system_name, (
unsigned long) getpid());
914 crm_info(
"Changed active directory to %s/%s/%s", base, pwent->pw_name, path);
951 if (enable && qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_STATE_GET, 0) != QB_LOG_STATE_ENABLED) {
952 qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_TRUE);
955 }
else if (enable == FALSE) {
956 qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_FALSE);
963 static int args = TRUE;
966 if (args && argc > 1) {
970 if (qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_STATE_GET, 0) == QB_LOG_STATE_ENABLED) {
984 #define ARGS_FMT "Invoked: %s"
990 int existing_len = 0;
992 static int logged = 0;
994 char *arg_string = NULL;
996 if (argc == 0 || argv == NULL || logged) {
1002 for (; lpc < argc; lpc++) {
1003 if (argv[lpc] == NULL) {
1007 len = 2 + strlen(argv[lpc]);
1008 arg_string = realloc_safe(arg_string, len + existing_len);
1009 existing_len += sprintf(arg_string + existing_len,
"%s ", argv[lpc]);
1012 qb_log_from_external_source(__func__, __FILE__,
ARGS_FMT, LOG_NOTICE, line, 0, arg_string);
1021 const char *next = NULL;
1022 const char *offset = NULL;
1024 if (output == NULL) {
1026 output =
"-- empty --";
1034 (
int)(next - offset), offset);
1039 }
while (next != NULL && next[0] != 0);