10 #include <sys/param.h>
11 #include <sys/types.h>
14 #include <sys/utsname.h>
29 #include <qb/qbdefs.h>
36 static gboolean crm_tracing_enabled(
void);
43 crm_glib_handler(
const gchar * log_domain, GLogLevelFlags
flags,
const gchar * message,
46 int log_level = LOG_WARNING;
47 GLogLevelFlags msg_level = (
flags & G_LOG_LEVEL_MASK);
48 static struct qb_log_callsite *glib_cs = NULL;
50 if (glib_cs == NULL) {
51 glib_cs = qb_log_callsite_get(__FUNCTION__, __FILE__,
"glib-handler", LOG_DEBUG, __LINE__,
crm_trace_nonlog);
56 case G_LOG_LEVEL_CRITICAL:
61 crm_abort(__FILE__, __FUNCTION__, __LINE__, message, TRUE, TRUE);
65 case G_LOG_LEVEL_ERROR:
68 case G_LOG_LEVEL_MESSAGE:
69 log_level = LOG_NOTICE;
71 case G_LOG_LEVEL_INFO:
74 case G_LOG_LEVEL_DEBUG:
75 log_level = LOG_DEBUG;
78 case G_LOG_LEVEL_WARNING:
79 case G_LOG_FLAG_RECURSION:
80 case G_LOG_FLAG_FATAL:
81 case G_LOG_LEVEL_MASK:
82 log_level = LOG_WARNING;
86 do_crm_log(log_level,
"%s: %s", log_domain, message);
94 crm_trigger_blackbox(
int nsig)
107 const char *value = NULL;
109 snprintf(env_name,
NAME_MAX,
"PCMK_%s", option);
110 value = getenv(env_name);
112 crm_trace(
"Found %s = %s", env_name, value);
116 snprintf(env_name,
NAME_MAX,
"HA_%s", option);
117 value = getenv(env_name);
119 crm_trace(
"Found %s = %s", env_name, value);
123 crm_trace(
"Nothing found for %s", option);
132 snprintf(env_name,
NAME_MAX,
"PCMK_%s", option);
134 crm_trace(
"Setting %s to %s", env_name, value);
135 setenv(env_name, value, 1);
141 snprintf(env_name,
NAME_MAX,
"HA_%s", option);
143 crm_trace(
"Setting %s to %s", env_name, value);
144 setenv(env_name, value, 1);
159 }
else if (value != NULL && strstr(value,
daemon)) {
175 set_format_string(
int method,
const char *
daemon)
177 if (method == QB_LOG_SYSLOG) {
179 crm_extended_logging(method, QB_FALSE);
180 qb_log_format_set(method,
"%g %p: %b");
188 if (method > QB_LOG_STDERR) {
190 const char *nodename =
"localhost";
192 if (
uname(&res) == 0) {
193 nodename = res.nodename;
197 offset += snprintf(fmt + offset,
FMT_MAX - offset,
198 "%%t %s %-20s[%lu] ",
199 nodename,
daemon, (
unsigned long) getpid());
203 offset += snprintf(fmt + offset,
FMT_MAX - offset,
"(%%n");
204 if (crm_tracing_enabled()) {
206 offset += snprintf(fmt + offset,
FMT_MAX - offset,
"@%%f:%%l");
208 offset += snprintf(fmt + offset,
FMT_MAX - offset,
")");
211 offset += snprintf(fmt + offset,
FMT_MAX - offset,
" %%g\t%%p: %%b");
214 qb_log_format_set(method, fmt);
221 bool is_default =
false;
222 static int default_fd = -1;
223 static gboolean have_logfile = FALSE;
224 const char *default_logfile =
CRM_LOG_DIR "/pacemaker.log";
228 FILE *logfile = NULL;
229 char *parent_dir = NULL;
232 if (filename == NULL && have_logfile == FALSE) {
233 filename = default_logfile;
236 if (filename == NULL) {
242 }
else if(
safe_str_eq(filename, default_logfile)) {
246 if(is_default && default_fd >= 0) {
251 filename_cp = strdup(filename);
252 parent_dir = dirname(filename_cp);
253 rc = stat(parent_dir, &parent);
256 crm_err(
"Directory '%s' does not exist: logging to '%s' is disabled", parent_dir, filename);
263 logfile = fopen(filename,
"a");
264 if(logfile == NULL) {
265 crm_err(
"%s (%d): Logging to '%s' as uid=%u, gid=%u is disabled",
266 pcmk_strerror(errno), errno, filename, geteuid(), getegid());
271 if (geteuid() == 0) {
275 gboolean fix = FALSE;
276 int logfd = fileno(logfile);
278 rc = fstat(logfd, &st);
280 crm_perror(LOG_WARNING,
"Cannot stat %s", filename);
286 if (st.st_gid != pcmk_gid) {
289 }
else if ((st.st_mode & S_IRWXG) != (S_IRGRP | S_IWGRP)) {
296 rc = fchown(logfd, pcmk_uid, pcmk_gid);
298 crm_warn(
"Cannot change the ownership of %s to user %s and gid %d",
302 rc = fchmod(logfd, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
304 crm_warn(
"Cannot change the mode of %s to rw-rw----", filename);
307 fprintf(logfile,
"Set r/w permissions for uid=%d, gid=%d on %s\n",
308 pcmk_uid, pcmk_gid, filename);
309 if (fflush(logfile) < 0 || fsync(logfd) < 0) {
310 crm_err(
"Couldn't write out logfile: %s", filename);
317 fd = qb_log_file_open(filename);
320 crm_perror(LOG_WARNING,
"Couldn't send additional logging to %s", filename);
327 }
else if(default_fd >= 0) {
329 qb_log_ctl(default_fd, QB_LOG_CONF_ENABLED, QB_FALSE);
332 crm_notice(
"Additional logging available in %s", filename);
333 qb_log_ctl(fd, QB_LOG_CONF_ENABLED, QB_TRUE);
336 #ifdef HAVE_qb_log_conf_QB_LOG_CONF_MAX_LINE_LEN
338 qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_MAX_LINE_LEN, 800);
348 static int blackbox_trigger = 0;
349 static char *blackbox_file_prefix = NULL;
351 #ifdef QB_FEATURE_LOG_HIRES_TIMESTAMPS
361 if(cs && cs->priority < LOG_ERR) {
369 crm_control_blackbox(
int nsig,
bool enable)
373 if (blackbox_file_prefix == NULL) {
374 pid_t
pid = getpid();
379 (
unsigned long)
pid);
382 if (enable && qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_STATE_GET, 0) != QB_LOG_STATE_ENABLED) {
383 qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_SIZE, 5 * 1024 * 1024);
384 qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_TRUE);
387 for (lpc = QB_LOG_BLACKBOX; lpc < QB_LOG_TARGET_MAX; lpc++) {
388 qb_log_ctl(lpc, QB_LOG_CONF_FILE_SYNC, QB_TRUE);
391 crm_notice(
"Initiated blackbox recorder: %s", blackbox_file_prefix);
402 blackbox_trigger = qb_log_custom_open(blackbox_logger, NULL, NULL, NULL);
403 qb_log_ctl(blackbox_trigger, QB_LOG_CONF_ENABLED, QB_TRUE);
404 crm_trace(
"Trigger: %d is %d %d", blackbox_trigger,
405 qb_log_ctl(blackbox_trigger, QB_LOG_CONF_STATE_GET, 0), QB_LOG_STATE_ENABLED);
409 }
else if (!enable && qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_STATE_GET, 0) == QB_LOG_STATE_ENABLED) {
410 qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_FALSE);
413 for (lpc = QB_LOG_BLACKBOX; lpc < QB_LOG_TARGET_MAX; lpc++) {
414 qb_log_ctl(lpc, QB_LOG_CONF_FILE_SYNC, QB_FALSE);
422 crm_control_blackbox(nsig, TRUE);
428 crm_control_blackbox(nsig, FALSE);
434 static int counter = 1;
435 static time_t last = 0;
438 time_t now = time(NULL);
440 if (blackbox_file_prefix == NULL) {
449 if (nsig == 0 && now == last) {
454 snprintf(buffer,
NAME_MAX,
"%s.%d", blackbox_file_prefix, counter++);
455 if (nsig == SIGTRAP) {
456 crm_notice(
"Blackbox dump requested, please see %s for contents", buffer);
460 "Problem detected at %s:%d (%s), please see %s for additional details",
461 cs->function, cs->lineno, cs->filename, buffer);
463 crm_notice(
"Problem detected, please see %s for additional details", buffer);
467 qb_log_blackbox_write_to_file(buffer);
472 qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_FALSE);
473 qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_TRUE);
481 qb_log_blackbox_write_to_file(blackbox_file_prefix);
482 qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_FALSE);
491 return crm_log_init(entity, LOG_ERR, FALSE, FALSE, 0, NULL, TRUE);
497 const char *text = g_quark_to_string(tag);
506 crm_log_filter_source(
int source,
const char *trace_files,
const char *trace_fns,
507 const char *trace_fmts,
const char *trace_tags,
const char *trace_blackbox,
508 struct qb_log_callsite *cs)
510 if (qb_log_ctl(source, QB_LOG_CONF_STATE_GET, 0) != QB_LOG_STATE_ENABLED) {
514 qb_bit_set(cs->targets, source);
516 }
else if (source == blackbox_trigger && blackbox_trigger > 0) {
518 if (cs->priority <= LOG_ERR) {
519 qb_bit_set(cs->targets, source);
521 }
else if (trace_blackbox) {
524 if (strstr(trace_blackbox, key) != NULL) {
525 qb_bit_set(cs->targets, source);
530 }
else if (source == QB_LOG_SYSLOG) {
532 qb_bit_set(cs->targets, source);
536 qb_bit_set(cs->targets, source);
537 }
else if (trace_files && strstr(trace_files, cs->filename) != NULL) {
538 qb_bit_set(cs->targets, source);
539 }
else if (trace_fns && strstr(trace_fns, cs->function) != NULL) {
540 qb_bit_set(cs->targets, source);
541 }
else if (trace_fmts && strstr(trace_fmts, cs->format) != NULL) {
542 qb_bit_set(cs->targets, source);
543 }
else if (trace_tags
546 qb_bit_set(cs->targets, source);
551 crm_log_filter(
struct qb_log_callsite *cs)
554 static int need_init = 1;
555 static const char *trace_fns = NULL;
556 static const char *trace_tags = NULL;
557 static const char *trace_fmts = NULL;
558 static const char *trace_files = NULL;
559 static const char *trace_blackbox = NULL;
563 trace_fns = getenv(
"PCMK_trace_functions");
564 trace_fmts = getenv(
"PCMK_trace_formats");
565 trace_tags = getenv(
"PCMK_trace_tags");
566 trace_files = getenv(
"PCMK_trace_files");
567 trace_blackbox = getenv(
"PCMK_trace_blackbox");
569 if (trace_tags != NULL) {
572 const char *offset = NULL;
573 const char *next = trace_tags;
578 snprintf(token,
sizeof(token),
"%.*s", (
int)(next - offset), offset);
580 tag = g_quark_from_string(token);
581 crm_info(
"Created GQuark %u from token '%s' in '%s'", tag, token, trace_tags);
587 }
while (next != NULL && next[0] != 0);
592 for (lpc = QB_LOG_SYSLOG; lpc < QB_LOG_TARGET_MAX; lpc++) {
593 crm_log_filter_source(lpc, trace_files, trace_fns, trace_fmts, trace_tags, trace_blackbox,
601 gboolean refilter = FALSE;
607 if (cs->priority != level) {
608 cs->priority = level;
612 if (cs->tags != tags) {
621 if (cs->targets == 0) {
630 static gboolean log = TRUE;
635 (
"Enabling callsites based on priority=%d, files=%s, functions=%s, formats=%s, tags=%s",
636 crm_log_level, getenv(
"PCMK_trace_files"), getenv(
"PCMK_trace_functions"),
637 getenv(
"PCMK_trace_formats"), getenv(
"PCMK_trace_tags"));
639 qb_log_filter_fn_set(crm_log_filter);
643 crm_tracing_enabled(
void)
647 }
else if (getenv(
"PCMK_trace_files") || getenv(
"PCMK_trace_functions")
648 || getenv(
"PCMK_trace_formats") || getenv(
"PCMK_trace_tags")) {
655 crm_priority2int(
const char *name)
657 struct syslog_names {
661 static struct syslog_names p_names[] = {
662 {
"emerg", LOG_EMERG},
663 {
"alert", LOG_ALERT},
666 {
"warning", LOG_WARNING},
667 {
"notice", LOG_NOTICE},
669 {
"debug", LOG_DEBUG},
674 for (lpc = 0; name != NULL && p_names[lpc].name != NULL; lpc++) {
675 if (
crm_str_eq(p_names[lpc].name, name, TRUE)) {
676 return p_names[lpc].priority;
684 crm_identity(
const char *entity,
int argc,
char **argv)
693 }
else if (argc > 0 && argv != NULL) {
694 char *
mutable = strdup(argv[0]);
695 char *modified = basename(
mutable);
697 if (strstr(modified,
"lt-") == modified) {
721 static bool have_logging = FALSE;
723 if(have_logging == FALSE) {
729 crm_trace_nonlog = g_quark_from_static_string(
"Pacemaker non-logging tracepoint");
732 umask(S_IWGRP | S_IWOTH | S_IROTH);
738 g_log_set_always_fatal((GLogLevelFlags) 0);
741 crm_identity(entity, argc, argv);
743 qb_facility = qb_log_facility2int(
"local0");
748 qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_FALSE);
749 #ifdef HAVE_qb_log_conf_QB_LOG_CONF_MAX_LINE_LEN
751 qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_MAX_LINE_LEN, 256);
757 qb_log_tags_stringify_fn_set(crm_quark_to_string);
758 for (lpc = QB_LOG_SYSLOG; lpc < QB_LOG_TARGET_MAX; lpc++) {
759 qb_log_ctl(lpc, QB_LOG_CONF_THREADED, QB_FALSE);
760 #ifdef HAVE_qb_log_conf_QB_LOG_CONF_ELLIPSIS
762 qb_log_ctl(lpc, QB_LOG_CONF_ELLIPSIS, QB_TRUE);
771 int argc,
char **argv, gboolean quiet)
773 const char *syslog_priority = NULL;
776 const char *f_copy = facility;
786 if (facility == NULL) {
800 qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_FACILITY, qb_log_facility2int(facility));
810 if(syslog_priority) {
811 int priority = crm_priority2int(syslog_priority);
813 qb_log_filter_ctl(QB_LOG_SYSLOG, QB_LOG_FILTER_ADD, QB_LOG_FILTER_FILE,
"*", priority);
815 qb_log_filter_ctl(QB_LOG_SYSLOG, QB_LOG_FILTER_ADD, QB_LOG_FILTER_FILE,
"*", LOG_NOTICE);
820 qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_TRUE);
845 crm_trace(
"Quiet: %d, facility %s", quiet, f_copy);
857 const char *user = getenv(
"USER");
860 crm_trace(
"Not switching to corefile directory for %s", user);
868 struct passwd *pwent = getpwuid(user);
871 crm_perror(LOG_ERR,
"Cannot get name for uid: %d", user);
875 crm_trace(
"Don't change active directory for regular user: %s", pwent->pw_name);
877 }
else if (chdir(base) < 0) {
878 crm_perror(LOG_INFO,
"Cannot change active directory to %s", base);
881 crm_info(
"Changed active directory to %s", base);
886 snprintf(path, 512,
"%s-%lu",
crm_system_name, (
unsigned long) getpid());
889 crm_info(
"Changed active directory to %s/%s/%s", base, pwent->pw_name, path);
926 if (enable && qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_STATE_GET, 0) != QB_LOG_STATE_ENABLED) {
927 qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_TRUE);
930 }
else if (enable == FALSE) {
931 qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_FALSE);
938 static int args = TRUE;
941 if (args && argc > 1) {
945 if (qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_STATE_GET, 0) == QB_LOG_STATE_ENABLED) {
959 #define ARGS_FMT "Invoked: %s"
965 int existing_len = 0;
967 static int logged = 0;
969 char *arg_string = NULL;
971 if (argc == 0 || argv == NULL || logged) {
977 for (; lpc < argc; lpc++) {
978 if (argv[lpc] == NULL) {
982 len = 2 + strlen(argv[lpc]);
983 arg_string = realloc_safe(arg_string, len + existing_len);
984 existing_len += sprintf(arg_string + existing_len,
"%s ", argv[lpc]);
987 qb_log_from_external_source(__func__, __FILE__,
ARGS_FMT, LOG_NOTICE, line, 0, arg_string);
993 crm_log_output_fn(
const char *file,
const char *
function,
int line,
int level,
const char *prefix,
996 const char *next = NULL;
997 const char *offset = NULL;
999 if (output == NULL) {
1001 output =
"-- empty --";
1009 (
int)(next - offset), offset);
1014 }
while (next != NULL && next[0] != 0);