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 *object_name
,
313 const char *buffer
) {
316 struct iovec iovec
[5];
323 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)
346 static int write_to_syslog(
351 const char *object_name
,
353 const char *buffer
) {
355 char header_priority
[16], header_time
[64], header_pid
[16];
356 struct iovec iovec
[5];
357 struct msghdr msghdr
;
364 snprintf(header_priority
, sizeof(header_priority
), "<%i>", level
);
365 char_array_0(header_priority
);
367 t
= (time_t) (now(CLOCK_REALTIME
) / USEC_PER_SEC
);
372 if (strftime(header_time
, sizeof(header_time
), "%h %e %T ", tm
) <= 0)
375 snprintf(header_pid
, sizeof(header_pid
), "[%lu]: ", (unsigned long) getpid());
376 char_array_0(header_pid
);
379 IOVEC_SET_STRING(iovec
[0], header_priority
);
380 IOVEC_SET_STRING(iovec
[1], header_time
);
381 IOVEC_SET_STRING(iovec
[2], program_invocation_short_name
);
382 IOVEC_SET_STRING(iovec
[3], header_pid
);
383 IOVEC_SET_STRING(iovec
[4], buffer
);
385 /* When using syslog via SOCK_STREAM separate the messages by NUL chars */
386 if (syslog_is_stream
)
390 msghdr
.msg_iov
= iovec
;
391 msghdr
.msg_iovlen
= ELEMENTSOF(iovec
);
396 n
= sendmsg(syslog_fd
, &msghdr
, MSG_NOSIGNAL
);
400 if (!syslog_is_stream
||
401 (size_t) n
>= IOVEC_TOTAL_SIZE(iovec
, ELEMENTSOF(iovec
)))
404 IOVEC_INCREMENT(iovec
, ELEMENTSOF(iovec
), n
);
410 static int write_to_kmsg(
415 const char *object_name
,
417 const char *buffer
) {
419 char header_priority
[16], header_pid
[16];
420 struct iovec iovec
[5];
425 snprintf(header_priority
, sizeof(header_priority
), "<%i>", level
);
426 char_array_0(header_priority
);
428 snprintf(header_pid
, sizeof(header_pid
), "[%lu]: ", (unsigned long) getpid());
429 char_array_0(header_pid
);
432 IOVEC_SET_STRING(iovec
[0], header_priority
);
433 IOVEC_SET_STRING(iovec
[1], program_invocation_short_name
);
434 IOVEC_SET_STRING(iovec
[2], header_pid
);
435 IOVEC_SET_STRING(iovec
[3], buffer
);
436 IOVEC_SET_STRING(iovec
[4], "\n");
438 if (writev(kmsg_fd
, iovec
, ELEMENTSOF(iovec
)) < 0)
444 static int log_do_header(char *header
, size_t size
,
446 const char *file
, int line
, const char *func
,
447 const char *object_name
, const char *object
) {
448 snprintf(header
, size
,
450 "SYSLOG_FACILITY=%i\n"
455 "SYSLOG_IDENTIFIER=%s\n",
458 file
? "CODE_FILE=" : "",
459 file
? LINE_MAX
: 0, file
, /* %.0s means no output */
461 line
? "CODE_LINE=" : "",
462 line
? 1 : 0, line
, /* %.0d means no output too, special case for 0 */
464 func
? "CODE_FUNCTION=" : "",
465 func
? LINE_MAX
: 0, func
,
467 object
? object_name
: "",
468 object
? LINE_MAX
: 0, object
, /* %.0s means no output */
470 program_invocation_short_name
);
471 header
[size
- 1] = '\0';
475 static int write_to_journal(
480 const char *object_name
,
482 const char *buffer
) {
484 char header
[LINE_MAX
];
485 struct iovec iovec
[4] = {{0}};
486 struct msghdr mh
= {0};
491 log_do_header(header
, sizeof(header
), level
,
492 file
, line
, func
, object_name
, object
);
494 IOVEC_SET_STRING(iovec
[0], header
);
495 IOVEC_SET_STRING(iovec
[1], "MESSAGE=");
496 IOVEC_SET_STRING(iovec
[2], buffer
);
497 IOVEC_SET_STRING(iovec
[3], "\n");
500 mh
.msg_iovlen
= ELEMENTSOF(iovec
);
502 if (sendmsg(journal_fd
, &mh
, MSG_NOSIGNAL
) < 0)
508 static int log_dispatch(
513 const char *object_name
,
519 if (log_target
== LOG_TARGET_NULL
)
522 /* Patch in LOG_DAEMON facility if necessary */
523 if ((level
& LOG_FACMASK
) == 0)
524 level
= log_facility
| LOG_PRI(level
);
530 buffer
+= strspn(buffer
, NEWLINE
);
535 if ((e
= strpbrk(buffer
, NEWLINE
)))
538 if (log_target
== LOG_TARGET_AUTO
||
539 log_target
== LOG_TARGET_JOURNAL_OR_KMSG
||
540 log_target
== LOG_TARGET_JOURNAL
) {
542 k
= write_to_journal(level
, file
, line
, func
,
543 object_name
, object
, buffer
);
545 if (k
< 0 && k
!= -EAGAIN
)
552 if (log_target
== LOG_TARGET_SYSLOG_OR_KMSG
||
553 log_target
== LOG_TARGET_SYSLOG
) {
555 k
= write_to_syslog(level
, file
, line
, func
,
556 object_name
, object
, buffer
);
558 if (k
< 0 && k
!= -EAGAIN
)
566 (log_target
== LOG_TARGET_AUTO
||
567 log_target
== LOG_TARGET_SAFE
||
568 log_target
== LOG_TARGET_SYSLOG_OR_KMSG
||
569 log_target
== LOG_TARGET_JOURNAL_OR_KMSG
||
570 log_target
== LOG_TARGET_KMSG
)) {
572 k
= write_to_kmsg(level
, file
, line
, func
,
573 object_name
, object
, buffer
);
575 if (k
< 0 && k
!= -EAGAIN
)
583 k
= write_to_console(level
, file
, line
, func
,
584 object_name
, object
, buffer
);
595 int log_dump_internal(
604 /* This modifies the buffer... */
606 if (_likely_(LOG_PRI(level
) > log_max_level
))
610 r
= log_dispatch(level
, file
, line
, func
, NULL
, NULL
, buffer
);
624 char buffer
[LINE_MAX
];
627 if (_likely_(LOG_PRI(level
) > log_max_level
))
631 vsnprintf(buffer
, sizeof(buffer
), format
, ap
);
632 char_array_0(buffer
);
634 r
= log_dispatch(level
, file
, line
, func
, NULL
, NULL
, buffer
);
645 const char *format
, ...) {
650 va_start(ap
, format
);
651 r
= log_metav(level
, file
, line
, func
, format
, ap
);
657 int log_metav_object(
662 const char *object_name
,
667 char buffer
[LINE_MAX
];
670 if (_likely_(LOG_PRI(level
) > log_max_level
))
674 vsnprintf(buffer
, sizeof(buffer
), format
, ap
);
675 char_array_0(buffer
);
677 r
= log_dispatch(level
, file
, line
, func
,
678 object_name
, object
, buffer
);
689 const char *object_name
,
691 const char *format
, ...) {
696 va_start(ap
, format
);
697 r
= log_metav_object(level
, file
, line
, func
,
698 object_name
, object
, format
, ap
);
704 #pragma GCC diagnostic push
705 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
706 _noreturn_
static void log_assert(const char *text
, const char *file
, int line
, const char *func
, const char *format
) {
707 static char buffer
[LINE_MAX
];
709 snprintf(buffer
, sizeof(buffer
), format
, text
, file
, line
, func
);
711 char_array_0(buffer
);
712 log_abort_msg
= buffer
;
714 log_dispatch(LOG_CRIT
, file
, line
, func
, NULL
, NULL
, buffer
);
717 #pragma GCC diagnostic pop
719 _noreturn_
void log_assert_failed(const char *text
, const char *file
, int line
, const char *func
) {
720 log_assert(text
, file
, line
, func
, "Assertion '%s' failed at %s:%u, function %s(). Aborting.");
723 _noreturn_
void log_assert_failed_unreachable(const char *text
, const char *file
, int line
, const char *func
) {
724 log_assert(text
, file
, line
, func
, "Code should not be reached '%s' at %s:%u, function %s(). Aborting.");
727 int log_oom_internal(const char *file
, int line
, const char *func
) {
728 log_meta(LOG_ERR
, file
, line
, func
, "Out of memory.");
732 int log_struct_internal(
737 const char *format
, ...) {
743 if (_likely_(LOG_PRI(level
) > log_max_level
))
746 if (log_target
== LOG_TARGET_NULL
)
749 if ((level
& LOG_FACMASK
) == 0)
750 level
= log_facility
| LOG_PRI(level
);
754 if ((log_target
== LOG_TARGET_AUTO
||
755 log_target
== LOG_TARGET_JOURNAL_OR_KMSG
||
756 log_target
== LOG_TARGET_JOURNAL
) &&
759 char header
[LINE_MAX
];
760 struct iovec iovec
[17] = {{0}};
763 static const char nl
= '\n';
765 /* If the journal is available do structured logging */
766 log_do_header(header
, sizeof(header
), level
,
767 file
, line
, func
, NULL
, NULL
);
768 IOVEC_SET_STRING(iovec
[n
++], header
);
770 va_start(ap
, format
);
771 while (format
&& n
+ 1 < ELEMENTSOF(iovec
)) {
775 /* We need to copy the va_list structure,
776 * since vasprintf() leaves it afterwards at
777 * an undefined location */
780 if (vasprintf(&buf
, format
, aq
) < 0) {
787 /* Now, jump enough ahead, so that we point to
788 * the next format string */
789 VA_FORMAT_ADVANCE(format
, ap
);
791 IOVEC_SET_STRING(iovec
[n
++], buf
);
793 iovec
[n
].iov_base
= (char*) &nl
;
794 iovec
[n
].iov_len
= 1;
797 format
= va_arg(ap
, char *);
804 if (sendmsg(journal_fd
, &mh
, MSG_NOSIGNAL
) < 0)
811 for (i
= 1; i
< n
; i
+= 2)
812 free(iovec
[i
].iov_base
);
818 /* Fallback if journal logging is not available */
820 va_start(ap
, format
);
825 vsnprintf(buf
, sizeof(buf
), format
, aq
);
829 if (startswith(buf
, "MESSAGE=")) {
834 VA_FORMAT_ADVANCE(format
, ap
);
836 format
= va_arg(ap
, char *);
841 r
= log_dispatch(level
, file
, line
, func
,
842 NULL
, NULL
, buf
+ 8);
851 int log_set_target_from_string(const char *e
) {
854 t
= log_target_from_string(e
);
862 int log_set_max_level_from_string(const char *e
) {
865 t
= log_level_from_string(e
);
869 log_set_max_level(t
);
873 void log_parse_environment(void) {
876 e
= secure_getenv("SYSTEMD_LOG_TARGET");
877 if (e
&& log_set_target_from_string(e
) < 0)
878 log_warning("Failed to parse log target %s. Ignoring.", e
);
880 e
= secure_getenv("SYSTEMD_LOG_LEVEL");
881 if (e
&& log_set_max_level_from_string(e
) < 0)
882 log_warning("Failed to parse log level %s. Ignoring.", e
);
884 e
= secure_getenv("SYSTEMD_LOG_COLOR");
885 if (e
&& log_show_color_from_string(e
) < 0)
886 log_warning("Failed to parse bool %s. Ignoring.", e
);
888 e
= secure_getenv("SYSTEMD_LOG_LOCATION");
889 if (e
&& log_show_location_from_string(e
) < 0)
890 log_warning("Failed to parse bool %s. Ignoring.", e
);
893 LogTarget
log_get_target(void) {
897 int log_get_max_level(void) {
898 return log_max_level
;
901 void log_show_color(bool b
) {
905 void log_show_location(bool b
) {
909 int log_show_color_from_string(const char *e
) {
912 t
= parse_boolean(e
);
920 int log_show_location_from_string(const char *e
) {
923 t
= parse_boolean(e
);
927 log_show_location(t
);
931 bool log_on_console(void) {
932 if (log_target
== LOG_TARGET_CONSOLE
)
935 return syslog_fd
< 0 && kmsg_fd
< 0 && journal_fd
< 0;
938 static const char *const log_target_table
[] = {
939 [LOG_TARGET_CONSOLE
] = "console",
940 [LOG_TARGET_KMSG
] = "kmsg",
941 [LOG_TARGET_JOURNAL
] = "journal",
942 [LOG_TARGET_JOURNAL_OR_KMSG
] = "journal-or-kmsg",
943 [LOG_TARGET_SYSLOG
] = "syslog",
944 [LOG_TARGET_SYSLOG_OR_KMSG
] = "syslog-or-kmsg",
945 [LOG_TARGET_AUTO
] = "auto",
946 [LOG_TARGET_SAFE
] = "safe",
947 [LOG_TARGET_NULL
] = "null"
950 DEFINE_STRING_TABLE_LOOKUP(log_target
, LogTarget
);