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) {
119 /* All output to the syslog/journal fds we do asynchronously,
120 * and if the buffers are full we just drop the messages */
122 fd = socket(AF_UNIX, type|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
126 fd_inc_sndbuf(fd, SNDBUF_SIZE);
131 static int log_open_syslog(void) {
133 union sockaddr_union sa = {
134 .un.sun_family = AF_UNIX,
135 .un.sun_path = "/dev/log",
141 syslog_fd = create_log_socket(SOCK_DGRAM);
147 if (connect(syslog_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
148 close_nointr_nofail(syslog_fd);
150 /* Some legacy syslog systems still use stream
151 * sockets. They really shouldn't. But what can we
153 syslog_fd = create_log_socket(SOCK_STREAM);
159 if (connect(syslog_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
164 syslog_is_stream = true;
166 syslog_is_stream = false;
175 void log_close_journal(void) {
180 close_nointr_nofail(journal_fd);
184 static int log_open_journal(void) {
185 union sockaddr_union sa = {
186 .un.sun_family = AF_UNIX,
187 .un.sun_path = "/run/systemd/journal/socket",
194 journal_fd = create_log_socket(SOCK_DGRAM);
195 if (journal_fd < 0) {
200 if (connect(journal_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
215 /* If we don't use the console we close it here, to not get
216 * killed by SAK. If we don't use syslog we close it here so
217 * that we are not confused by somebody deleting the socket in
218 * the fs. If we don't use /dev/kmsg we still keep it open,
219 * because there is no reason to close it. */
221 if (log_target == LOG_TARGET_NULL) {
228 if ((log_target != LOG_TARGET_AUTO && log_target != LOG_TARGET_SAFE) ||
230 isatty(STDERR_FILENO) <= 0) {
232 if (log_target == LOG_TARGET_AUTO ||
233 log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
234 log_target == LOG_TARGET_JOURNAL) {
235 r = log_open_journal();
243 if (log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
244 log_target == LOG_TARGET_SYSLOG) {
245 r = log_open_syslog();
253 if (log_target == LOG_TARGET_AUTO ||
254 log_target == LOG_TARGET_SAFE ||
255 log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
256 log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
257 log_target == LOG_TARGET_KMSG) {
271 /* Get the real /dev/console if we are PID=1, hence reopen */
273 return log_open_console();
276 void log_set_target(LogTarget target) {
278 assert(target < _LOG_TARGET_MAX);
283 void log_close(void) {
290 void log_forget_fds(void) {
291 console_fd = kmsg_fd = syslog_fd = journal_fd = -1;
294 void log_set_max_level(int level) {
295 assert((level & LOG_PRIMASK) == level);
297 log_max_level = level;
300 void log_set_facility(int facility) {
301 log_facility = facility;
304 static int write_to_console(
309 const char *object_name,
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)
342 static int write_to_syslog(
347 const char *object_name,
349 const char *buffer) {
351 char header_priority[16], header_time[64], header_pid[16];
352 struct iovec iovec[5] = {};
353 struct msghdr msghdr = {
355 .msg_iovlen = ELEMENTSOF(iovec),
363 snprintf(header_priority, sizeof(header_priority), "<%i>", level);
364 char_array_0(header_priority);
366 t = (time_t) (now(CLOCK_REALTIME) / USEC_PER_SEC);
371 if (strftime(header_time, sizeof(header_time), "%h %e %T ", tm) <= 0)
374 snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) getpid());
375 char_array_0(header_pid);
377 IOVEC_SET_STRING(iovec[0], header_priority);
378 IOVEC_SET_STRING(iovec[1], header_time);
379 IOVEC_SET_STRING(iovec[2], program_invocation_short_name);
380 IOVEC_SET_STRING(iovec[3], header_pid);
381 IOVEC_SET_STRING(iovec[4], buffer);
383 /* When using syslog via SOCK_STREAM separate the messages by NUL chars */
384 if (syslog_is_stream)
390 n = sendmsg(syslog_fd, &msghdr, MSG_NOSIGNAL);
394 if (!syslog_is_stream ||
395 (size_t) n >= IOVEC_TOTAL_SIZE(iovec, ELEMENTSOF(iovec)))
398 IOVEC_INCREMENT(iovec, ELEMENTSOF(iovec), n);
404 static int write_to_kmsg(
409 const char *object_name,
411 const char *buffer) {
413 char header_priority[16], header_pid[16];
414 struct iovec iovec[5] = {};
419 snprintf(header_priority, sizeof(header_priority), "<%i>", level);
420 char_array_0(header_priority);
422 snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) getpid());
423 char_array_0(header_pid);
425 IOVEC_SET_STRING(iovec[0], header_priority);
426 IOVEC_SET_STRING(iovec[1], program_invocation_short_name);
427 IOVEC_SET_STRING(iovec[2], header_pid);
428 IOVEC_SET_STRING(iovec[3], buffer);
429 IOVEC_SET_STRING(iovec[4], "\n");
431 if (writev(kmsg_fd, iovec, ELEMENTSOF(iovec)) < 0)
437 static int log_do_header(char *header, size_t size,
439 const char *file, int line, const char *func,
440 const char *object_name, const char *object) {
441 snprintf(header, size,
443 "SYSLOG_FACILITY=%i\n"
448 "SYSLOG_IDENTIFIER=%s\n",
451 file ? "CODE_FILE=" : "",
452 file ? LINE_MAX : 0, file, /* %.0s means no output */
454 line ? "CODE_LINE=" : "",
455 line ? 1 : 0, line, /* %.0d means no output too, special case for 0 */
457 func ? "CODE_FUNCTION=" : "",
458 func ? LINE_MAX : 0, func,
460 object ? object_name : "",
461 object ? LINE_MAX : 0, object, /* %.0s means no output */
463 program_invocation_short_name);
464 header[size - 1] = '\0';
468 static int write_to_journal(
473 const char *object_name,
475 const char *buffer) {
477 char header[LINE_MAX];
478 struct iovec iovec[4] = {};
479 struct msghdr mh = {};
484 log_do_header(header, sizeof(header), level,
485 file, line, func, object_name, object);
487 IOVEC_SET_STRING(iovec[0], header);
488 IOVEC_SET_STRING(iovec[1], "MESSAGE=");
489 IOVEC_SET_STRING(iovec[2], buffer);
490 IOVEC_SET_STRING(iovec[3], "\n");
493 mh.msg_iovlen = ELEMENTSOF(iovec);
495 if (sendmsg(journal_fd, &mh, MSG_NOSIGNAL) < 0)
501 static int log_dispatch(
506 const char *object_name,
512 if (log_target == LOG_TARGET_NULL)
515 /* Patch in LOG_DAEMON facility if necessary */
516 if ((level & LOG_FACMASK) == 0)
517 level = log_facility | LOG_PRI(level);
523 buffer += strspn(buffer, NEWLINE);
528 if ((e = strpbrk(buffer, NEWLINE)))
531 if (log_target == LOG_TARGET_AUTO ||
532 log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
533 log_target == LOG_TARGET_JOURNAL) {
535 k = write_to_journal(level, file, line, func,
536 object_name, object, buffer);
545 if (log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
546 log_target == LOG_TARGET_SYSLOG) {
548 k = write_to_syslog(level, file, line, func,
549 object_name, object, buffer);
559 (log_target == LOG_TARGET_AUTO ||
560 log_target == LOG_TARGET_SAFE ||
561 log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
562 log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
563 log_target == LOG_TARGET_KMSG)) {
565 k = write_to_kmsg(level, file, line, func,
566 object_name, object, buffer);
575 k = write_to_console(level, file, line, func,
576 object_name, object, buffer);
587 int log_dump_internal(
596 /* This modifies the buffer... */
598 if (_likely_(LOG_PRI(level) > log_max_level))
601 return log_dispatch(level, file, line, func, NULL, NULL, buffer);
613 char buffer[LINE_MAX];
615 if (_likely_(LOG_PRI(level) > log_max_level))
618 vsnprintf(buffer, sizeof(buffer), format, ap);
619 char_array_0(buffer);
621 return log_dispatch(level, file, line, func, NULL, NULL, buffer);
629 const char *format, ...) {
634 va_start(ap, format);
635 r = log_metav(level, file, line, func, format, ap);
641 int log_metav_object(
646 const char *object_name,
652 char buffer[LINE_MAX];
654 if (_likely_(LOG_PRI(level) > log_max_level))
657 vsnprintf(buffer, sizeof(buffer), format, ap);
658 char_array_0(buffer);
660 return log_dispatch(level, file, line, func,
661 object_name, object, buffer);
669 const char *object_name,
671 const char *format, ...) {
676 va_start(ap, format);
677 r = log_metav_object(level, file, line, func,
678 object_name, object, format, ap);
684 #pragma GCC diagnostic push
685 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
686 _noreturn_ static void log_assert(const char *text, const char *file, int line, const char *func, const char *format) {
687 static char buffer[LINE_MAX];
689 snprintf(buffer, sizeof(buffer), format, text, file, line, func);
691 char_array_0(buffer);
692 log_abort_msg = buffer;
694 log_dispatch(LOG_CRIT, file, line, func, NULL, NULL, buffer);
697 #pragma GCC diagnostic pop
699 _noreturn_ void log_assert_failed(const char *text, const char *file, int line, const char *func) {
700 log_assert(text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Aborting.");
703 _noreturn_ void log_assert_failed_unreachable(const char *text, const char *file, int line, const char *func) {
704 log_assert(text, file, line, func, "Code should not be reached '%s' at %s:%u, function %s(). Aborting.");
707 int log_oom_internal(const char *file, int line, const char *func) {
708 log_meta(LOG_ERR, file, line, func, "Out of memory.");
712 int log_struct_internal(
717 const char *format, ...) {
723 if (_likely_(LOG_PRI(level) > log_max_level))
726 if (log_target == LOG_TARGET_NULL)
729 if ((level & LOG_FACMASK) == 0)
730 level = log_facility | LOG_PRI(level);
732 if ((log_target == LOG_TARGET_AUTO ||
733 log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
734 log_target == LOG_TARGET_JOURNAL) &&
737 char header[LINE_MAX];
738 struct iovec iovec[17] = {};
743 static const char nl = '\n';
745 /* If the journal is available do structured logging */
746 log_do_header(header, sizeof(header), level,
747 file, line, func, NULL, NULL);
748 IOVEC_SET_STRING(iovec[n++], header);
750 va_start(ap, format);
751 while (format && n + 1 < ELEMENTSOF(iovec)) {
755 /* We need to copy the va_list structure,
756 * since vasprintf() leaves it afterwards at
757 * an undefined location */
760 if (vasprintf(&buf, format, aq) < 0) {
767 /* Now, jump enough ahead, so that we point to
768 * the next format string */
769 VA_FORMAT_ADVANCE(format, ap);
771 IOVEC_SET_STRING(iovec[n++], buf);
773 iovec[n].iov_base = (char*) &nl;
774 iovec[n].iov_len = 1;
777 format = va_arg(ap, char *);
782 if (sendmsg(journal_fd, &mh, MSG_NOSIGNAL) < 0)
789 for (i = 1; i < n; i += 2)
790 free(iovec[i].iov_base);
796 /* Fallback if journal logging is not available */
798 va_start(ap, format);
803 vsnprintf(buf, sizeof(buf), format, aq);
807 if (startswith(buf, "MESSAGE=")) {
812 VA_FORMAT_ADVANCE(format, ap);
814 format = va_arg(ap, char *);
819 r = log_dispatch(level, file, line, func,
820 NULL, NULL, buf + 8);
828 int log_set_target_from_string(const char *e) {
831 t = log_target_from_string(e);
839 int log_set_max_level_from_string(const char *e) {
842 t = log_level_from_string(e);
846 log_set_max_level(t);
850 void log_parse_environment(void) {
853 e = secure_getenv("SYSTEMD_LOG_TARGET");
854 if (e && log_set_target_from_string(e) < 0)
855 log_warning("Failed to parse log target %s. Ignoring.", e);
857 e = secure_getenv("SYSTEMD_LOG_LEVEL");
858 if (e && log_set_max_level_from_string(e) < 0)
859 log_warning("Failed to parse log level %s. Ignoring.", e);
861 e = secure_getenv("SYSTEMD_LOG_COLOR");
862 if (e && log_show_color_from_string(e) < 0)
863 log_warning("Failed to parse bool %s. Ignoring.", e);
865 e = secure_getenv("SYSTEMD_LOG_LOCATION");
866 if (e && log_show_location_from_string(e) < 0)
867 log_warning("Failed to parse bool %s. Ignoring.", e);
870 LogTarget log_get_target(void) {
874 int log_get_max_level(void) {
875 return log_max_level;
878 void log_show_color(bool b) {
882 void log_show_location(bool b) {
886 int log_show_color_from_string(const char *e) {
889 t = parse_boolean(e);
897 int log_show_location_from_string(const char *e) {
900 t = parse_boolean(e);
904 log_show_location(t);
908 bool log_on_console(void) {
909 if (log_target == LOG_TARGET_CONSOLE)
912 return syslog_fd < 0 && kmsg_fd < 0 && journal_fd < 0;
915 static const char *const log_target_table[] = {
916 [LOG_TARGET_CONSOLE] = "console",
917 [LOG_TARGET_KMSG] = "kmsg",
918 [LOG_TARGET_JOURNAL] = "journal",
919 [LOG_TARGET_JOURNAL_OR_KMSG] = "journal-or-kmsg",
920 [LOG_TARGET_SYSLOG] = "syslog",
921 [LOG_TARGET_SYSLOG_OR_KMSG] = "syslog-or-kmsg",
922 [LOG_TARGET_AUTO] = "auto",
923 [LOG_TARGET_SAFE] = "safe",
924 [LOG_TARGET_NULL] = "null"
927 DEFINE_STRING_TABLE_LOOKUP(log_target, LogTarget);