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/>.
27 #include <sys/socket.h>
36 #include "socket-util.h"
38 #define SNDBUF_SIZE (8*1024*1024)
40 static LogTarget log_target = LOG_TARGET_CONSOLE;
41 static int log_max_level = LOG_INFO;
42 static int log_facility = LOG_DAEMON;
44 static int console_fd = STDERR_FILENO;
45 static int syslog_fd = -1;
46 static int kmsg_fd = -1;
47 static int journal_fd = -1;
49 static bool syslog_is_stream = false;
51 static bool show_color = false;
52 static bool show_location = false;
54 static bool upgrade_syslog_to_journal = false;
56 /* Akin to glibc's __abort_msg; which is private and we hence cannot
58 static char *log_abort_msg = NULL;
60 void log_close_console(void) {
67 safe_close(console_fd);
73 static int log_open_console(void) {
79 console_fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
83 console_fd = STDERR_FILENO;
88 void log_close_kmsg(void) {
89 kmsg_fd = safe_close(kmsg_fd);
92 static int log_open_kmsg(void) {
97 kmsg_fd = open("/dev/kmsg", O_WRONLY|O_NOCTTY|O_CLOEXEC);
104 void log_close_syslog(void) {
105 syslog_fd = safe_close(syslog_fd);
108 static int create_log_socket(int type) {
112 fd = socket(AF_UNIX, type|SOCK_CLOEXEC, 0);
116 fd_inc_sndbuf(fd, SNDBUF_SIZE);
118 /* We need a blocking fd here since we'd otherwise lose
119 messages way too early. However, let's not hang forever in the
120 unlikely case of a deadlock. */
122 timeval_store(&tv, 10 * USEC_PER_MSEC);
124 timeval_store(&tv, 10 * USEC_PER_SEC);
125 (void) setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
130 static int log_open_syslog(void) {
132 static const union sockaddr_union sa = {
133 .un.sun_family = AF_UNIX,
134 .un.sun_path = "/dev/log",
142 syslog_fd = create_log_socket(SOCK_DGRAM);
148 if (connect(syslog_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
149 safe_close(syslog_fd);
151 /* Some legacy syslog systems still use stream
152 * sockets. They really shouldn't. But what can we
154 syslog_fd = create_log_socket(SOCK_STREAM);
160 if (connect(syslog_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
165 syslog_is_stream = true;
167 syslog_is_stream = false;
176 void log_close_journal(void) {
177 journal_fd = safe_close(journal_fd);
180 static int log_open_journal(void) {
182 static const union sockaddr_union sa = {
183 .un.sun_family = AF_UNIX,
184 .un.sun_path = "/run/systemd/journal/socket",
192 journal_fd = create_log_socket(SOCK_DGRAM);
193 if (journal_fd < 0) {
198 if (connect(journal_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
213 /* If we don't use the console we close it here, to not get
214 * killed by SAK. If we don't use syslog we close it here so
215 * that we are not confused by somebody deleting the socket in
216 * the fs. If we don't use /dev/kmsg we still keep it open,
217 * because there is no reason to close it. */
219 if (log_target == LOG_TARGET_NULL) {
226 if ((log_target != LOG_TARGET_AUTO && log_target != LOG_TARGET_SAFE) ||
228 isatty(STDERR_FILENO) <= 0) {
230 if (log_target == LOG_TARGET_AUTO ||
231 log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
232 log_target == LOG_TARGET_JOURNAL) {
233 r = log_open_journal();
241 if (log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
242 log_target == LOG_TARGET_SYSLOG) {
243 r = log_open_syslog();
251 if (log_target == LOG_TARGET_AUTO ||
252 log_target == LOG_TARGET_SAFE ||
253 log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
254 log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
255 log_target == LOG_TARGET_KMSG) {
269 return log_open_console();
272 void log_set_target(LogTarget target) {
274 assert(target < _LOG_TARGET_MAX);
276 if (upgrade_syslog_to_journal) {
277 if (target == LOG_TARGET_SYSLOG)
278 target = LOG_TARGET_JOURNAL;
279 else if (target == LOG_TARGET_SYSLOG_OR_KMSG)
280 target = LOG_TARGET_JOURNAL_OR_KMSG;
286 void log_close(void) {
293 void log_forget_fds(void) {
294 console_fd = kmsg_fd = syslog_fd = journal_fd = -1;
297 void log_set_max_level(int level) {
298 assert((level & LOG_PRIMASK) == level);
300 log_max_level = level;
303 void log_set_facility(int facility) {
304 log_facility = facility;
307 static int write_to_console(
313 const char *object_field,
315 const char *buffer) {
318 struct iovec iovec[5] = {};
325 highlight = LOG_PRI(level) <= LOG_ERR && show_color;
328 snprintf(location, sizeof(location), "(%s:%u) ", file, line);
329 char_array_0(location);
330 IOVEC_SET_STRING(iovec[n++], location);
334 IOVEC_SET_STRING(iovec[n++], ANSI_HIGHLIGHT_RED_ON);
335 IOVEC_SET_STRING(iovec[n++], buffer);
337 IOVEC_SET_STRING(iovec[n++], ANSI_HIGHLIGHT_OFF);
338 IOVEC_SET_STRING(iovec[n++], "\n");
340 if (writev(console_fd, iovec, n) < 0) {
342 if (errno == EIO && getpid() == 1) {
344 /* If somebody tried to kick us from our
345 * console tty (via vhangup() or suchlike),
346 * try to reconnect */
354 if (writev(console_fd, iovec, n) < 0)
363 static int write_to_syslog(
369 const char *object_field,
371 const char *buffer) {
373 char header_priority[1 + DECIMAL_STR_MAX(int) + 2], header_time[64], header_pid[1 + DECIMAL_STR_MAX(pid_t) + 4];
374 struct iovec iovec[5] = {};
375 struct msghdr msghdr = {
377 .msg_iovlen = ELEMENTSOF(iovec),
385 snprintf(header_priority, sizeof(header_priority), "<%i>", level);
386 char_array_0(header_priority);
388 t = (time_t) (now(CLOCK_REALTIME) / USEC_PER_SEC);
393 if (strftime(header_time, sizeof(header_time), "%h %e %T ", tm) <= 0)
396 snprintf(header_pid, sizeof(header_pid), "["PID_FMT"]: ", getpid());
397 char_array_0(header_pid);
399 IOVEC_SET_STRING(iovec[0], header_priority);
400 IOVEC_SET_STRING(iovec[1], header_time);
401 IOVEC_SET_STRING(iovec[2], program_invocation_short_name);
402 IOVEC_SET_STRING(iovec[3], header_pid);
403 IOVEC_SET_STRING(iovec[4], buffer);
405 /* When using syslog via SOCK_STREAM separate the messages by NUL chars */
406 if (syslog_is_stream)
412 n = sendmsg(syslog_fd, &msghdr, MSG_NOSIGNAL);
416 if (!syslog_is_stream ||
417 (size_t) n >= IOVEC_TOTAL_SIZE(iovec, ELEMENTSOF(iovec)))
420 IOVEC_INCREMENT(iovec, ELEMENTSOF(iovec), n);
426 static int write_to_kmsg(
432 const char *object_field,
434 const char *buffer) {
436 char header_priority[1 + DECIMAL_STR_MAX(int) + 2], header_pid[1 + DECIMAL_STR_MAX(pid_t) + 4];
437 struct iovec iovec[5] = {};
442 snprintf(header_priority, sizeof(header_priority), "<%i>", level);
443 char_array_0(header_priority);
445 snprintf(header_pid, sizeof(header_pid), "["PID_FMT"]: ", getpid());
446 char_array_0(header_pid);
448 IOVEC_SET_STRING(iovec[0], header_priority);
449 IOVEC_SET_STRING(iovec[1], program_invocation_short_name);
450 IOVEC_SET_STRING(iovec[2], header_pid);
451 IOVEC_SET_STRING(iovec[3], buffer);
452 IOVEC_SET_STRING(iovec[4], "\n");
454 if (writev(kmsg_fd, iovec, ELEMENTSOF(iovec)) < 0)
460 static int log_do_header(
465 const char *file, int line, const char *func,
466 const char *object_field, const char *object) {
468 snprintf(header, size,
470 "SYSLOG_FACILITY=%i\n"
476 "SYSLOG_IDENTIFIER=%s\n",
479 isempty(file) ? "" : "CODE_FILE=",
480 isempty(file) ? "" : file,
481 isempty(file) ? "" : "\n",
482 line ? "CODE_LINE=" : "",
483 line ? 1 : 0, line, /* %.0d means no output too, special case for 0 */
485 isempty(func) ? "" : "CODE_FUNCTION=",
486 isempty(func) ? "" : func,
487 isempty(func) ? "" : "\n",
488 error ? "ERRNO=" : "",
489 error ? 1 : 0, error,
491 isempty(object) ? "" : object_field,
492 isempty(object) ? "" : object,
493 isempty(object) ? "" : "\n",
494 program_invocation_short_name);
495 header[size - 1] = '\0';
500 static int write_to_journal(
506 const char *object_field,
508 const char *buffer) {
510 char header[LINE_MAX];
511 struct iovec iovec[4] = {};
512 struct msghdr mh = {};
517 log_do_header(header, sizeof(header), level, error, file, line, func, object_field, object);
519 IOVEC_SET_STRING(iovec[0], header);
520 IOVEC_SET_STRING(iovec[1], "MESSAGE=");
521 IOVEC_SET_STRING(iovec[2], buffer);
522 IOVEC_SET_STRING(iovec[3], "\n");
525 mh.msg_iovlen = ELEMENTSOF(iovec);
527 if (sendmsg(journal_fd, &mh, MSG_NOSIGNAL) < 0)
533 static int log_dispatch(
539 const char *object_field,
545 if (log_target == LOG_TARGET_NULL)
548 /* Patch in LOG_DAEMON facility if necessary */
549 if ((level & LOG_FACMASK) == 0)
550 level = log_facility | LOG_PRI(level);
559 buffer += strspn(buffer, NEWLINE);
564 if ((e = strpbrk(buffer, NEWLINE)))
567 if (log_target == LOG_TARGET_AUTO ||
568 log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
569 log_target == LOG_TARGET_JOURNAL) {
571 k = write_to_journal(level, error, file, line, func, object_field, object, buffer);
579 if (log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
580 log_target == LOG_TARGET_SYSLOG) {
582 k = write_to_syslog(level, error, file, line, func, object_field, object, buffer);
591 (log_target == LOG_TARGET_AUTO ||
592 log_target == LOG_TARGET_SAFE ||
593 log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
594 log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
595 log_target == LOG_TARGET_KMSG)) {
597 k = write_to_kmsg(level, error, file, line, func, object_field, object, buffer);
605 (void) write_to_console(level, error, file, line, func, object_field, object, buffer);
613 int log_dump_internal(
623 /* This modifies the buffer... */
628 if (_likely_(LOG_PRI(level) > log_max_level))
631 return log_dispatch(level, error, file, line, func, NULL, NULL, buffer);
644 char buffer[LINE_MAX];
649 if (_likely_(LOG_PRI(level) > log_max_level))
652 /* Make sure that %m maps to the specified error */
656 vsnprintf(buffer, sizeof(buffer), format, ap);
657 char_array_0(buffer);
659 return log_dispatch(level, error, file, line, func, NULL, NULL, buffer);
668 const char *format, ...) {
673 va_start(ap, format);
674 r = log_internalv(level, error, file, line, func, format, ap);
680 int log_object_internalv(
686 const char *object_field,
692 char buffer[LINE_MAX];
697 if (_likely_(LOG_PRI(level) > log_max_level))
700 /* Make sure that %m maps to the specified error */
704 vsnprintf(buffer, sizeof(buffer), format, ap);
705 char_array_0(buffer);
707 return log_dispatch(level, error, file, line, func, object_field, object, buffer);
710 int log_object_internal(
716 const char *object_field,
718 const char *format, ...) {
723 va_start(ap, format);
724 r = log_object_internalv(level, error, file, line, func, object_field, object, format, ap);
730 static void log_assert(
736 const char *format) {
738 static char buffer[LINE_MAX];
740 if (_likely_(LOG_PRI(level) > log_max_level))
743 DISABLE_WARNING_FORMAT_NONLITERAL;
744 snprintf(buffer, sizeof(buffer), format, text, file, line, func);
747 char_array_0(buffer);
748 log_abort_msg = buffer;
750 log_dispatch(level, 0, file, line, func, NULL, NULL, buffer);
753 noreturn void log_assert_failed(const char *text, const char *file, int line, const char *func) {
754 log_assert(LOG_CRIT, text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Aborting.");
758 noreturn void log_assert_failed_unreachable(const char *text, const char *file, int line, const char *func) {
759 log_assert(LOG_CRIT, text, file, line, func, "Code should not be reached '%s' at %s:%u, function %s(). Aborting.");
763 void log_assert_failed_return(const char *text, const char *file, int line, const char *func) {
765 log_assert(LOG_DEBUG, text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Ignoring.");
768 int log_oom_internal(const char *file, int line, const char *func) {
769 log_internal(LOG_ERR, ENOMEM, file, line, func, "Out of memory.");
773 int log_struct_internal(
779 const char *format, ...) {
789 if (_likely_(LOG_PRI(level) > log_max_level))
792 if (log_target == LOG_TARGET_NULL)
795 if ((level & LOG_FACMASK) == 0)
796 level = log_facility | LOG_PRI(level);
798 if ((log_target == LOG_TARGET_AUTO ||
799 log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
800 log_target == LOG_TARGET_JOURNAL) &&
802 char header[LINE_MAX];
803 struct iovec iovec[17] = {};
808 static const char nl = '\n';
809 bool fallback = false;
811 /* If the journal is available do structured logging */
812 log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL);
813 IOVEC_SET_STRING(iovec[n++], header);
815 va_start(ap, format);
816 while (format && n + 1 < ELEMENTSOF(iovec)) {
820 /* We need to copy the va_list structure,
821 * since vasprintf() leaves it afterwards at
822 * an undefined location */
828 if (vasprintf(&m, format, aq) < 0) {
835 /* Now, jump enough ahead, so that we point to
836 * the next format string */
837 VA_FORMAT_ADVANCE(format, ap);
839 IOVEC_SET_STRING(iovec[n++], m);
841 iovec[n].iov_base = (char*) &nl;
842 iovec[n].iov_len = 1;
845 format = va_arg(ap, char *);
850 (void) sendmsg(journal_fd, &mh, MSG_NOSIGNAL);
854 for (i = 1; i < n; i += 2)
855 free(iovec[i].iov_base);
861 /* Fallback if journal logging is not available or didn't work. */
863 va_start(ap, format);
871 vsnprintf(buf, sizeof(buf), format, aq);
875 if (startswith(buf, "MESSAGE=")) {
880 VA_FORMAT_ADVANCE(format, ap);
882 format = va_arg(ap, char *);
889 return log_dispatch(level, error, file, line, func, NULL, NULL, buf + 8);
892 int log_set_target_from_string(const char *e) {
895 t = log_target_from_string(e);
903 int log_set_max_level_from_string(const char *e) {
906 t = log_level_from_string(e);
910 log_set_max_level(t);
914 static int parse_proc_cmdline_item(const char *key, const char *value) {
917 * The systemd.log_xyz= settings are parsed by all tools, and
920 * However, "quiet" is only parsed by PID 1!
923 if (streq(key, "debug") && !value)
924 log_set_max_level(LOG_DEBUG);
926 else if (streq(key, "systemd.log_target") && value) {
928 if (log_set_target_from_string(value) < 0)
929 log_warning("Failed to parse log target '%s'. Ignoring.", value);
931 } else if (streq(key, "systemd.log_level") && value) {
933 if (log_set_max_level_from_string(value) < 0)
934 log_warning("Failed to parse log level '%s'. Ignoring.", value);
936 } else if (streq(key, "systemd.log_color") && value) {
938 if (log_show_color_from_string(value) < 0)
939 log_warning("Failed to parse log color setting '%s'. Ignoring.", value);
941 } else if (streq(key, "systemd.log_location") && value) {
943 if (log_show_location_from_string(value) < 0)
944 log_warning("Failed to parse log location setting '%s'. Ignoring.", value);
950 void log_parse_environment(void) {
953 (void) parse_proc_cmdline(parse_proc_cmdline_item);
955 e = secure_getenv("SYSTEMD_LOG_TARGET");
956 if (e && log_set_target_from_string(e) < 0)
957 log_warning("Failed to parse log target '%s'. Ignoring.", e);
959 e = secure_getenv("SYSTEMD_LOG_LEVEL");
960 if (e && log_set_max_level_from_string(e) < 0)
961 log_warning("Failed to parse log level '%s'. Ignoring.", e);
963 e = secure_getenv("SYSTEMD_LOG_COLOR");
964 if (e && log_show_color_from_string(e) < 0)
965 log_warning("Failed to parse bool '%s'. Ignoring.", e);
967 e = secure_getenv("SYSTEMD_LOG_LOCATION");
968 if (e && log_show_location_from_string(e) < 0)
969 log_warning("Failed to parse bool '%s'. Ignoring.", e);
972 LogTarget log_get_target(void) {
976 int log_get_max_level(void) {
977 return log_max_level;
980 void log_show_color(bool b) {
984 bool log_get_show_color(void) {
988 void log_show_location(bool b) {
992 bool log_get_show_location(void) {
993 return show_location;
996 int log_show_color_from_string(const char *e) {
999 t = parse_boolean(e);
1007 int log_show_location_from_string(const char *e) {
1010 t = parse_boolean(e);
1014 log_show_location(t);
1018 bool log_on_console(void) {
1019 if (log_target == LOG_TARGET_CONSOLE)
1022 return syslog_fd < 0 && kmsg_fd < 0 && journal_fd < 0;
1025 static const char *const log_target_table[_LOG_TARGET_MAX] = {
1026 [LOG_TARGET_CONSOLE] = "console",
1027 [LOG_TARGET_KMSG] = "kmsg",
1028 [LOG_TARGET_JOURNAL] = "journal",
1029 [LOG_TARGET_JOURNAL_OR_KMSG] = "journal-or-kmsg",
1030 [LOG_TARGET_SYSLOG] = "syslog",
1031 [LOG_TARGET_SYSLOG_OR_KMSG] = "syslog-or-kmsg",
1032 [LOG_TARGET_AUTO] = "auto",
1033 [LOG_TARGET_SAFE] = "safe",
1034 [LOG_TARGET_NULL] = "null"
1037 DEFINE_STRING_TABLE_LOOKUP(log_target, LogTarget);
1039 void log_received_signal(int level, const struct signalfd_siginfo *si) {
1040 if (si->ssi_pid > 0) {
1041 _cleanup_free_ char *p = NULL;
1043 get_process_comm(si->ssi_pid, &p);
1046 "Received SIG%s from PID "PID_FMT" (%s).",
1047 signal_to_string(si->ssi_signo),
1048 si->ssi_pid, strna(p));
1052 signal_to_string(si->ssi_signo));
1056 void log_set_upgrade_syslog_to_journal(bool b) {
1057 upgrade_syslog_to_journal = b;