1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
9 #include <sys/signalfd.h>
16 #include "sd-messages.h"
18 #include "alloc-util.h"
19 #include "argv-util.h"
21 #include "errno-util.h"
23 #include "format-util.h"
27 #include "missing_syscall.h"
28 #include "missing_threads.h"
29 #include "parse-util.h"
30 #include "proc-cmdline.h"
31 #include "process-util.h"
32 #include "ratelimit.h"
33 #include "signal-util.h"
34 #include "socket-util.h"
35 #include "stdio-util.h"
36 #include "string-table.h"
37 #include "string-util.h"
39 #include "syslog-util.h"
40 #include "terminal-util.h"
41 #include "time-util.h"
44 #define SNDBUF_SIZE (8*1024*1024)
45 #define IOVEC_MAX 128U
47 static log_syntax_callback_t log_syntax_callback
= NULL
;
48 static void *log_syntax_callback_userdata
= NULL
;
50 static LogTarget log_target
= LOG_TARGET_CONSOLE
;
51 static int log_max_level
= LOG_INFO
;
52 static int log_facility
= LOG_DAEMON
;
54 static int console_fd
= STDERR_FILENO
;
55 static int syslog_fd
= -EBADF
;
56 static int kmsg_fd
= -EBADF
;
57 static int journal_fd
= -EBADF
;
59 static bool syslog_is_stream
= false;
61 static int show_color
= -1; /* tristate */
62 static bool show_location
= false;
63 static bool show_time
= false;
64 static bool show_tid
= false;
66 static bool upgrade_syslog_to_journal
= false;
67 static bool always_reopen_console
= false;
68 static bool open_when_needed
= false;
69 static bool prohibit_ipc
= false;
71 /* Akin to glibc's __abort_msg; which is private and we hence cannot
73 static char *log_abort_msg
= NULL
;
75 typedef struct LogContext
{
77 /* Depending on which destructor is used (log_context_free() or log_context_detach()) the memory
78 * referenced by this is freed or not */
80 struct iovec
*input_iovec
;
83 LIST_FIELDS(struct LogContext
, ll
);
86 static thread_local
LIST_HEAD(LogContext
, _log_context
) = NULL
;
87 static thread_local
size_t _log_context_num_fields
= 0;
89 #if LOG_MESSAGE_VERIFICATION || defined(__COVERITY__)
90 bool _log_message_dummy
= false; /* Always false */
93 /* An assert to use in logging functions that does not call recursively
94 * into our logging functions (since that might lead to a loop). */
95 #define assert_raw(expr) \
97 if (_unlikely_(!(expr))) { \
98 fputs(#expr "\n", stderr); \
103 static void log_close_console(void) {
104 console_fd
= safe_close_above_stdio(console_fd
);
107 static int log_open_console(void) {
109 if (!always_reopen_console
) {
110 console_fd
= STDERR_FILENO
;
114 if (console_fd
< 3) {
117 fd
= open_terminal("/dev/console", O_WRONLY
|O_NOCTTY
|O_CLOEXEC
);
121 console_fd
= fd_move_above_stdio(fd
);
127 static void log_close_kmsg(void) {
128 kmsg_fd
= safe_close(kmsg_fd
);
131 static int log_open_kmsg(void) {
136 kmsg_fd
= open("/dev/kmsg", O_WRONLY
|O_NOCTTY
|O_CLOEXEC
);
140 kmsg_fd
= fd_move_above_stdio(kmsg_fd
);
144 static void log_close_syslog(void) {
145 syslog_fd
= safe_close(syslog_fd
);
148 static int create_log_socket(int type
) {
152 fd
= socket(AF_UNIX
, type
|SOCK_CLOEXEC
, 0);
156 fd
= fd_move_above_stdio(fd
);
157 (void) fd_inc_sndbuf(fd
, SNDBUF_SIZE
);
159 /* We need a blocking fd here since we'd otherwise lose messages way too early. However, let's not hang forever
160 * in the unlikely case of a deadlock. */
161 if (getpid_cached() == 1)
162 timeval_store(&tv
, 10 * USEC_PER_MSEC
);
164 timeval_store(&tv
, 10 * USEC_PER_SEC
);
165 (void) setsockopt(fd
, SOL_SOCKET
, SO_SNDTIMEO
, &tv
, sizeof(tv
));
170 static int log_open_syslog(void) {
176 syslog_fd
= create_log_socket(SOCK_DGRAM
);
182 r
= connect_unix_path(syslog_fd
, AT_FDCWD
, "/dev/log");
184 safe_close(syslog_fd
);
186 /* Some legacy syslog systems still use stream sockets. They really shouldn't. But what can
188 syslog_fd
= create_log_socket(SOCK_STREAM
);
194 r
= connect_unix_path(syslog_fd
, AT_FDCWD
, "/dev/log");
198 syslog_is_stream
= true;
200 syslog_is_stream
= false;
209 static void log_close_journal(void) {
210 journal_fd
= safe_close(journal_fd
);
213 static int log_open_journal(void) {
219 journal_fd
= create_log_socket(SOCK_DGRAM
);
220 if (journal_fd
< 0) {
225 r
= connect_unix_path(journal_fd
, AT_FDCWD
, "/run/systemd/journal/socket");
236 static bool stderr_is_journal(void) {
237 _cleanup_free_
char *w
= NULL
;
242 e
= getenv("JOURNAL_STREAM");
246 if (extract_first_word(&e
, &w
, ":", EXTRACT_DONT_COALESCE_SEPARATORS
) <= 0)
251 if (safe_atou64(w
, &dev
) < 0)
253 if (safe_atou64(e
, &ino
) < 0)
256 if (fstat(STDERR_FILENO
, &st
) < 0)
259 return st
.st_dev
== dev
&& st
.st_ino
== ino
;
265 /* Do not call from library code. */
267 /* This function is often called in preparation for logging. Let's make sure we don't clobber errno,
268 * so that a call to a logging function immediately following a log_open() call can still easily
269 * reference an error that happened immediately before the log_open() call. */
272 /* If we don't use the console, we close it here to not get killed by SAK. If we don't use syslog, we
273 * close it here too, so that we are not confused by somebody deleting the socket in the fs, and to
274 * make sure we don't use it if prohibit_ipc is set. If we don't use /dev/kmsg we still keep it open,
275 * because there is no reason to close it. */
277 if (log_target
== LOG_TARGET_NULL
) {
284 if (getpid_cached() == 1 ||
285 stderr_is_journal() ||
289 LOG_TARGET_JOURNAL_OR_KMSG
,
291 LOG_TARGET_SYSLOG_OR_KMSG
)) {
294 if (IN_SET(log_target
,
296 LOG_TARGET_JOURNAL_OR_KMSG
,
297 LOG_TARGET_JOURNAL
)) {
299 r
= log_open_journal();
307 if (IN_SET(log_target
,
308 LOG_TARGET_SYSLOG_OR_KMSG
,
309 LOG_TARGET_SYSLOG
)) {
311 r
= log_open_syslog();
320 if (IN_SET(log_target
, LOG_TARGET_AUTO
,
321 LOG_TARGET_JOURNAL_OR_KMSG
,
322 LOG_TARGET_SYSLOG_OR_KMSG
,
337 return log_open_console();
340 void log_set_target(LogTarget target
) {
342 assert(target
< _LOG_TARGET_MAX
);
344 if (upgrade_syslog_to_journal
) {
345 if (target
== LOG_TARGET_SYSLOG
)
346 target
= LOG_TARGET_JOURNAL
;
347 else if (target
== LOG_TARGET_SYSLOG_OR_KMSG
)
348 target
= LOG_TARGET_JOURNAL_OR_KMSG
;
354 void log_set_target_and_open(LogTarget target
) {
355 log_set_target(target
);
359 void log_close(void) {
360 /* Do not call from library code. */
368 void log_forget_fds(void) {
369 /* Do not call from library code. */
371 console_fd
= kmsg_fd
= syslog_fd
= journal_fd
= -EBADF
;
374 void log_set_max_level(int level
) {
375 assert(level
== LOG_NULL
|| (level
& LOG_PRIMASK
) == level
);
377 log_max_level
= level
;
380 void log_set_facility(int facility
) {
381 log_facility
= facility
;
384 static int write_to_console(
390 const char *buffer
) {
393 header_time
[FORMAT_TIMESTAMP_MAX
],
394 prefix
[1 + DECIMAL_STR_MAX(int) + 2],
395 tid_string
[3 + DECIMAL_STR_MAX(pid_t
) + 1];
396 struct iovec iovec
[9];
397 const char *on
= NULL
, *off
= NULL
;
403 if (log_target
== LOG_TARGET_CONSOLE_PREFIXED
) {
404 xsprintf(prefix
, "<%i>", level
);
405 iovec
[n
++] = IOVEC_MAKE_STRING(prefix
);
409 format_timestamp(header_time
, sizeof(header_time
), now(CLOCK_REALTIME
))) {
410 iovec
[n
++] = IOVEC_MAKE_STRING(header_time
);
411 iovec
[n
++] = IOVEC_MAKE_STRING(" ");
415 xsprintf(tid_string
, "(" PID_FMT
") ", gettid());
416 iovec
[n
++] = IOVEC_MAKE_STRING(tid_string
);
419 if (log_get_show_color())
420 get_log_colors(LOG_PRI(level
), &on
, &off
, NULL
);
423 const char *lon
= "", *loff
= "";
424 if (log_get_show_color()) {
425 lon
= ansi_highlight_yellow4();
426 loff
= ansi_normal();
429 (void) snprintf(location
, sizeof location
, "%s%s:%i%s: ", lon
, file
, line
, loff
);
430 iovec
[n
++] = IOVEC_MAKE_STRING(location
);
434 iovec
[n
++] = IOVEC_MAKE_STRING(on
);
435 iovec
[n
++] = IOVEC_MAKE_STRING(buffer
);
437 iovec
[n
++] = IOVEC_MAKE_STRING(off
);
438 iovec
[n
++] = IOVEC_MAKE_STRING("\n");
440 if (writev(console_fd
, iovec
, n
) < 0) {
442 if (errno
== EIO
&& getpid_cached() == 1) {
444 /* If somebody tried to kick us from our console tty (via vhangup() or suchlike), try
448 (void) log_open_console();
452 if (writev(console_fd
, iovec
, n
) < 0)
461 static int write_to_syslog(
467 const char *buffer
) {
469 char header_priority
[2 + DECIMAL_STR_MAX(int) + 1],
471 header_pid
[4 + DECIMAL_STR_MAX(pid_t
) + 1];
478 xsprintf(header_priority
, "<%i>", level
);
480 t
= (time_t) (now(CLOCK_REALTIME
) / USEC_PER_SEC
);
481 if (!localtime_r(&t
, &tm
))
484 if (strftime(header_time
, sizeof(header_time
), "%h %e %T ", &tm
) <= 0)
487 xsprintf(header_pid
, "["PID_FMT
"]: ", getpid_cached());
489 struct iovec iovec
[] = {
490 IOVEC_MAKE_STRING(header_priority
),
491 IOVEC_MAKE_STRING(header_time
),
492 IOVEC_MAKE_STRING(program_invocation_short_name
),
493 IOVEC_MAKE_STRING(header_pid
),
494 IOVEC_MAKE_STRING(buffer
),
496 const struct msghdr msghdr
= {
498 .msg_iovlen
= ELEMENTSOF(iovec
),
501 /* When using syslog via SOCK_STREAM separate the messages by NUL chars */
502 if (syslog_is_stream
)
503 iovec
[ELEMENTSOF(iovec
) - 1].iov_len
++;
508 n
= sendmsg(syslog_fd
, &msghdr
, MSG_NOSIGNAL
);
512 if (!syslog_is_stream
)
515 if (IOVEC_INCREMENT(iovec
, ELEMENTSOF(iovec
), n
))
522 static int write_to_kmsg(
528 const char *buffer
) {
530 /* Set a ratelimit on the amount of messages logged to /dev/kmsg. This is mostly supposed to be a
531 * safety catch for the case where start indiscriminately logging in a loop. It will not catch cases
532 * where we log excessively, but not in a tight loop.
534 * Note that this ratelimit is per-emitter, so we might still overwhelm /dev/kmsg with multiple
537 static thread_local RateLimit ratelimit
= { 5 * USEC_PER_SEC
, 200 };
539 char header_priority
[2 + DECIMAL_STR_MAX(int) + 1],
540 header_pid
[4 + DECIMAL_STR_MAX(pid_t
) + 1];
545 if (!ratelimit_below(&ratelimit
))
548 xsprintf(header_priority
, "<%i>", level
);
549 xsprintf(header_pid
, "["PID_FMT
"]: ", getpid_cached());
551 const struct iovec iovec
[] = {
552 IOVEC_MAKE_STRING(header_priority
),
553 IOVEC_MAKE_STRING(program_invocation_short_name
),
554 IOVEC_MAKE_STRING(header_pid
),
555 IOVEC_MAKE_STRING(buffer
),
556 IOVEC_MAKE_STRING("\n"),
559 if (writev(kmsg_fd
, iovec
, ELEMENTSOF(iovec
)) < 0)
565 static int log_do_header(
570 const char *file
, int line
, const char *func
,
571 const char *object_field
, const char *object
,
572 const char *extra_field
, const char *extra
) {
575 error
= IS_SYNTHETIC_ERRNO(error
) ? 0 : ERRNO_VALUE(error
);
577 r
= snprintf(header
, size
,
579 "SYSLOG_FACILITY=%i\n"
581 "%s%.256s%s" /* CODE_FILE */
582 "%s%.*i%s" /* CODE_LINE */
583 "%s%.256s%s" /* CODE_FUNC */
584 "%s%.*i%s" /* ERRNO */
585 "%s%.256s%s" /* object */
586 "%s%.256s%s" /* extra */
587 "SYSLOG_IDENTIFIER=%.256s\n",
591 isempty(file
) ? "" : "CODE_FILE=",
592 isempty(file
) ? "" : file
,
593 isempty(file
) ? "" : "\n",
594 line
? "CODE_LINE=" : "",
595 line
? 1 : 0, line
, /* %.0d means no output too, special case for 0 */
597 isempty(func
) ? "" : "CODE_FUNC=",
598 isempty(func
) ? "" : func
,
599 isempty(func
) ? "" : "\n",
600 error
? "ERRNO=" : "",
601 error
? 1 : 0, error
,
603 isempty(object
) ? "" : object_field
,
604 isempty(object
) ? "" : object
,
605 isempty(object
) ? "" : "\n",
606 isempty(extra
) ? "" : extra_field
,
607 isempty(extra
) ? "" : extra
,
608 isempty(extra
) ? "" : "\n",
609 program_invocation_short_name
);
610 assert_raw((size_t) r
< size
);
615 static void log_do_context(struct iovec
*iovec
, size_t iovec_len
, size_t *n
) {
619 LIST_FOREACH(ll
, c
, _log_context
) {
620 STRV_FOREACH(s
, c
->fields
) {
621 if (*n
+ 2 >= iovec_len
)
624 iovec
[(*n
)++] = IOVEC_MAKE_STRING(*s
);
625 iovec
[(*n
)++] = IOVEC_MAKE_STRING("\n");
628 for (size_t i
= 0; i
< c
->n_input_iovec
; i
++) {
629 if (*n
+ 2 >= iovec_len
)
632 iovec
[(*n
)++] = c
->input_iovec
[i
];
633 iovec
[(*n
)++] = IOVEC_MAKE_STRING("\n");
638 static int write_to_journal(
644 const char *object_field
,
646 const char *extra_field
,
648 const char *buffer
) {
650 char header
[LINE_MAX
];
651 size_t n
= 0, iovec_len
;
657 iovec_len
= MIN(4 + _log_context_num_fields
* 2, IOVEC_MAX
);
658 iovec
= newa(struct iovec
, iovec_len
);
660 log_do_header(header
, sizeof(header
), level
, error
, file
, line
, func
, object_field
, object
, extra_field
, extra
);
662 iovec
[n
++] = IOVEC_MAKE_STRING(header
);
663 iovec
[n
++] = IOVEC_MAKE_STRING("MESSAGE=");
664 iovec
[n
++] = IOVEC_MAKE_STRING(buffer
);
665 iovec
[n
++] = IOVEC_MAKE_STRING("\n");
667 log_do_context(iovec
, iovec_len
, &n
);
669 const struct msghdr msghdr
= {
674 if (sendmsg(journal_fd
, &msghdr
, MSG_NOSIGNAL
) < 0)
680 int log_dispatch_internal(
686 const char *object_field
,
688 const char *extra_field
,
694 if (log_target
== LOG_TARGET_NULL
)
695 return -ERRNO_VALUE(error
);
697 /* Patch in LOG_DAEMON facility if necessary */
698 if ((level
& LOG_FACMASK
) == 0)
699 level
|= log_facility
;
701 if (open_when_needed
)
708 buffer
+= strspn(buffer
, NEWLINE
);
713 if ((e
= strpbrk(buffer
, NEWLINE
)))
716 if (IN_SET(log_target
, LOG_TARGET_AUTO
,
717 LOG_TARGET_JOURNAL_OR_KMSG
,
718 LOG_TARGET_JOURNAL
)) {
720 k
= write_to_journal(level
, error
, file
, line
, func
, object_field
, object
, extra_field
, extra
, buffer
);
721 if (k
< 0 && k
!= -EAGAIN
)
725 if (IN_SET(log_target
, LOG_TARGET_SYSLOG_OR_KMSG
,
726 LOG_TARGET_SYSLOG
)) {
728 k
= write_to_syslog(level
, error
, file
, line
, func
, buffer
);
729 if (k
< 0 && k
!= -EAGAIN
)
734 IN_SET(log_target
, LOG_TARGET_AUTO
,
735 LOG_TARGET_SYSLOG_OR_KMSG
,
736 LOG_TARGET_JOURNAL_OR_KMSG
,
742 k
= write_to_kmsg(level
, error
, file
, line
, func
, buffer
);
745 (void) log_open_console();
750 (void) write_to_console(level
, error
, file
, line
, func
, buffer
);
755 if (open_when_needed
)
758 return -ERRNO_VALUE(error
);
761 int log_dump_internal(
771 /* This modifies the buffer... */
773 if (_likely_(LOG_PRI(level
) > log_max_level
))
774 return -ERRNO_VALUE(error
);
776 return log_dispatch_internal(level
, error
, file
, line
, func
, NULL
, NULL
, NULL
, NULL
, buffer
);
788 if (_likely_(LOG_PRI(level
) > log_max_level
))
789 return -ERRNO_VALUE(error
);
791 /* Make sure that %m maps to the specified error (or "Success"). */
792 char buffer
[LINE_MAX
];
793 LOCAL_ERRNO(ERRNO_VALUE(error
));
795 (void) vsnprintf(buffer
, sizeof buffer
, format
, ap
);
797 return log_dispatch_internal(level
, error
, file
, line
, func
, NULL
, NULL
, NULL
, NULL
, buffer
);
806 const char *format
, ...) {
811 va_start(ap
, format
);
812 r
= log_internalv(level
, error
, file
, line
, func
, format
, ap
);
818 int log_object_internalv(
824 const char *object_field
,
826 const char *extra_field
,
833 if (_likely_(LOG_PRI(level
) > log_max_level
))
834 return -ERRNO_VALUE(error
);
836 /* Make sure that %m maps to the specified error (or "Success"). */
837 LOCAL_ERRNO(ERRNO_VALUE(error
));
839 /* Prepend the object name before the message */
844 buffer
= newa(char, n
+ 2 + LINE_MAX
);
845 b
= stpcpy(stpcpy(buffer
, object
), ": ");
847 b
= buffer
= newa(char, LINE_MAX
);
849 (void) vsnprintf(b
, LINE_MAX
, format
, ap
);
851 return log_dispatch_internal(level
, error
, file
, line
, func
,
852 object_field
, object
, extra_field
, extra
, buffer
);
855 int log_object_internal(
861 const char *object_field
,
863 const char *extra_field
,
865 const char *format
, ...) {
870 va_start(ap
, format
);
871 r
= log_object_internalv(level
, error
, file
, line
, func
, object_field
, object
, extra_field
, extra
, format
, ap
);
877 static void log_assert(
883 const char *format
) {
885 static char buffer
[LINE_MAX
];
887 if (_likely_(LOG_PRI(level
) > log_max_level
))
890 DISABLE_WARNING_FORMAT_NONLITERAL
;
891 (void) snprintf(buffer
, sizeof buffer
, format
, text
, file
, line
, func
);
894 log_abort_msg
= buffer
;
896 log_dispatch_internal(level
, 0, file
, line
, func
, NULL
, NULL
, NULL
, NULL
, buffer
);
899 _noreturn_
void log_assert_failed(
904 log_assert(LOG_CRIT
, text
, file
, line
, func
,
905 "Assertion '%s' failed at %s:%u, function %s(). Aborting.");
909 _noreturn_
void log_assert_failed_unreachable(
913 log_assert(LOG_CRIT
, "Code should not be reached", file
, line
, func
,
914 "%s at %s:%u, function %s(). Aborting. 💥");
918 void log_assert_failed_return(
924 log_assert(LOG_DEBUG
, text
, file
, line
, func
,
925 "Assertion '%s' failed at %s:%u, function %s(). Ignoring.");
928 int log_oom_internal(int level
, const char *file
, int line
, const char *func
) {
929 return log_internal(level
, ENOMEM
, file
, line
, func
, "Out of memory.");
932 int log_format_iovec(
936 bool newline_separator
,
941 static const char nl
= '\n';
943 while (format
&& *n
+ 1 < iovec_len
) {
948 /* We need to copy the va_list structure,
949 * since vasprintf() leaves it afterwards at
950 * an undefined location */
952 errno
= ERRNO_VALUE(error
);
955 r
= vasprintf(&m
, format
, aq
);
960 /* Now, jump enough ahead, so that we point to
961 * the next format string */
962 VA_FORMAT_ADVANCE(format
, ap
);
964 iovec
[(*n
)++] = IOVEC_MAKE_STRING(m
);
965 if (newline_separator
)
966 iovec
[(*n
)++] = IOVEC_MAKE((char *)&nl
, 1);
968 format
= va_arg(ap
, char *);
973 int log_struct_internal(
979 const char *format
, ...) {
986 if (_likely_(LOG_PRI(level
) > log_max_level
) ||
987 log_target
== LOG_TARGET_NULL
)
988 return -ERRNO_VALUE(error
);
990 if ((level
& LOG_FACMASK
) == 0)
991 level
|= log_facility
;
993 if (IN_SET(log_target
,
995 LOG_TARGET_JOURNAL_OR_KMSG
,
996 LOG_TARGET_JOURNAL
)) {
998 if (open_when_needed
)
1001 if (journal_fd
>= 0) {
1002 char header
[LINE_MAX
];
1003 struct iovec
*iovec
;
1004 size_t n
= 0, m
, iovec_len
;
1006 bool fallback
= false;
1008 iovec_len
= MIN(17 + _log_context_num_fields
* 2, IOVEC_MAX
);
1009 iovec
= newa(struct iovec
, iovec_len
);
1011 /* If the journal is available do structured logging.
1012 * Do not report the errno if it is synthetic. */
1013 log_do_header(header
, sizeof(header
), level
, error
, file
, line
, func
, NULL
, NULL
, NULL
, NULL
);
1014 iovec
[n
++] = IOVEC_MAKE_STRING(header
);
1016 va_start(ap
, format
);
1017 r
= log_format_iovec(iovec
, iovec_len
, &n
, true, error
, format
, ap
);
1022 log_do_context(iovec
, iovec_len
, &n
);
1024 const struct msghdr msghdr
= {
1029 (void) sendmsg(journal_fd
, &msghdr
, MSG_NOSIGNAL
);
1033 for (size_t i
= 1; i
< m
; i
+= 2)
1034 free(iovec
[i
].iov_base
);
1037 if (open_when_needed
)
1040 return -ERRNO_VALUE(error
);
1045 /* Fallback if journal logging is not available or didn't work. */
1047 va_start(ap
, format
);
1051 errno
= ERRNO_VALUE(error
);
1054 (void) vsnprintf(buf
, sizeof buf
, format
, aq
);
1057 if (startswith(buf
, "MESSAGE=")) {
1062 VA_FORMAT_ADVANCE(format
, ap
);
1064 format
= va_arg(ap
, char *);
1069 if (open_when_needed
)
1072 return -ERRNO_VALUE(error
);
1075 return log_dispatch_internal(level
, error
, file
, line
, func
, NULL
, NULL
, NULL
, NULL
, buf
+ 8);
1078 int log_struct_iovec_internal(
1084 const struct iovec input_iovec
[],
1085 size_t n_input_iovec
) {
1089 if (_likely_(LOG_PRI(level
) > log_max_level
) ||
1090 log_target
== LOG_TARGET_NULL
)
1091 return -ERRNO_VALUE(error
);
1093 if ((level
& LOG_FACMASK
) == 0)
1094 level
|= log_facility
;
1096 if (IN_SET(log_target
, LOG_TARGET_AUTO
,
1097 LOG_TARGET_JOURNAL_OR_KMSG
,
1098 LOG_TARGET_JOURNAL
) &&
1101 char header
[LINE_MAX
];
1102 struct iovec
*iovec
;
1103 size_t n
= 0, iovec_len
;
1105 iovec_len
= MIN(1 + n_input_iovec
* 2 + _log_context_num_fields
* 2, IOVEC_MAX
);
1106 iovec
= newa(struct iovec
, iovec_len
);
1108 log_do_header(header
, sizeof(header
), level
, error
, file
, line
, func
, NULL
, NULL
, NULL
, NULL
);
1110 iovec
[n
++] = IOVEC_MAKE_STRING(header
);
1111 for (size_t i
= 0; i
< n_input_iovec
; i
++) {
1112 iovec
[n
++] = input_iovec
[i
];
1113 iovec
[n
++] = IOVEC_MAKE_STRING("\n");
1116 log_do_context(iovec
, iovec_len
, &n
);
1118 const struct msghdr msghdr
= {
1123 if (sendmsg(journal_fd
, &msghdr
, MSG_NOSIGNAL
) >= 0)
1124 return -ERRNO_VALUE(error
);
1127 for (size_t i
= 0; i
< n_input_iovec
; i
++)
1128 if (memory_startswith(input_iovec
[i
].iov_base
, input_iovec
[i
].iov_len
, "MESSAGE=")) {
1131 m
= strndupa_safe((char*) input_iovec
[i
].iov_base
+ STRLEN("MESSAGE="),
1132 input_iovec
[i
].iov_len
- STRLEN("MESSAGE="));
1134 return log_dispatch_internal(level
, error
, file
, line
, func
, NULL
, NULL
, NULL
, NULL
, m
);
1137 /* Couldn't find MESSAGE=. */
1138 return -ERRNO_VALUE(error
);
1141 int log_set_target_from_string(const char *e
) {
1144 t
= log_target_from_string(e
);
1152 int log_set_max_level_from_string(const char *e
) {
1155 t
= log_level_from_string(e
);
1159 log_set_max_level(t
);
1163 static int parse_proc_cmdline_item(const char *key
, const char *value
, void *data
) {
1166 * The systemd.log_xyz= settings are parsed by all tools, and
1169 * However, "quiet" is only parsed by PID 1, and only turns of
1170 * status output to /dev/console, but does not alter the log
1174 if (streq(key
, "debug") && !value
)
1175 log_set_max_level(LOG_DEBUG
);
1177 else if (proc_cmdline_key_streq(key
, "systemd.log_target")) {
1179 if (proc_cmdline_value_missing(key
, value
))
1182 if (log_set_target_from_string(value
) < 0)
1183 log_warning("Failed to parse log target '%s'. Ignoring.", value
);
1185 } else if (proc_cmdline_key_streq(key
, "systemd.log_level")) {
1187 if (proc_cmdline_value_missing(key
, value
))
1190 if (log_set_max_level_from_string(value
) < 0)
1191 log_warning("Failed to parse log level '%s'. Ignoring.", value
);
1193 } else if (proc_cmdline_key_streq(key
, "systemd.log_color")) {
1195 if (log_show_color_from_string(value
?: "1") < 0)
1196 log_warning("Failed to parse log color setting '%s'. Ignoring.", value
);
1198 } else if (proc_cmdline_key_streq(key
, "systemd.log_location")) {
1200 if (log_show_location_from_string(value
?: "1") < 0)
1201 log_warning("Failed to parse log location setting '%s'. Ignoring.", value
);
1203 } else if (proc_cmdline_key_streq(key
, "systemd.log_tid")) {
1205 if (log_show_tid_from_string(value
?: "1") < 0)
1206 log_warning("Failed to parse log tid setting '%s'. Ignoring.", value
);
1208 } else if (proc_cmdline_key_streq(key
, "systemd.log_time")) {
1210 if (log_show_time_from_string(value
?: "1") < 0)
1211 log_warning("Failed to parse log time setting '%s'. Ignoring.", value
);
1218 static bool should_parse_proc_cmdline(void) {
1219 /* PID1 always reads the kernel command line. */
1220 if (getpid_cached() == 1)
1223 /* Otherwise, parse the commandline if invoked directly by systemd. */
1224 return invoked_by_systemd();
1227 void log_parse_environment_variables(void) {
1230 e
= getenv("SYSTEMD_LOG_TARGET");
1231 if (e
&& log_set_target_from_string(e
) < 0)
1232 log_warning("Failed to parse log target '%s'. Ignoring.", e
);
1234 e
= getenv("SYSTEMD_LOG_LEVEL");
1235 if (e
&& log_set_max_level_from_string(e
) < 0)
1236 log_warning("Failed to parse log level '%s'. Ignoring.", e
);
1238 e
= getenv("SYSTEMD_LOG_COLOR");
1239 if (e
&& log_show_color_from_string(e
) < 0)
1240 log_warning("Failed to parse log color '%s'. Ignoring.", e
);
1242 e
= getenv("SYSTEMD_LOG_LOCATION");
1243 if (e
&& log_show_location_from_string(e
) < 0)
1244 log_warning("Failed to parse log location '%s'. Ignoring.", e
);
1246 e
= getenv("SYSTEMD_LOG_TIME");
1247 if (e
&& log_show_time_from_string(e
) < 0)
1248 log_warning("Failed to parse log time '%s'. Ignoring.", e
);
1250 e
= getenv("SYSTEMD_LOG_TID");
1251 if (e
&& log_show_tid_from_string(e
) < 0)
1252 log_warning("Failed to parse log tid '%s'. Ignoring.", e
);
1255 void log_parse_environment(void) {
1256 /* Do not call from library code. */
1258 if (should_parse_proc_cmdline())
1259 (void) proc_cmdline_parse(parse_proc_cmdline_item
, NULL
, PROC_CMDLINE_STRIP_RD_PREFIX
);
1261 log_parse_environment_variables();
1264 LogTarget
log_get_target(void) {
1268 int log_get_max_level(void) {
1269 return log_max_level
;
1272 void log_show_color(bool b
) {
1276 bool log_get_show_color(void) {
1277 return show_color
> 0; /* Defaults to false. */
1280 void log_show_location(bool b
) {
1284 bool log_get_show_location(void) {
1285 return show_location
;
1288 void log_show_time(bool b
) {
1292 bool log_get_show_time(void) {
1296 void log_show_tid(bool b
) {
1300 bool log_get_show_tid(void) {
1304 int log_show_color_from_string(const char *e
) {
1307 t
= parse_boolean(e
);
1315 int log_show_location_from_string(const char *e
) {
1318 t
= parse_boolean(e
);
1322 log_show_location(t
);
1326 int log_show_time_from_string(const char *e
) {
1329 t
= parse_boolean(e
);
1337 int log_show_tid_from_string(const char *e
) {
1340 t
= parse_boolean(e
);
1348 bool log_on_console(void) {
1349 if (IN_SET(log_target
, LOG_TARGET_CONSOLE
,
1350 LOG_TARGET_CONSOLE_PREFIXED
))
1353 return syslog_fd
< 0 && kmsg_fd
< 0 && journal_fd
< 0;
1356 static const char *const log_target_table
[_LOG_TARGET_MAX
] = {
1357 [LOG_TARGET_CONSOLE
] = "console",
1358 [LOG_TARGET_CONSOLE_PREFIXED
] = "console-prefixed",
1359 [LOG_TARGET_KMSG
] = "kmsg",
1360 [LOG_TARGET_JOURNAL
] = "journal",
1361 [LOG_TARGET_JOURNAL_OR_KMSG
] = "journal-or-kmsg",
1362 [LOG_TARGET_SYSLOG
] = "syslog",
1363 [LOG_TARGET_SYSLOG_OR_KMSG
] = "syslog-or-kmsg",
1364 [LOG_TARGET_AUTO
] = "auto",
1365 [LOG_TARGET_NULL
] = "null",
1368 DEFINE_STRING_TABLE_LOOKUP(log_target
, LogTarget
);
1370 void log_received_signal(int level
, const struct signalfd_siginfo
*si
) {
1373 if (pid_is_valid(si
->ssi_pid
)) {
1374 _cleanup_free_
char *p
= NULL
;
1376 (void) get_process_comm(si
->ssi_pid
, &p
);
1379 "Received SIG%s from PID %"PRIu32
" (%s).",
1380 signal_to_string(si
->ssi_signo
),
1381 si
->ssi_pid
, strna(p
));
1385 signal_to_string(si
->ssi_signo
));
1388 void set_log_syntax_callback(log_syntax_callback_t cb
, void *userdata
) {
1389 assert(!log_syntax_callback
|| !cb
);
1390 assert(!log_syntax_callback_userdata
|| !userdata
);
1392 log_syntax_callback
= cb
;
1393 log_syntax_callback_userdata
= userdata
;
1396 int log_syntax_internal(
1399 const char *config_file
,
1400 unsigned config_line
,
1405 const char *format
, ...) {
1409 if (log_syntax_callback
)
1410 log_syntax_callback(unit
, level
, log_syntax_callback_userdata
);
1412 if (_likely_(LOG_PRI(level
) > log_max_level
) ||
1413 log_target
== LOG_TARGET_NULL
)
1414 return -ERRNO_VALUE(error
);
1416 char buffer
[LINE_MAX
];
1418 const char *unit_fmt
= NULL
;
1420 errno
= ERRNO_VALUE(error
);
1422 va_start(ap
, format
);
1423 (void) vsnprintf(buffer
, sizeof buffer
, format
, ap
);
1427 unit_fmt
= getpid_cached() == 1 ? "UNIT=%s" : "USER_UNIT=%s";
1430 if (config_line
> 0)
1431 return log_struct_internal(
1435 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR
,
1436 "CONFIG_FILE=%s", config_file
,
1437 "CONFIG_LINE=%u", config_line
,
1438 LOG_MESSAGE("%s:%u: %s", config_file
, config_line
, buffer
),
1442 return log_struct_internal(
1446 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR
,
1447 "CONFIG_FILE=%s", config_file
,
1448 LOG_MESSAGE("%s: %s", config_file
, buffer
),
1452 return log_struct_internal(
1456 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR
,
1457 LOG_MESSAGE("%s: %s", unit
, buffer
),
1461 return log_struct_internal(
1465 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR
,
1466 LOG_MESSAGE("%s", buffer
),
1470 int log_syntax_invalid_utf8_internal(
1473 const char *config_file
,
1474 unsigned config_line
,
1478 const char *rvalue
) {
1480 _cleanup_free_
char *p
= NULL
;
1483 p
= utf8_escape_invalid(rvalue
);
1485 return log_syntax_internal(unit
, level
, config_file
, config_line
,
1486 SYNTHETIC_ERRNO(EINVAL
), file
, line
, func
,
1487 "String is not UTF-8 clean, ignoring assignment: %s", strna(p
));
1490 void log_set_upgrade_syslog_to_journal(bool b
) {
1491 upgrade_syslog_to_journal
= b
;
1493 /* Make the change effective immediately */
1495 if (log_target
== LOG_TARGET_SYSLOG
)
1496 log_target
= LOG_TARGET_JOURNAL
;
1497 else if (log_target
== LOG_TARGET_SYSLOG_OR_KMSG
)
1498 log_target
= LOG_TARGET_JOURNAL_OR_KMSG
;
1502 void log_set_always_reopen_console(bool b
) {
1503 always_reopen_console
= b
;
1506 void log_set_open_when_needed(bool b
) {
1507 open_when_needed
= b
;
1510 void log_set_prohibit_ipc(bool b
) {
1514 int log_emergency_level(void) {
1515 /* Returns the log level to use for log_emergency() logging. We use LOG_EMERG only when we are PID 1, as only
1516 * then the system of the whole system is obviously affected. */
1518 return getpid_cached() == 1 ? LOG_EMERG
: LOG_ERR
;
1521 int log_dup_console(void) {
1524 /* Duplicate the fd we use for fd logging if it's < 3 and use the copy from now on. This call is useful
1525 * whenever we want to continue logging through the original fd, but want to rearrange stderr. */
1527 if (console_fd
< 0 || console_fd
>= 3)
1530 copy
= fcntl(console_fd
, F_DUPFD_CLOEXEC
, 3);
1538 void log_setup(void) {
1539 log_set_target(LOG_TARGET_AUTO
);
1540 log_parse_environment();
1542 if (log_on_console() && show_color
< 0)
1543 log_show_color(true);
1546 static int saved_log_context_enabled
= -1;
1548 bool log_context_enabled(void) {
1551 if (log_get_max_level() == LOG_DEBUG
)
1554 if (saved_log_context_enabled
>= 0)
1555 return saved_log_context_enabled
;
1557 r
= getenv_bool_secure("SYSTEMD_ENABLE_LOG_CONTEXT");
1558 if (r
< 0 && r
!= -ENXIO
)
1559 log_debug_errno(r
, "Failed to parse $SYSTEMD_ENABLE_LOG_CONTEXT, ignoring: %m");
1561 saved_log_context_enabled
= r
> 0;
1563 return saved_log_context_enabled
;
1566 static LogContext
* log_context_attach(LogContext
*c
) {
1569 _log_context_num_fields
+= strv_length(c
->fields
);
1570 _log_context_num_fields
+= c
->n_input_iovec
;
1572 return LIST_PREPEND(ll
, _log_context
, c
);
1575 static LogContext
* log_context_detach(LogContext
*c
) {
1579 assert(_log_context_num_fields
>= strv_length(c
->fields
) + c
->n_input_iovec
);
1580 _log_context_num_fields
-= strv_length(c
->fields
);
1581 _log_context_num_fields
-= c
->n_input_iovec
;
1583 LIST_REMOVE(ll
, _log_context
, c
);
1587 LogContext
* log_context_new(char **fields
, bool owned
) {
1591 LIST_FOREACH(ll
, i
, _log_context
)
1592 if (i
->fields
== fields
) {
1594 return log_context_ref(i
);
1597 LogContext
*c
= new(LogContext
, 1);
1607 return log_context_attach(c
);
1610 LogContext
* log_context_newv(struct iovec
*input_iovec
, size_t n_input_iovec
, bool owned
) {
1611 if (!input_iovec
|| n_input_iovec
== 0)
1614 LIST_FOREACH(ll
, i
, _log_context
)
1615 if (i
->input_iovec
== input_iovec
&& i
->n_input_iovec
== n_input_iovec
) {
1617 return log_context_ref(i
);
1620 LogContext
*c
= new(LogContext
, 1);
1626 .input_iovec
= input_iovec
,
1627 .n_input_iovec
= n_input_iovec
,
1631 return log_context_attach(c
);
1634 static LogContext
* log_context_free(LogContext
*c
) {
1638 log_context_detach(c
);
1641 strv_free(c
->fields
);
1642 iovec_array_free(c
->input_iovec
, c
->n_input_iovec
);
1648 DEFINE_TRIVIAL_REF_UNREF_FUNC(LogContext
, log_context
, log_context_free
);
1650 LogContext
* log_context_new_consume(char **fields
) {
1651 LogContext
*c
= log_context_new(fields
, /*owned=*/ true);
1658 LogContext
* log_context_new_consumev(struct iovec
*input_iovec
, size_t n_input_iovec
) {
1659 LogContext
*c
= log_context_newv(input_iovec
, n_input_iovec
, /*owned=*/ true);
1661 iovec_array_free(input_iovec
, n_input_iovec
);
1666 size_t log_context_num_contexts(void) {
1669 LIST_FOREACH(ll
, c
, _log_context
)
1675 size_t log_context_num_fields(void) {
1676 return _log_context_num_fields
;