1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
30 #include <sys/signalfd.h>
31 #include <sys/socket.h>
38 #include "sd-messages.h"
40 #include "alloc-util.h"
42 #include "formats-util.h"
47 #include "parse-util.h"
48 #include "proc-cmdline.h"
49 #include "process-util.h"
50 #include "signal-util.h"
51 #include "socket-util.h"
52 #include "stdio-util.h"
53 #include "string-table.h"
54 #include "string-util.h"
55 #include "syslog-util.h"
56 #include "terminal-util.h"
57 #include "time-util.h"
60 #define SNDBUF_SIZE (8*1024*1024)
62 static LogTarget log_target = LOG_TARGET_CONSOLE;
63 static int log_max_level = LOG_INFO;
64 static int log_facility = LOG_DAEMON;
66 static int console_fd = STDERR_FILENO;
67 static int syslog_fd = -1;
68 static int kmsg_fd = -1;
69 static int journal_fd = -1;
71 static bool syslog_is_stream = false;
73 static bool show_color = false;
74 static bool show_location = false;
76 /// UNNEEDED by elogind static bool upgrade_syslog_to_journal = false;
78 /* Akin to glibc's __abort_msg; which is private and we hence cannot
80 static char *log_abort_msg = NULL;
82 void log_close_console(void) {
89 safe_close(console_fd);
95 static int log_open_console(void) {
101 console_fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
105 console_fd = STDERR_FILENO;
110 void log_close_kmsg(void) {
111 kmsg_fd = safe_close(kmsg_fd);
114 static int log_open_kmsg(void) {
119 kmsg_fd = open("/dev/kmsg", O_WRONLY|O_NOCTTY|O_CLOEXEC);
126 void log_close_syslog(void) {
127 syslog_fd = safe_close(syslog_fd);
130 static int create_log_socket(int type) {
134 fd = socket(AF_UNIX, type|SOCK_CLOEXEC, 0);
138 fd_inc_sndbuf(fd, SNDBUF_SIZE);
140 /* We need a blocking fd here since we'd otherwise lose
141 messages way too early. However, let's not hang forever in the
142 unlikely case of a deadlock. */
144 timeval_store(&tv, 10 * USEC_PER_MSEC);
146 timeval_store(&tv, 10 * USEC_PER_SEC);
147 (void) setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
152 static int log_open_syslog(void) {
154 static const union sockaddr_union sa = {
155 .un.sun_family = AF_UNIX,
156 .un.sun_path = "/dev/log",
164 syslog_fd = create_log_socket(SOCK_DGRAM);
170 if (connect(syslog_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
171 safe_close(syslog_fd);
173 /* Some legacy syslog systems still use stream
174 * sockets. They really shouldn't. But what can we
176 syslog_fd = create_log_socket(SOCK_STREAM);
182 if (connect(syslog_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
187 syslog_is_stream = true;
189 syslog_is_stream = false;
198 #if 0 /// UNNEEDED by elogind
199 void log_close_journal(void) {
200 journal_fd = safe_close(journal_fd);
203 static int log_open_journal(void) {
205 static const union sockaddr_union sa = {
206 .un.sun_family = AF_UNIX,
207 .un.sun_path = "/run/systemd/journal/socket",
215 journal_fd = create_log_socket(SOCK_DGRAM);
216 if (journal_fd < 0) {
221 if (connect(journal_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
237 /* If we don't use the console we close it here, to not get
238 * killed by SAK. If we don't use syslog we close it here so
239 * that we are not confused by somebody deleting the socket in
240 * the fs. If we don't use /dev/kmsg we still keep it open,
241 * because there is no reason to close it. */
243 if (log_target == LOG_TARGET_NULL) {
244 /// UNNEEDED by elogind log_close_journal();
250 if ((log_target != LOG_TARGET_AUTO && log_target != LOG_TARGET_SAFE) ||
252 isatty(STDERR_FILENO) <= 0) {
254 #if 0 /// elogind does not support logging to systemd-journald
255 if (log_target == LOG_TARGET_AUTO ||
256 log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
257 log_target == LOG_TARGET_JOURNAL) {
258 r = log_open_journal();
266 if (log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
267 log_target == LOG_TARGET_SYSLOG) {
268 r = log_open_syslog();
270 /// UNNEEDED by elogind log_close_journal();
276 if (log_target == LOG_TARGET_AUTO ||
277 log_target == LOG_TARGET_SAFE ||
278 /// UNNEEDED by elogind log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
279 log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
280 log_target == LOG_TARGET_KMSG) {
283 /// UNNEEDED by elogind log_close_journal();
291 /// UNNEEDED by elogind log_close_journal();
294 return log_open_console();
297 void log_set_target(LogTarget target) {
299 assert(target < _LOG_TARGET_MAX);
301 #if 0 /// elogind does not support logging to systemd-journald
302 if (upgrade_syslog_to_journal) {
303 if (target == LOG_TARGET_SYSLOG)
304 target = LOG_TARGET_JOURNAL;
305 else if (target == LOG_TARGET_SYSLOG_OR_KMSG)
306 target = LOG_TARGET_JOURNAL_OR_KMSG;
313 void log_close(void) {
314 /// UNNEDED by elogind log_close_journal();
320 #if 0 /// UNNEEDED by elogind
321 void log_forget_fds(void) {
322 console_fd = kmsg_fd = syslog_fd = journal_fd = -1;
326 void log_set_max_level(int level) {
327 assert((level & LOG_PRIMASK) == level);
329 log_max_level = level;
332 void log_set_facility(int facility) {
333 log_facility = facility;
336 static int write_to_console(
342 const char *object_field,
344 const char *buffer) {
346 char location[64], prefix[1 + DECIMAL_STR_MAX(int) + 2];
347 struct iovec iovec[6] = {};
354 if (log_target == LOG_TARGET_CONSOLE_PREFIXED) {
355 sprintf(prefix, "<%i>", level);
356 IOVEC_SET_STRING(iovec[n++], prefix);
359 highlight = LOG_PRI(level) <= LOG_ERR && show_color;
362 xsprintf(location, "(%s:%i) ", file, line);
363 IOVEC_SET_STRING(iovec[n++], location);
367 IOVEC_SET_STRING(iovec[n++], ANSI_HIGHLIGHT_RED);
368 IOVEC_SET_STRING(iovec[n++], buffer);
370 IOVEC_SET_STRING(iovec[n++], ANSI_NORMAL);
371 IOVEC_SET_STRING(iovec[n++], "\n");
373 if (writev(console_fd, iovec, n) < 0) {
375 if (errno == EIO && getpid() == 1) {
377 /* If somebody tried to kick us from our
378 * console tty (via vhangup() or suchlike),
379 * try to reconnect */
387 if (writev(console_fd, iovec, n) < 0)
396 static int write_to_syslog(
402 const char *object_field,
404 const char *buffer) {
406 char header_priority[2 + DECIMAL_STR_MAX(int) + 1],
408 header_pid[4 + DECIMAL_STR_MAX(pid_t) + 1];
409 struct iovec iovec[5] = {};
410 struct msghdr msghdr = {
412 .msg_iovlen = ELEMENTSOF(iovec),
420 xsprintf(header_priority, "<%i>", level);
422 t = (time_t) (now(CLOCK_REALTIME) / USEC_PER_SEC);
427 if (strftime(header_time, sizeof(header_time), "%h %e %T ", tm) <= 0)
430 xsprintf(header_pid, "["PID_FMT"]: ", getpid());
432 IOVEC_SET_STRING(iovec[0], header_priority);
433 IOVEC_SET_STRING(iovec[1], header_time);
434 IOVEC_SET_STRING(iovec[2], program_invocation_short_name);
435 IOVEC_SET_STRING(iovec[3], header_pid);
436 IOVEC_SET_STRING(iovec[4], buffer);
438 /* When using syslog via SOCK_STREAM separate the messages by NUL chars */
439 if (syslog_is_stream)
445 n = sendmsg(syslog_fd, &msghdr, MSG_NOSIGNAL);
449 if (!syslog_is_stream ||
450 (size_t) n >= IOVEC_TOTAL_SIZE(iovec, ELEMENTSOF(iovec)))
453 IOVEC_INCREMENT(iovec, ELEMENTSOF(iovec), n);
459 static int write_to_kmsg(
465 const char *object_field,
467 const char *buffer) {
469 char header_priority[2 + DECIMAL_STR_MAX(int) + 1],
470 header_pid[4 + DECIMAL_STR_MAX(pid_t) + 1];
471 struct iovec iovec[5] = {};
476 xsprintf(header_priority, "<%i>", level);
477 xsprintf(header_pid, "["PID_FMT"]: ", getpid());
479 IOVEC_SET_STRING(iovec[0], header_priority);
480 IOVEC_SET_STRING(iovec[1], program_invocation_short_name);
481 IOVEC_SET_STRING(iovec[2], header_pid);
482 IOVEC_SET_STRING(iovec[3], buffer);
483 IOVEC_SET_STRING(iovec[4], "\n");
485 if (writev(kmsg_fd, iovec, ELEMENTSOF(iovec)) < 0)
491 #if 0 /// UNNEEDED by elogind
492 static int log_do_header(
497 const char *file, int line, const char *func,
498 const char *object_field, const char *object) {
500 snprintf(header, size,
502 "SYSLOG_FACILITY=%i\n"
508 "SYSLOG_IDENTIFIER=%s\n",
511 isempty(file) ? "" : "CODE_FILE=",
512 isempty(file) ? "" : file,
513 isempty(file) ? "" : "\n",
514 line ? "CODE_LINE=" : "",
515 line ? 1 : 0, line, /* %.0d means no output too, special case for 0 */
517 isempty(func) ? "" : "CODE_FUNCTION=",
518 isempty(func) ? "" : func,
519 isempty(func) ? "" : "\n",
520 error ? "ERRNO=" : "",
521 error ? 1 : 0, error,
523 isempty(object) ? "" : object_field,
524 isempty(object) ? "" : object,
525 isempty(object) ? "" : "\n",
526 program_invocation_short_name);
531 static int write_to_journal(
537 const char *object_field,
539 const char *buffer) {
541 char header[LINE_MAX];
542 struct iovec iovec[4] = {};
543 struct msghdr mh = {};
548 log_do_header(header, sizeof(header), level, error, file, line, func, object_field, object);
550 IOVEC_SET_STRING(iovec[0], header);
551 IOVEC_SET_STRING(iovec[1], "MESSAGE=");
552 IOVEC_SET_STRING(iovec[2], buffer);
553 IOVEC_SET_STRING(iovec[3], "\n");
556 mh.msg_iovlen = ELEMENTSOF(iovec);
558 if (sendmsg(journal_fd, &mh, MSG_NOSIGNAL) < 0)
565 static int log_dispatch(
571 const char *object_field,
577 if (log_target == LOG_TARGET_NULL)
580 /* Patch in LOG_DAEMON facility if necessary */
581 if ((level & LOG_FACMASK) == 0)
582 level = log_facility | LOG_PRI(level);
591 buffer += strspn(buffer, NEWLINE);
596 if ((e = strpbrk(buffer, NEWLINE)))
599 #if 0 /// elogind does not support logging to systemd-journald
600 if (log_target == LOG_TARGET_AUTO ||
601 log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
602 log_target == LOG_TARGET_JOURNAL) {
604 k = write_to_journal(level, error, file, line, func, object_field, object, buffer);
613 if (log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
614 log_target == LOG_TARGET_SYSLOG) {
616 k = write_to_syslog(level, error, file, line, func, object_field, object, buffer);
625 (log_target == LOG_TARGET_AUTO ||
626 log_target == LOG_TARGET_SAFE ||
627 log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
628 /// UNNEEDED by elogind log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
629 log_target == LOG_TARGET_KMSG)) {
631 k = write_to_kmsg(level, error, file, line, func, object_field, object, buffer);
639 (void) write_to_console(level, error, file, line, func, object_field, object, buffer);
647 int log_dump_internal(
657 /* This modifies the buffer... */
662 if (_likely_(LOG_PRI(level) > log_max_level))
665 return log_dispatch(level, error, file, line, func, NULL, NULL, buffer);
678 char buffer[LINE_MAX];
683 if (_likely_(LOG_PRI(level) > log_max_level))
686 /* Make sure that %m maps to the specified error */
690 vsnprintf(buffer, sizeof(buffer), format, ap);
692 return log_dispatch(level, error, file, line, func, NULL, NULL, buffer);
701 const char *format, ...) {
706 va_start(ap, format);
707 r = log_internalv(level, error, file, line, func, format, ap);
713 int log_object_internalv(
719 const char *object_field,
731 if (_likely_(LOG_PRI(level) > log_max_level))
734 /* Make sure that %m maps to the specified error */
738 /* Prepend the object name before the message */
743 l = n + 2 + LINE_MAX;
745 buffer = newa(char, l);
746 b = stpcpy(stpcpy(buffer, object), ": ");
749 b = buffer = newa(char, l);
752 vsnprintf(b, l, format, ap);
754 return log_dispatch(level, error, file, line, func, object_field, object, buffer);
757 int log_object_internal(
763 const char *object_field,
765 const char *format, ...) {
770 va_start(ap, format);
771 r = log_object_internalv(level, error, file, line, func, object_field, object, format, ap);
777 static void log_assert(
783 const char *format) {
785 static char buffer[LINE_MAX];
787 if (_likely_(LOG_PRI(level) > log_max_level))
790 DISABLE_WARNING_FORMAT_NONLITERAL;
791 xsprintf(buffer, format, text, file, line, func);
794 log_abort_msg = buffer;
796 log_dispatch(level, 0, file, line, func, NULL, NULL, buffer);
799 noreturn void log_assert_failed(const char *text, const char *file, int line, const char *func) {
800 log_assert(LOG_CRIT, text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Aborting.");
804 noreturn void log_assert_failed_unreachable(const char *text, const char *file, int line, const char *func) {
805 log_assert(LOG_CRIT, text, file, line, func, "Code should not be reached '%s' at %s:%u, function %s(). Aborting.");
809 void log_assert_failed_return(const char *text, const char *file, int line, const char *func) {
811 log_assert(LOG_DEBUG, text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Ignoring.");
814 int log_oom_internal(const char *file, int line, const char *func) {
815 log_internal(LOG_ERR, ENOMEM, file, line, func, "Out of memory.");
819 int log_format_iovec(
823 bool newline_separator,
828 static const char nl = '\n';
830 while (format && *n + 1 < iovec_len) {
835 /* We need to copy the va_list structure,
836 * since vasprintf() leaves it afterwards at
837 * an undefined location */
843 r = vasprintf(&m, format, aq);
848 /* Now, jump enough ahead, so that we point to
849 * the next format string */
850 VA_FORMAT_ADVANCE(format, ap);
852 IOVEC_SET_STRING(iovec[(*n)++], m);
854 if (newline_separator) {
855 iovec[*n].iov_base = (char*) &nl;
856 iovec[*n].iov_len = 1;
860 format = va_arg(ap, char *);
865 int log_struct_internal(
871 const char *format, ...) {
881 if (_likely_(LOG_PRI(level) > log_max_level))
884 if (log_target == LOG_TARGET_NULL)
887 if ((level & LOG_FACMASK) == 0)
888 level = log_facility | LOG_PRI(level);
890 #if 0 /// elogind does not support logging to systemd-journald
891 if ((log_target == LOG_TARGET_AUTO ||
892 log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
893 log_target == LOG_TARGET_JOURNAL) &&
895 char header[LINE_MAX];
896 struct iovec iovec[17] = {};
902 bool fallback = false;
904 /* If the journal is available do structured logging */
905 log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL);
906 IOVEC_SET_STRING(iovec[n++], header);
908 va_start(ap, format);
909 r = log_format_iovec(iovec, ELEMENTSOF(iovec), &n, true, error, format, ap);
914 (void) sendmsg(journal_fd, &mh, MSG_NOSIGNAL);
918 for (i = 1; i < n; i += 2)
919 free(iovec[i].iov_base);
926 /* Fallback if journal logging is not available or didn't work. */
928 va_start(ap, format);
936 vsnprintf(buf, sizeof(buf), format, aq);
939 if (startswith(buf, "MESSAGE=")) {
944 VA_FORMAT_ADVANCE(format, ap);
946 format = va_arg(ap, char *);
953 return log_dispatch(level, error, file, line, func, NULL, NULL, buf + 8);
956 int log_set_target_from_string(const char *e) {
959 t = log_target_from_string(e);
967 int log_set_max_level_from_string(const char *e) {
970 t = log_level_from_string(e);
974 log_set_max_level(t);
978 static int parse_proc_cmdline_item(const char *key, const char *value) {
981 * The systemd.log_xyz= settings are parsed by all tools, and
984 * However, "quiet" is only parsed by PID 1, and only turns of
985 * status output to /dev/console, but does not alter the log
989 if (streq(key, "debug") && !value)
990 log_set_max_level(LOG_DEBUG);
992 else if (streq(key, "systemd.log_target") && value) {
994 if (log_set_target_from_string(value) < 0)
995 log_warning("Failed to parse log target '%s'. Ignoring.", value);
997 } else if (streq(key, "systemd.log_level") && value) {
999 if (log_set_max_level_from_string(value) < 0)
1000 log_warning("Failed to parse log level '%s'. Ignoring.", value);
1002 } else if (streq(key, "systemd.log_color") && value) {
1004 if (log_show_color_from_string(value) < 0)
1005 log_warning("Failed to parse log color setting '%s'. Ignoring.", value);
1007 } else if (streq(key, "systemd.log_location") && value) {
1009 if (log_show_location_from_string(value) < 0)
1010 log_warning("Failed to parse log location setting '%s'. Ignoring.", value);
1016 void log_parse_environment(void) {
1019 if (get_ctty_devnr(0, NULL) < 0)
1020 /* Only try to read the command line in daemons.
1021 We assume that anything that has a controlling
1022 tty is user stuff. */
1023 (void) parse_proc_cmdline(parse_proc_cmdline_item);
1025 e = secure_getenv("SYSTEMD_LOG_TARGET");
1026 if (e && log_set_target_from_string(e) < 0)
1027 log_warning("Failed to parse log target '%s'. Ignoring.", e);
1029 e = secure_getenv("SYSTEMD_LOG_LEVEL");
1030 if (e && log_set_max_level_from_string(e) < 0)
1031 log_warning("Failed to parse log level '%s'. Ignoring.", e);
1033 e = secure_getenv("SYSTEMD_LOG_COLOR");
1034 if (e && log_show_color_from_string(e) < 0)
1035 log_warning("Failed to parse bool '%s'. Ignoring.", e);
1037 e = secure_getenv("SYSTEMD_LOG_LOCATION");
1038 if (e && log_show_location_from_string(e) < 0)
1039 log_warning("Failed to parse bool '%s'. Ignoring.", e);
1042 LogTarget log_get_target(void) {
1046 int log_get_max_level(void) {
1047 return log_max_level;
1050 void log_show_color(bool b) {
1054 bool log_get_show_color(void) {
1058 void log_show_location(bool b) {
1062 bool log_get_show_location(void) {
1063 return show_location;
1066 int log_show_color_from_string(const char *e) {
1069 t = parse_boolean(e);
1077 int log_show_location_from_string(const char *e) {
1080 t = parse_boolean(e);
1084 log_show_location(t);
1088 bool log_on_console(void) {
1089 if (log_target == LOG_TARGET_CONSOLE ||
1090 log_target == LOG_TARGET_CONSOLE_PREFIXED)
1093 return syslog_fd < 0 && kmsg_fd < 0 && journal_fd < 0;
1096 static const char *const log_target_table[_LOG_TARGET_MAX] = {
1097 [LOG_TARGET_CONSOLE] = "console",
1098 [LOG_TARGET_CONSOLE_PREFIXED] = "console-prefixed",
1099 [LOG_TARGET_KMSG] = "kmsg",
1100 #if 0 /// elogind does not support logging to systemd-journald
1101 [LOG_TARGET_JOURNAL] = "journal",
1102 [LOG_TARGET_JOURNAL_OR_KMSG] = "journal-or-kmsg",
1104 [LOG_TARGET_SYSLOG] = "syslog",
1105 [LOG_TARGET_SYSLOG_OR_KMSG] = "syslog-or-kmsg",
1106 [LOG_TARGET_AUTO] = "auto",
1107 [LOG_TARGET_SAFE] = "safe",
1108 [LOG_TARGET_NULL] = "null"
1111 DEFINE_STRING_TABLE_LOOKUP(log_target, LogTarget);
1113 #if 0 /// UNNEEDED by elogind
1114 void log_received_signal(int level, const struct signalfd_siginfo *si) {
1115 if (si->ssi_pid > 0) {
1116 _cleanup_free_ char *p = NULL;
1118 get_process_comm(si->ssi_pid, &p);
1121 "Received SIG%s from PID %"PRIu32" (%s).",
1122 signal_to_string(si->ssi_signo),
1123 si->ssi_pid, strna(p));
1127 signal_to_string(si->ssi_signo));
1131 void log_set_upgrade_syslog_to_journal(bool b) {
1132 upgrade_syslog_to_journal = b;
1136 int log_syntax_internal(
1139 const char *config_file,
1140 unsigned config_line,
1145 const char *format, ...) {
1148 char buffer[LINE_MAX];
1155 if (_likely_(LOG_PRI(level) > log_max_level))
1158 if (log_target == LOG_TARGET_NULL)
1164 va_start(ap, format);
1165 vsnprintf(buffer, sizeof(buffer), format, ap);
1169 r = log_struct_internal(
1172 getpid() == 1 ? "UNIT=%s" : "USER_UNIT=%s", unit,
1173 LOG_MESSAGE_ID(SD_MESSAGE_INVALID_CONFIGURATION),
1174 "CONFIG_FILE=%s", config_file,
1175 "CONFIG_LINE=%u", config_line,
1176 LOG_MESSAGE("[%s:%u] %s", config_file, config_line, buffer),
1179 r = log_struct_internal(
1182 LOG_MESSAGE_ID(SD_MESSAGE_INVALID_CONFIGURATION),
1183 "CONFIG_FILE=%s", config_file,
1184 "CONFIG_LINE=%u", config_line,
1185 LOG_MESSAGE("[%s:%u] %s", config_file, config_line, buffer),