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) {
132 union sockaddr_union sa;
139 sa.un.sun_family = AF_UNIX;
140 strncpy(sa.un.sun_path, "/dev/log", sizeof(sa.un.sun_path));
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 close_nointr_nofail(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) {
181 close_nointr_nofail(journal_fd);
185 static int log_open_journal(void) {
186 union sockaddr_union sa;
192 journal_fd = create_log_socket(SOCK_DGRAM);
193 if (journal_fd < 0) {
199 sa.un.sun_family = AF_UNIX;
200 strncpy(sa.un.sun_path, "/run/systemd/journal/socket", sizeof(sa.un.sun_path));
202 if (connect(journal_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
217 /* If we don't use the console we close it here, to not get
218 * killed by SAK. If we don't use syslog we close it here so
219 * that we are not confused by somebody deleting the socket in
220 * the fs. If we don't use /dev/kmsg we still keep it open,
221 * because there is no reason to close it. */
223 if (log_target == LOG_TARGET_NULL) {
230 if ((log_target != LOG_TARGET_AUTO && log_target != LOG_TARGET_SAFE) ||
232 isatty(STDERR_FILENO) <= 0) {
234 if (log_target == LOG_TARGET_AUTO ||
235 log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
236 log_target == LOG_TARGET_JOURNAL) {
237 r = log_open_journal();
245 if (log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
246 log_target == LOG_TARGET_SYSLOG) {
247 r = log_open_syslog();
255 if (log_target == LOG_TARGET_AUTO ||
256 log_target == LOG_TARGET_SAFE ||
257 log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
258 log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
259 log_target == LOG_TARGET_KMSG) {
273 /* Get the real /dev/console if we are PID=1, hence reopen */
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 *buffer) {
314 struct iovec iovec[5];
321 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)
344 static int write_to_syslog(
349 const char *buffer) {
351 char header_priority[16], header_time[64], header_pid[16];
352 struct iovec iovec[5];
353 struct msghdr msghdr;
360 snprintf(header_priority, sizeof(header_priority), "<%i>", level);
361 char_array_0(header_priority);
363 t = (time_t) (now(CLOCK_REALTIME) / USEC_PER_SEC);
364 if (!(tm = localtime(&t)))
367 if (strftime(header_time, sizeof(header_time), "%h %e %T ", tm) <= 0)
370 snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) getpid());
371 char_array_0(header_pid);
374 IOVEC_SET_STRING(iovec[0], header_priority);
375 IOVEC_SET_STRING(iovec[1], header_time);
376 IOVEC_SET_STRING(iovec[2], program_invocation_short_name);
377 IOVEC_SET_STRING(iovec[3], header_pid);
378 IOVEC_SET_STRING(iovec[4], buffer);
380 /* When using syslog via SOCK_STREAM separate the messages by NUL chars */
381 if (syslog_is_stream)
385 msghdr.msg_iov = iovec;
386 msghdr.msg_iovlen = ELEMENTSOF(iovec);
391 n = sendmsg(syslog_fd, &msghdr, MSG_NOSIGNAL);
395 if (!syslog_is_stream ||
396 (size_t) n >= IOVEC_TOTAL_SIZE(iovec, ELEMENTSOF(iovec)))
399 IOVEC_INCREMENT(iovec, ELEMENTSOF(iovec), n);
405 static int write_to_kmsg(
410 const char *buffer) {
412 char header_priority[16], header_pid[16];
413 struct iovec iovec[5];
418 snprintf(header_priority, sizeof(header_priority), "<%i>", level);
419 char_array_0(header_priority);
421 snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) getpid());
422 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 write_to_journal(
442 const char *buffer) {
444 char header[LINE_MAX];
445 struct iovec iovec[3];
451 snprintf(header, sizeof(header),
453 "SYSLOG_FACILITY=%i\n"
457 "SYSLOG_IDENTIFIER=%s\n"
464 program_invocation_short_name);
466 char_array_0(header);
469 IOVEC_SET_STRING(iovec[0], header);
470 IOVEC_SET_STRING(iovec[1], buffer);
471 IOVEC_SET_STRING(iovec[2], "\n");
475 mh.msg_iovlen = ELEMENTSOF(iovec);
477 if (sendmsg(journal_fd, &mh, MSG_NOSIGNAL) < 0)
483 static int log_dispatch(
492 if (log_target == LOG_TARGET_NULL)
495 /* Patch in LOG_DAEMON facility if necessary */
496 if ((level & LOG_FACMASK) == 0)
497 level = log_facility | LOG_PRI(level);
503 buffer += strspn(buffer, NEWLINE);
508 if ((e = strpbrk(buffer, NEWLINE)))
511 if (log_target == LOG_TARGET_AUTO ||
512 log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
513 log_target == LOG_TARGET_JOURNAL) {
515 k = write_to_journal(level, file, line, func, buffer);
524 if (log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
525 log_target == LOG_TARGET_SYSLOG) {
527 k = write_to_syslog(level, file, line, func, buffer);
537 (log_target == LOG_TARGET_AUTO ||
538 log_target == LOG_TARGET_SAFE ||
539 log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
540 log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
541 log_target == LOG_TARGET_KMSG)) {
543 k = write_to_kmsg(level, file, line, func, buffer);
552 k = write_to_console(level, file, line, func, buffer);
563 int log_dump_internal(
572 /* This modifies the buffer... */
574 if (_likely_(LOG_PRI(level) > log_max_level))
578 r = log_dispatch(level, file, line, func, buffer);
592 char buffer[LINE_MAX];
595 if (_likely_(LOG_PRI(level) > log_max_level))
599 vsnprintf(buffer, sizeof(buffer), format, ap);
600 char_array_0(buffer);
602 r = log_dispatch(level, file, line, func, buffer);
613 const char *format, ...) {
618 va_start(ap, format);
619 r = log_metav(level, file, line, func, format, ap);
625 #pragma GCC diagnostic push
626 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
627 _noreturn_ static void log_assert(const char *text, const char *file, int line, const char *func, const char *format) {
628 static char buffer[LINE_MAX];
630 snprintf(buffer, sizeof(buffer), format, text, file, line, func);
632 char_array_0(buffer);
633 log_abort_msg = buffer;
635 log_dispatch(LOG_CRIT, file, line, func, buffer);
638 #pragma GCC diagnostic pop
640 _noreturn_ void log_assert_failed(const char *text, const char *file, int line, const char *func) {
641 log_assert(text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Aborting.");
644 _noreturn_ void log_assert_failed_unreachable(const char *text, const char *file, int line, const char *func) {
645 log_assert(text, file, line, func, "Code should not be reached '%s' at %s:%u, function %s(). Aborting.");
648 int log_oom_internal(const char *file, int line, const char *func) {
649 log_meta(LOG_ERR, file, line, func, "Out of memory.");
653 int log_struct_internal(
658 const char *format, ...) {
664 if (_likely_(LOG_PRI(level) > log_max_level))
667 if (log_target == LOG_TARGET_NULL)
670 if ((level & LOG_FACMASK) == 0)
671 level = log_facility | LOG_PRI(level);
675 if ((log_target == LOG_TARGET_AUTO ||
676 log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
677 log_target == LOG_TARGET_JOURNAL) &&
680 char header[LINE_MAX];
681 struct iovec iovec[17];
684 const char nl = '\n';
686 /* If the journal is available do structured logging */
688 snprintf(header, sizeof(header),
690 "SYSLOG_FACILITY=%i\n"
694 "SYSLOG_IDENTIFIER=%s\n",
700 program_invocation_short_name);
701 char_array_0(header);
704 IOVEC_SET_STRING(iovec[n++], header);
706 va_start(ap, format);
707 while (format && n + 1 < ELEMENTSOF(iovec)) {
711 /* We need to copy the va_list structure,
712 * since vasprintf() leaves it afterwards at
713 * an undefined location */
716 if (vasprintf(&buf, format, aq) < 0) {
723 /* Now, jump enough ahead, so that we point to
724 * the next format string */
725 VA_FORMAT_ADVANCE(format, ap);
727 IOVEC_SET_STRING(iovec[n++], buf);
729 iovec[n].iov_base = (char*) &nl;
730 iovec[n].iov_len = 1;
733 format = va_arg(ap, char *);
740 if (sendmsg(journal_fd, &mh, MSG_NOSIGNAL) < 0)
747 for (i = 1; i < n; i += 2)
748 free(iovec[i].iov_base);
754 /* Fallback if journal logging is not available */
756 va_start(ap, format);
761 vsnprintf(buf, sizeof(buf), format, aq);
765 if (startswith(buf, "MESSAGE=")) {
770 VA_FORMAT_ADVANCE(format, ap);
772 format = va_arg(ap, char *);
777 r = log_dispatch(level, file, line, func, buf + 8);
786 int log_set_target_from_string(const char *e) {
789 t = log_target_from_string(e);
797 int log_set_max_level_from_string(const char *e) {
800 t = log_level_from_string(e);
804 log_set_max_level(t);
808 void log_parse_environment(void) {
811 e = secure_getenv("SYSTEMD_LOG_TARGET");
812 if (e && log_set_target_from_string(e) < 0)
813 log_warning("Failed to parse log target %s. Ignoring.", e);
815 e = secure_getenv("SYSTEMD_LOG_LEVEL");
816 if (e && log_set_max_level_from_string(e) < 0)
817 log_warning("Failed to parse log level %s. Ignoring.", e);
819 e = secure_getenv("SYSTEMD_LOG_COLOR");
820 if (e && log_show_color_from_string(e) < 0)
821 log_warning("Failed to parse bool %s. Ignoring.", e);
823 e = secure_getenv("SYSTEMD_LOG_LOCATION");
824 if (e && log_show_location_from_string(e) < 0)
825 log_warning("Failed to parse bool %s. Ignoring.", e);
828 LogTarget log_get_target(void) {
832 int log_get_max_level(void) {
833 return log_max_level;
836 void log_show_color(bool b) {
840 void log_show_location(bool b) {
844 int log_show_color_from_string(const char *e) {
847 t = parse_boolean(e);
855 int log_show_location_from_string(const char *e) {
858 t = parse_boolean(e);
862 log_show_location(t);
866 bool log_on_console(void) {
867 if (log_target == LOG_TARGET_CONSOLE)
870 return syslog_fd < 0 && kmsg_fd < 0 && journal_fd < 0;
873 static const char *const log_target_table[] = {
874 [LOG_TARGET_CONSOLE] = "console",
875 [LOG_TARGET_KMSG] = "kmsg",
876 [LOG_TARGET_JOURNAL] = "journal",
877 [LOG_TARGET_JOURNAL_OR_KMSG] = "journal-or-kmsg",
878 [LOG_TARGET_SYSLOG] = "syslog",
879 [LOG_TARGET_SYSLOG_OR_KMSG] = "syslog-or-kmsg",
880 [LOG_TARGET_AUTO] = "auto",
881 [LOG_TARGET_SAFE] = "safe",
882 [LOG_TARGET_NULL] = "null"
885 DEFINE_STRING_TABLE_LOOKUP(log_target, LogTarget);