static bool show_color = false;
static bool show_location = false;
-/* Akin to glibc's __abort_msg; which is private and we hance cannot
+/* Akin to glibc's __abort_msg; which is private and we hence cannot
* use here. */
static char *log_abort_msg = NULL;
return console_fd;
}
- log_debug("Succesfully opened /dev/console for logging.");
+ log_debug("Successfully opened /dev/console for logging.");
} else
console_fd = STDERR_FILENO;
return 0;
if ((kmsg_fd = open("/dev/kmsg", O_WRONLY|O_NOCTTY|O_CLOEXEC)) < 0) {
- log_info("Failed to open /dev/kmsg for logging: %s", strerror(errno));
+ log_error("Failed to open /dev/kmsg for logging: %s", strerror(errno));
return -errno;
}
- log_debug("Succesfully opened /dev/kmsg for logging.");
+ log_debug("Successfully opened /dev/kmsg for logging.");
return 0;
}
} else
syslog_is_stream = false;
- log_debug("Succesfully opened syslog for logging.");
+ log_debug("Successfully opened syslog for logging.");
return 0;
fail:
log_close_syslog();
- log_info("Failed to open syslog for logging: %s", strerror(-r));
+ log_debug("Failed to open syslog for logging: %s", strerror(-r));
return r;
}
return 0;
}
- if (log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
- log_target == LOG_TARGET_SYSLOG)
- if ((r = log_open_syslog()) >= 0) {
- log_close_console();
- return r;
- }
-
- if (log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
- log_target == LOG_TARGET_KMSG)
- if ((r = log_open_kmsg()) >= 0) {
- log_close_syslog();
- log_close_console();
- return r;
- }
+ if (log_target != LOG_TARGET_AUTO ||
+ getpid() == 1 ||
+ isatty(STDERR_FILENO) <= 0) {
+
+ if (log_target == LOG_TARGET_AUTO ||
+ log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
+ log_target == LOG_TARGET_SYSLOG)
+ if ((r = log_open_syslog()) >= 0) {
+ log_close_console();
+ return r;
+ }
+ if (log_target == LOG_TARGET_AUTO ||
+ log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
+ log_target == LOG_TARGET_KMSG)
+ if ((r = log_open_kmsg()) >= 0) {
+ log_close_syslog();
+ log_close_console();
+ return r;
+ }
+ }
log_close_syslog();
+
+ /* Get the real /dev/console if we are PID=1, hence reopen */
+ log_close_console();
return log_open_console();
}
log_target = target;
}
+void log_close(void) {
+ log_close_console();
+ log_close_kmsg();
+ log_close_syslog();
+}
+
void log_set_max_level(int level) {
assert((level & LOG_PRIMASK) == level);
}
static int write_to_console(
- int level,
- const char*file,
- int line,
- const char *func,
- const char *buffer) {
+ int level,
+ const char*file,
+ int line,
+ const char *func,
+ const char *buffer) {
char location[64];
struct iovec iovec[5];
if (syslog_fd < 0)
return 0;
- snprintf(header_priority, sizeof(header_priority), "<%i>", LOG_MAKEPRI(LOG_DAEMON, LOG_PRI(level)));
+ snprintf(header_priority, sizeof(header_priority), "<%i>", level);
char_array_0(header_priority);
t = (time_t) (now(CLOCK_REALTIME) / USEC_PER_SEC);
IOVEC_SET_STRING(iovec[3], header_pid);
IOVEC_SET_STRING(iovec[4], buffer);
- /* When using syslog via SOCK_STREAM seperate the messages by NUL chars */
+ /* When using syslog via SOCK_STREAM separate the messages by NUL chars */
if (syslog_is_stream)
iovec[4].iov_len++;
if (kmsg_fd < 0)
return 0;
- snprintf(header_priority, sizeof(header_priority), "<%i>", LOG_PRI(level));
+ snprintf(header_priority, sizeof(header_priority), "<%i>", level);
char_array_0(header_priority);
snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) getpid());
if (log_target == LOG_TARGET_NULL)
return 0;
+ /* Patch in LOG_DAEMON facility if necessary */
+ if ((level & LOG_FACMASK) == 0)
+ level = LOG_DAEMON | LOG_PRI(level);
+
do {
char *e;
int k = 0;
if ((e = strpbrk(buffer, NEWLINE)))
*(e++) = 0;
- if (log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
+ if (log_target == LOG_TARGET_AUTO ||
+ log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
log_target == LOG_TARGET_SYSLOG) {
if ((k = write_to_syslog(level, file, line, func, buffer)) < 0) {
}
if (k <= 0 &&
- (log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
+ (log_target == LOG_TARGET_AUTO ||
+ log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
log_target == LOG_TARGET_KMSG)) {
if ((k = write_to_kmsg(level, file, line, func, buffer)) < 0) {
if (log_show_color_from_string(e) < 0)
log_warning("Failed to parse bool %s. Ignoring.", e);
- if ((e = getenv("SYSTEMD_LOG_LOCATION"))) {
+ if ((e = getenv("SYSTEMD_LOG_LOCATION")))
if (log_show_location_from_string(e) < 0)
log_warning("Failed to parse bool %s. Ignoring.", e);
- }
}
LogTarget log_get_target(void) {
[LOG_TARGET_SYSLOG] = "syslog",
[LOG_TARGET_KMSG] = "kmsg",
[LOG_TARGET_SYSLOG_OR_KMSG] = "syslog-or-kmsg",
- [LOG_TARGET_NULL] = "null"
+ [LOG_TARGET_NULL] = "null",
+ [LOG_TARGET_AUTO] = "auto"
};
DEFINE_STRING_TABLE_LOOKUP(log_target, LogTarget);