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 /* Akin to glibc's __abort_msg; which is private and we hence cannot
56 static char *log_abort_msg = NULL;
58 void log_close_console(void) {
65 close_nointr_nofail(console_fd);
71 static int log_open_console(void) {
77 console_fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
81 console_fd = STDERR_FILENO;
86 void log_close_kmsg(void) {
91 close_nointr_nofail(kmsg_fd);
95 static int log_open_kmsg(void) {
100 kmsg_fd = open("/dev/kmsg", O_WRONLY|O_NOCTTY|O_CLOEXEC);
107 void log_close_syslog(void) {
112 close_nointr_nofail(syslog_fd);
116 static int create_log_socket(int type) {
120 fd = socket(AF_UNIX, type|SOCK_CLOEXEC, 0);
124 fd_inc_sndbuf(fd, SNDBUF_SIZE);
126 /* We need a blocking fd here since we'd otherwise lose
127 messages way too early. However, let's not hang forever in the
128 unlikely case of a deadlock. */
129 timeval_store(&tv, 1*USEC_PER_MINUTE);
130 setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
135 static int log_open_syslog(void) {
137 union sockaddr_union sa = {
138 .un.sun_family = AF_UNIX,
139 .un.sun_path = "/dev/log",
145 syslog_fd = create_log_socket(SOCK_DGRAM);
151 if (connect(syslog_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
152 close_nointr_nofail(syslog_fd);
154 /* Some legacy syslog systems still use stream
155 * sockets. They really shouldn't. But what can we
157 syslog_fd = create_log_socket(SOCK_STREAM);
163 if (connect(syslog_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
168 syslog_is_stream = true;
170 syslog_is_stream = false;
179 void log_close_journal(void) {
184 close_nointr_nofail(journal_fd);
188 static int log_open_journal(void) {
189 union sockaddr_union sa = {
190 .un.sun_family = AF_UNIX,
191 .un.sun_path = "/run/systemd/journal/socket",
198 journal_fd = create_log_socket(SOCK_DGRAM);
199 if (journal_fd < 0) {
204 if (connect(journal_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
219 /* If we don't use the console we close it here, to not get
220 * killed by SAK. If we don't use syslog we close it here so
221 * that we are not confused by somebody deleting the socket in
222 * the fs. If we don't use /dev/kmsg we still keep it open,
223 * because there is no reason to close it. */
225 if (log_target == LOG_TARGET_NULL) {
232 if ((log_target != LOG_TARGET_AUTO && log_target != LOG_TARGET_SAFE) ||
234 isatty(STDERR_FILENO) <= 0) {
236 if (log_target == LOG_TARGET_AUTO ||
237 log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
238 log_target == LOG_TARGET_JOURNAL) {
239 r = log_open_journal();
247 if (log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
248 log_target == LOG_TARGET_SYSLOG) {
249 r = log_open_syslog();
257 if (log_target == LOG_TARGET_AUTO ||
258 log_target == LOG_TARGET_SAFE ||
259 log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
260 log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
261 log_target == LOG_TARGET_KMSG) {
275 return log_open_console();
278 void log_set_target(LogTarget target) {
280 assert(target < _LOG_TARGET_MAX);
285 void log_close(void) {
292 void log_forget_fds(void) {
293 console_fd = kmsg_fd = syslog_fd = journal_fd = -1;
296 void log_set_max_level(int level) {
297 assert((level & LOG_PRIMASK) == level);
299 log_max_level = level;
302 void log_set_facility(int facility) {
303 log_facility = facility;
306 static int write_to_console(
311 const char *object_name,
313 const char *buffer) {
316 struct iovec iovec[5] = {};
323 highlight = LOG_PRI(level) <= LOG_ERR && show_color;
326 snprintf(location, sizeof(location), "(%s:%u) ", file, line);
327 char_array_0(location);
328 IOVEC_SET_STRING(iovec[n++], location);
332 IOVEC_SET_STRING(iovec[n++], ANSI_HIGHLIGHT_RED_ON);
333 IOVEC_SET_STRING(iovec[n++], buffer);
335 IOVEC_SET_STRING(iovec[n++], ANSI_HIGHLIGHT_OFF);
336 IOVEC_SET_STRING(iovec[n++], "\n");
338 if (writev(console_fd, iovec, n) < 0) {
340 if (errno == EIO && getpid() == 1) {
342 /* If somebody tried to kick us from our
343 * console tty (via vhangup() or suchlike),
344 * try to reconnect */
352 if (writev(console_fd, iovec, n) < 0)
361 static int write_to_syslog(
366 const char *object_name,
368 const char *buffer) {
370 char header_priority[16], header_time[64], header_pid[16];
371 struct iovec iovec[5] = {};
372 struct msghdr msghdr = {
374 .msg_iovlen = ELEMENTSOF(iovec),
382 snprintf(header_priority, sizeof(header_priority), "<%i>", level);
383 char_array_0(header_priority);
385 t = (time_t) (now(CLOCK_REALTIME) / USEC_PER_SEC);
390 if (strftime(header_time, sizeof(header_time), "%h %e %T ", tm) <= 0)
393 snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) getpid());
394 char_array_0(header_pid);
396 IOVEC_SET_STRING(iovec[0], header_priority);
397 IOVEC_SET_STRING(iovec[1], header_time);
398 IOVEC_SET_STRING(iovec[2], program_invocation_short_name);
399 IOVEC_SET_STRING(iovec[3], header_pid);
400 IOVEC_SET_STRING(iovec[4], buffer);
402 /* When using syslog via SOCK_STREAM separate the messages by NUL chars */
403 if (syslog_is_stream)
409 n = sendmsg(syslog_fd, &msghdr, MSG_NOSIGNAL);
413 if (!syslog_is_stream ||
414 (size_t) n >= IOVEC_TOTAL_SIZE(iovec, ELEMENTSOF(iovec)))
417 IOVEC_INCREMENT(iovec, ELEMENTSOF(iovec), n);
423 static int write_to_kmsg(
428 const char *object_name,
430 const char *buffer) {
432 char header_priority[16], header_pid[16];
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), "[%lu]: ", (unsigned long) 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(char *header, size_t size,
458 const char *file, int line, const char *func,
459 const char *object_name, const char *object) {
460 snprintf(header, size,
462 "SYSLOG_FACILITY=%i\n"
467 "SYSLOG_IDENTIFIER=%s\n",
470 file ? "CODE_FILE=" : "",
471 file ? LINE_MAX : 0, file, /* %.0s means no output */
473 line ? "CODE_LINE=" : "",
474 line ? 1 : 0, line, /* %.0d means no output too, special case for 0 */
476 func ? "CODE_FUNCTION=" : "",
477 func ? LINE_MAX : 0, func,
479 object ? object_name : "",
480 object ? LINE_MAX : 0, object, /* %.0s means no output */
482 program_invocation_short_name);
483 header[size - 1] = '\0';
487 static int write_to_journal(
492 const char *object_name,
494 const char *buffer) {
496 char header[LINE_MAX];
497 struct iovec iovec[4] = {};
498 struct msghdr mh = {};
503 log_do_header(header, sizeof(header), level,
504 file, line, func, object_name, object);
506 IOVEC_SET_STRING(iovec[0], header);
507 IOVEC_SET_STRING(iovec[1], "MESSAGE=");
508 IOVEC_SET_STRING(iovec[2], buffer);
509 IOVEC_SET_STRING(iovec[3], "\n");
512 mh.msg_iovlen = ELEMENTSOF(iovec);
514 if (sendmsg(journal_fd, &mh, MSG_NOSIGNAL) < 0)
520 static int log_dispatch(
525 const char *object_name,
531 if (log_target == LOG_TARGET_NULL)
534 /* Patch in LOG_DAEMON facility if necessary */
535 if ((level & LOG_FACMASK) == 0)
536 level = log_facility | LOG_PRI(level);
542 buffer += strspn(buffer, NEWLINE);
547 if ((e = strpbrk(buffer, NEWLINE)))
550 if (log_target == LOG_TARGET_AUTO ||
551 log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
552 log_target == LOG_TARGET_JOURNAL) {
554 k = write_to_journal(level, file, line, func,
555 object_name, object, buffer);
564 if (log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
565 log_target == LOG_TARGET_SYSLOG) {
567 k = write_to_syslog(level, file, line, func,
568 object_name, object, buffer);
578 (log_target == LOG_TARGET_AUTO ||
579 log_target == LOG_TARGET_SAFE ||
580 log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
581 log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
582 log_target == LOG_TARGET_KMSG)) {
584 k = write_to_kmsg(level, file, line, func,
585 object_name, object, buffer);
594 k = write_to_console(level, file, line, func,
595 object_name, object, buffer);
606 int log_dump_internal(
615 /* This modifies the buffer... */
617 if (_likely_(LOG_PRI(level) > log_max_level))
620 return log_dispatch(level, file, line, func, NULL, NULL, buffer);
632 char buffer[LINE_MAX];
634 if (_likely_(LOG_PRI(level) > log_max_level))
637 vsnprintf(buffer, sizeof(buffer), format, ap);
638 char_array_0(buffer);
640 return log_dispatch(level, file, line, func, NULL, NULL, buffer);
648 const char *format, ...) {
653 va_start(ap, format);
654 r = log_metav(level, file, line, func, format, ap);
660 int log_metav_object(
665 const char *object_name,
671 char buffer[LINE_MAX];
673 if (_likely_(LOG_PRI(level) > log_max_level))
676 vsnprintf(buffer, sizeof(buffer), format, ap);
677 char_array_0(buffer);
679 return log_dispatch(level, file, line, func,
680 object_name, object, buffer);
688 const char *object_name,
690 const char *format, ...) {
695 va_start(ap, format);
696 r = log_metav_object(level, file, line, func,
697 object_name, object, format, ap);
703 #pragma GCC diagnostic push
704 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
705 static void log_assert(int level, const char *text, const char *file, int line, const char *func, const char *format) {
706 static char buffer[LINE_MAX];
708 if (_likely_(LOG_PRI(level) > log_max_level))
711 snprintf(buffer, sizeof(buffer), format, text, file, line, func);
713 char_array_0(buffer);
714 log_abort_msg = buffer;
716 log_dispatch(level, file, line, func, NULL, NULL, buffer);
718 #pragma GCC diagnostic pop
720 noreturn void log_assert_failed(const char *text, const char *file, int line, const char *func) {
721 log_assert(LOG_CRIT, text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Aborting.");
725 noreturn void log_assert_failed_unreachable(const char *text, const char *file, int line, const char *func) {
726 log_assert(LOG_CRIT, text, file, line, func, "Code should not be reached '%s' at %s:%u, function %s(). Aborting.");
730 void log_assert_failed_return(const char *text, const char *file, int line, const char *func) {
732 log_assert(LOG_DEBUG, text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Ignoring.");
735 int log_oom_internal(const char *file, int line, const char *func) {
736 log_meta(LOG_ERR, file, line, func, "Out of memory.");
740 int log_struct_internal(
745 const char *format, ...) {
751 if (_likely_(LOG_PRI(level) > log_max_level))
754 if (log_target == LOG_TARGET_NULL)
757 if ((level & LOG_FACMASK) == 0)
758 level = log_facility | LOG_PRI(level);
760 if ((log_target == LOG_TARGET_AUTO ||
761 log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
762 log_target == LOG_TARGET_JOURNAL) &&
765 char header[LINE_MAX];
766 struct iovec iovec[17] = {};
771 static const char nl = '\n';
773 /* If the journal is available do structured logging */
774 log_do_header(header, sizeof(header), level,
775 file, line, func, NULL, NULL);
776 IOVEC_SET_STRING(iovec[n++], header);
778 va_start(ap, format);
779 while (format && n + 1 < ELEMENTSOF(iovec)) {
783 /* We need to copy the va_list structure,
784 * since vasprintf() leaves it afterwards at
785 * an undefined location */
788 if (vasprintf(&buf, format, aq) < 0) {
795 /* Now, jump enough ahead, so that we point to
796 * the next format string */
797 VA_FORMAT_ADVANCE(format, ap);
799 IOVEC_SET_STRING(iovec[n++], buf);
801 iovec[n].iov_base = (char*) &nl;
802 iovec[n].iov_len = 1;
805 format = va_arg(ap, char *);
810 if (sendmsg(journal_fd, &mh, MSG_NOSIGNAL) < 0)
817 for (i = 1; i < n; i += 2)
818 free(iovec[i].iov_base);
824 /* Fallback if journal logging is not available */
826 va_start(ap, format);
831 vsnprintf(buf, sizeof(buf), format, aq);
835 if (startswith(buf, "MESSAGE=")) {
840 VA_FORMAT_ADVANCE(format, ap);
842 format = va_arg(ap, char *);
847 r = log_dispatch(level, file, line, func,
848 NULL, NULL, buf + 8);
856 int log_set_target_from_string(const char *e) {
859 t = log_target_from_string(e);
867 int log_set_max_level_from_string(const char *e) {
870 t = log_level_from_string(e);
874 log_set_max_level(t);
878 void log_parse_environment(void) {
881 e = secure_getenv("SYSTEMD_LOG_TARGET");
882 if (e && log_set_target_from_string(e) < 0)
883 log_warning("Failed to parse log target %s. Ignoring.", e);
885 e = secure_getenv("SYSTEMD_LOG_LEVEL");
886 if (e && log_set_max_level_from_string(e) < 0)
887 log_warning("Failed to parse log level %s. Ignoring.", e);
889 e = secure_getenv("SYSTEMD_LOG_COLOR");
890 if (e && log_show_color_from_string(e) < 0)
891 log_warning("Failed to parse bool %s. Ignoring.", e);
893 e = secure_getenv("SYSTEMD_LOG_LOCATION");
894 if (e && log_show_location_from_string(e) < 0)
895 log_warning("Failed to parse bool %s. Ignoring.", e);
898 LogTarget log_get_target(void) {
902 int log_get_max_level(void) {
903 return log_max_level;
906 void log_show_color(bool b) {
910 void log_show_location(bool b) {
914 int log_show_color_from_string(const char *e) {
917 t = parse_boolean(e);
925 int log_show_location_from_string(const char *e) {
928 t = parse_boolean(e);
932 log_show_location(t);
936 bool log_on_console(void) {
937 if (log_target == LOG_TARGET_CONSOLE)
940 return syslog_fd < 0 && kmsg_fd < 0 && journal_fd < 0;
943 static const char *const log_target_table[] = {
944 [LOG_TARGET_CONSOLE] = "console",
945 [LOG_TARGET_KMSG] = "kmsg",
946 [LOG_TARGET_JOURNAL] = "journal",
947 [LOG_TARGET_JOURNAL_OR_KMSG] = "journal-or-kmsg",
948 [LOG_TARGET_SYSLOG] = "syslog",
949 [LOG_TARGET_SYSLOG_OR_KMSG] = "syslog-or-kmsg",
950 [LOG_TARGET_AUTO] = "auto",
951 [LOG_TARGET_SAFE] = "safe",
952 [LOG_TARGET_NULL] = "null"
955 DEFINE_STRING_TABLE_LOOKUP(log_target, LogTarget);