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 union sockaddr_union sa = {
133 .un.sun_family = AF_UNIX,
134 .un.sun_path = "/dev/log",
140 syslog_fd = create_log_socket(SOCK_DGRAM);
146 if (connect(syslog_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
147 safe_close(syslog_fd);
149 /* Some legacy syslog systems still use stream
150 * sockets. They really shouldn't. But what can we
152 syslog_fd = create_log_socket(SOCK_STREAM);
158 if (connect(syslog_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
163 syslog_is_stream = true;
165 syslog_is_stream = false;
174 void log_close_journal(void) {
175 journal_fd = safe_close(journal_fd);
178 static int log_open_journal(void) {
179 union sockaddr_union sa = {
180 .un.sun_family = AF_UNIX,
181 .un.sun_path = "/run/systemd/journal/socket",
188 journal_fd = create_log_socket(SOCK_DGRAM);
189 if (journal_fd < 0) {
194 if (connect(journal_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
209 /* If we don't use the console we close it here, to not get
210 * killed by SAK. If we don't use syslog we close it here so
211 * that we are not confused by somebody deleting the socket in
212 * the fs. If we don't use /dev/kmsg we still keep it open,
213 * because there is no reason to close it. */
215 if (log_target == LOG_TARGET_NULL) {
222 if ((log_target != LOG_TARGET_AUTO && log_target != LOG_TARGET_SAFE) ||
224 isatty(STDERR_FILENO) <= 0) {
226 if (log_target == LOG_TARGET_AUTO ||
227 log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
228 log_target == LOG_TARGET_JOURNAL) {
229 r = log_open_journal();
237 if (log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
238 log_target == LOG_TARGET_SYSLOG) {
239 r = log_open_syslog();
247 if (log_target == LOG_TARGET_AUTO ||
248 log_target == LOG_TARGET_SAFE ||
249 log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
250 log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
251 log_target == LOG_TARGET_KMSG) {
265 return log_open_console();
268 void log_set_target(LogTarget target) {
270 assert(target < _LOG_TARGET_MAX);
272 if (upgrade_syslog_to_journal) {
273 if (target == LOG_TARGET_SYSLOG)
274 target = LOG_TARGET_JOURNAL;
275 else if (target == LOG_TARGET_SYSLOG_OR_KMSG)
276 target = LOG_TARGET_JOURNAL_OR_KMSG;
282 void log_close(void) {
289 void log_forget_fds(void) {
290 console_fd = kmsg_fd = syslog_fd = journal_fd = -1;
293 void log_set_max_level(int level) {
294 assert((level & LOG_PRIMASK) == level);
296 log_max_level = level;
299 void log_set_facility(int facility) {
300 log_facility = facility;
303 static int write_to_console(
309 const char *object_field,
311 const char *buffer) {
314 struct iovec iovec[5] = {};
321 highlight = LOG_PRI(level) <= LOG_ERR && show_color;
324 snprintf(location, sizeof(location), "(%s:%u) ", file, line);
325 char_array_0(location);
326 IOVEC_SET_STRING(iovec[n++], location);
330 IOVEC_SET_STRING(iovec[n++], ANSI_HIGHLIGHT_RED_ON);
331 IOVEC_SET_STRING(iovec[n++], buffer);
333 IOVEC_SET_STRING(iovec[n++], ANSI_HIGHLIGHT_OFF);
334 IOVEC_SET_STRING(iovec[n++], "\n");
336 if (writev(console_fd, iovec, n) < 0) {
338 if (errno == EIO && getpid() == 1) {
340 /* If somebody tried to kick us from our
341 * console tty (via vhangup() or suchlike),
342 * try to reconnect */
350 if (writev(console_fd, iovec, n) < 0)
359 static int write_to_syslog(
365 const char *object_field,
367 const char *buffer) {
369 char header_priority[1 + DECIMAL_STR_MAX(int) + 2], header_time[64], header_pid[1 + DECIMAL_STR_MAX(pid_t) + 4];
370 struct iovec iovec[5] = {};
371 struct msghdr msghdr = {
373 .msg_iovlen = ELEMENTSOF(iovec),
381 snprintf(header_priority, sizeof(header_priority), "<%i>", level);
382 char_array_0(header_priority);
384 t = (time_t) (now(CLOCK_REALTIME) / USEC_PER_SEC);
389 if (strftime(header_time, sizeof(header_time), "%h %e %T ", tm) <= 0)
392 snprintf(header_pid, sizeof(header_pid), "["PID_FMT"]: ", getpid());
393 char_array_0(header_pid);
395 IOVEC_SET_STRING(iovec[0], header_priority);
396 IOVEC_SET_STRING(iovec[1], header_time);
397 IOVEC_SET_STRING(iovec[2], program_invocation_short_name);
398 IOVEC_SET_STRING(iovec[3], header_pid);
399 IOVEC_SET_STRING(iovec[4], buffer);
401 /* When using syslog via SOCK_STREAM separate the messages by NUL chars */
402 if (syslog_is_stream)
408 n = sendmsg(syslog_fd, &msghdr, MSG_NOSIGNAL);
412 if (!syslog_is_stream ||
413 (size_t) n >= IOVEC_TOTAL_SIZE(iovec, ELEMENTSOF(iovec)))
416 IOVEC_INCREMENT(iovec, ELEMENTSOF(iovec), n);
422 static int write_to_kmsg(
428 const char *object_field,
430 const char *buffer) {
432 char header_priority[1 + DECIMAL_STR_MAX(int) + 2], header_pid[1 + DECIMAL_STR_MAX(pid_t) + 4];
433 struct iovec iovec[5] = {};
438 snprintf(header_priority, sizeof(header_priority), "<%i>", level);
439 char_array_0(header_priority);
441 snprintf(header_pid, sizeof(header_pid), "["PID_FMT"]: ", getpid());
442 char_array_0(header_pid);
444 IOVEC_SET_STRING(iovec[0], header_priority);
445 IOVEC_SET_STRING(iovec[1], program_invocation_short_name);
446 IOVEC_SET_STRING(iovec[2], header_pid);
447 IOVEC_SET_STRING(iovec[3], buffer);
448 IOVEC_SET_STRING(iovec[4], "\n");
450 if (writev(kmsg_fd, iovec, ELEMENTSOF(iovec)) < 0)
456 static int log_do_header(
461 const char *file, int line, const char *func,
462 const char *object_field, const char *object) {
464 snprintf(header, size,
466 "SYSLOG_FACILITY=%i\n"
472 "SYSLOG_IDENTIFIER=%s\n",
475 isempty(file) ? "" : "CODE_FILE=",
476 isempty(file) ? "" : file,
477 isempty(file) ? "" : "\n",
478 line ? "CODE_LINE=" : "",
479 line ? 1 : 0, line, /* %.0d means no output too, special case for 0 */
481 isempty(func) ? "" : "CODE_FUNCTION=",
482 isempty(func) ? "" : func,
483 isempty(func) ? "" : "\n",
484 error ? "ERRNO=" : "",
485 error ? 1 : 0, error,
487 isempty(object) ? "" : object_field,
488 isempty(object) ? "" : object,
489 isempty(object) ? "" : "\n",
490 program_invocation_short_name);
491 header[size - 1] = '\0';
496 static int write_to_journal(
502 const char *object_field,
504 const char *buffer) {
506 char header[LINE_MAX];
507 struct iovec iovec[4] = {};
508 struct msghdr mh = {};
513 log_do_header(header, sizeof(header), level, error, file, line, func, object_field, object);
515 IOVEC_SET_STRING(iovec[0], header);
516 IOVEC_SET_STRING(iovec[1], "MESSAGE=");
517 IOVEC_SET_STRING(iovec[2], buffer);
518 IOVEC_SET_STRING(iovec[3], "\n");
521 mh.msg_iovlen = ELEMENTSOF(iovec);
523 if (sendmsg(journal_fd, &mh, MSG_NOSIGNAL) < 0)
529 static int log_dispatch(
535 const char *object_field,
541 if (log_target == LOG_TARGET_NULL)
544 /* Patch in LOG_DAEMON facility if necessary */
545 if ((level & LOG_FACMASK) == 0)
546 level = log_facility | LOG_PRI(level);
555 buffer += strspn(buffer, NEWLINE);
560 if ((e = strpbrk(buffer, NEWLINE)))
563 if (log_target == LOG_TARGET_AUTO ||
564 log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
565 log_target == LOG_TARGET_JOURNAL) {
567 k = write_to_journal(level, error, file, line, func, object_field, object, buffer);
576 if (log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
577 log_target == LOG_TARGET_SYSLOG) {
579 k = write_to_syslog(level, error, file, line, func, object_field, object, buffer);
589 (log_target == LOG_TARGET_AUTO ||
590 log_target == LOG_TARGET_SAFE ||
591 log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
592 log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
593 log_target == LOG_TARGET_KMSG)) {
595 k = write_to_kmsg(level, error, file, line, func, object_field, object, buffer);
604 k = write_to_console(level, error, file, line, func, object_field, object, buffer);
615 int log_dump_internal(
625 /* This modifies the buffer... */
627 if (_likely_(LOG_PRI(level) > log_max_level))
630 return log_dispatch(level, error, file, line, func, NULL, NULL, buffer);
643 char buffer[LINE_MAX];
645 if (_likely_(LOG_PRI(level) > log_max_level))
648 /* Make sure that %m maps to the specified error */
652 vsnprintf(buffer, sizeof(buffer), format, ap);
653 char_array_0(buffer);
655 return log_dispatch(level, error, file, line, func, NULL, NULL, buffer);
664 const char *format, ...) {
669 va_start(ap, format);
670 r = log_internalv(level, error, file, line, func, format, ap);
676 int log_object_internalv(
682 const char *object_field,
688 char buffer[LINE_MAX];
690 if (_likely_(LOG_PRI(level) > log_max_level))
693 /* Make sure that %m maps to the specified error */
697 vsnprintf(buffer, sizeof(buffer), format, ap);
698 char_array_0(buffer);
700 return log_dispatch(level, error, file, line, func, object_field, object, buffer);
703 int log_object_internal(
709 const char *object_field,
711 const char *format, ...) {
716 va_start(ap, format);
717 r = log_object_internalv(level, error, file, line, func, object_field, object, format, ap);
723 static void log_assert(
729 const char *format) {
731 static char buffer[LINE_MAX];
733 if (_likely_(LOG_PRI(level) > log_max_level))
736 DISABLE_WARNING_FORMAT_NONLITERAL;
737 snprintf(buffer, sizeof(buffer), format, text, file, line, func);
740 char_array_0(buffer);
741 log_abort_msg = buffer;
743 log_dispatch(level, 0, file, line, func, NULL, NULL, buffer);
746 noreturn void log_assert_failed(const char *text, const char *file, int line, const char *func) {
747 log_assert(LOG_CRIT, text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Aborting.");
751 noreturn void log_assert_failed_unreachable(const char *text, const char *file, int line, const char *func) {
752 log_assert(LOG_CRIT, text, file, line, func, "Code should not be reached '%s' at %s:%u, function %s(). Aborting.");
756 void log_assert_failed_return(const char *text, const char *file, int line, const char *func) {
758 log_assert(LOG_DEBUG, text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Ignoring.");
761 int log_oom_internal(const char *file, int line, const char *func) {
762 log_internal(LOG_ERR, ENOMEM, file, line, func, "Out of memory.");
766 int log_struct_internal(
772 const char *format, ...) {
778 if (_likely_(LOG_PRI(level) > log_max_level))
781 if (log_target == LOG_TARGET_NULL)
784 if ((level & LOG_FACMASK) == 0)
785 level = log_facility | LOG_PRI(level);
790 if ((log_target == LOG_TARGET_AUTO ||
791 log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
792 log_target == LOG_TARGET_JOURNAL) &&
795 char header[LINE_MAX];
796 struct iovec iovec[17] = {};
801 static const char nl = '\n';
803 /* If the journal is available do structured logging */
804 log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL);
805 IOVEC_SET_STRING(iovec[n++], header);
807 va_start(ap, format);
808 while (format && n + 1 < ELEMENTSOF(iovec)) {
812 /* We need to copy the va_list structure,
813 * since vasprintf() leaves it afterwards at
814 * an undefined location */
817 if (vasprintf(&buf, format, aq) < 0) {
824 /* Now, jump enough ahead, so that we point to
825 * the next format string */
826 VA_FORMAT_ADVANCE(format, ap);
828 IOVEC_SET_STRING(iovec[n++], buf);
830 iovec[n].iov_base = (char*) &nl;
831 iovec[n].iov_len = 1;
834 format = va_arg(ap, char *);
839 if (sendmsg(journal_fd, &mh, MSG_NOSIGNAL) < 0)
846 for (i = 1; i < n; i += 2)
847 free(iovec[i].iov_base);
853 /* Fallback if journal logging is not available */
855 va_start(ap, format);
860 vsnprintf(buf, sizeof(buf), format, aq);
864 if (startswith(buf, "MESSAGE=")) {
869 VA_FORMAT_ADVANCE(format, ap);
871 format = va_arg(ap, char *);
876 r = log_dispatch(level, error, file, line, func, NULL, NULL, buf + 8);
884 int log_set_target_from_string(const char *e) {
887 t = log_target_from_string(e);
895 int log_set_max_level_from_string(const char *e) {
898 t = log_level_from_string(e);
902 log_set_max_level(t);
906 static int parse_proc_cmdline_item(const char *key, const char *value) {
909 * The systemd.log_xyz= settings are parsed by all tools, and
912 * However, "quiet" is only parsed by PID 1!
915 if (streq(key, "debug") && !value)
916 log_set_max_level(LOG_DEBUG);
918 else if (streq(key, "systemd.log_target") && value) {
920 if (log_set_target_from_string(value) < 0)
921 log_warning("Failed to parse log target '%s'. Ignoring.", value);
923 } else if (streq(key, "systemd.log_level") && value) {
925 if (log_set_max_level_from_string(value) < 0)
926 log_warning("Failed to parse log level '%s'. Ignoring.", value);
928 } else if (streq(key, "systemd.log_color") && value) {
930 if (log_show_color_from_string(value) < 0)
931 log_warning("Failed to parse log color setting '%s'. Ignoring.", value);
933 } else if (streq(key, "systemd.log_location") && value) {
935 if (log_show_location_from_string(value) < 0)
936 log_warning("Failed to parse log location setting '%s'. Ignoring.", value);
942 void log_parse_environment(void) {
945 (void) parse_proc_cmdline(parse_proc_cmdline_item);
947 e = secure_getenv("SYSTEMD_LOG_TARGET");
948 if (e && log_set_target_from_string(e) < 0)
949 log_warning("Failed to parse log target '%s'. Ignoring.", e);
951 e = secure_getenv("SYSTEMD_LOG_LEVEL");
952 if (e && log_set_max_level_from_string(e) < 0)
953 log_warning("Failed to parse log level '%s'. Ignoring.", e);
955 e = secure_getenv("SYSTEMD_LOG_COLOR");
956 if (e && log_show_color_from_string(e) < 0)
957 log_warning("Failed to parse bool '%s'. Ignoring.", e);
959 e = secure_getenv("SYSTEMD_LOG_LOCATION");
960 if (e && log_show_location_from_string(e) < 0)
961 log_warning("Failed to parse bool '%s'. Ignoring.", e);
964 LogTarget log_get_target(void) {
968 int log_get_max_level(void) {
969 return log_max_level;
972 void log_show_color(bool b) {
976 bool log_get_show_color(void) {
980 void log_show_location(bool b) {
984 bool log_get_show_location(void) {
985 return show_location;
988 int log_show_color_from_string(const char *e) {
991 t = parse_boolean(e);
999 int log_show_location_from_string(const char *e) {
1002 t = parse_boolean(e);
1006 log_show_location(t);
1010 bool log_on_console(void) {
1011 if (log_target == LOG_TARGET_CONSOLE)
1014 return syslog_fd < 0 && kmsg_fd < 0 && journal_fd < 0;
1017 static const char *const log_target_table[_LOG_TARGET_MAX] = {
1018 [LOG_TARGET_CONSOLE] = "console",
1019 [LOG_TARGET_KMSG] = "kmsg",
1020 [LOG_TARGET_JOURNAL] = "journal",
1021 [LOG_TARGET_JOURNAL_OR_KMSG] = "journal-or-kmsg",
1022 [LOG_TARGET_SYSLOG] = "syslog",
1023 [LOG_TARGET_SYSLOG_OR_KMSG] = "syslog-or-kmsg",
1024 [LOG_TARGET_AUTO] = "auto",
1025 [LOG_TARGET_SAFE] = "safe",
1026 [LOG_TARGET_NULL] = "null"
1029 DEFINE_STRING_TABLE_LOOKUP(log_target, LogTarget);
1031 void log_received_signal(int level, const struct signalfd_siginfo *si) {
1032 if (si->ssi_pid > 0) {
1033 _cleanup_free_ char *p = NULL;
1035 get_process_comm(si->ssi_pid, &p);
1038 "Received SIG%s from PID "PID_FMT" (%s).",
1039 signal_to_string(si->ssi_signo),
1040 si->ssi_pid, strna(p));
1044 signal_to_string(si->ssi_signo));
1048 void log_set_upgrade_syslog_to_journal(bool b) {
1049 upgrade_syslog_to_journal = b;