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"
20 #include "errno-util.h"
22 #include "format-util.h"
26 #include "missing_syscall.h"
27 #include "parse-util.h"
28 #include "proc-cmdline.h"
29 #include "process-util.h"
30 #include "ratelimit.h"
31 #include "signal-util.h"
32 #include "socket-util.h"
33 #include "stdio-util.h"
34 #include "string-table.h"
35 #include "string-util.h"
36 #include "syslog-util.h"
37 #include "terminal-util.h"
38 #include "time-util.h"
41 #define SNDBUF_SIZE (8*1024*1024)
43 static log_syntax_callback_t log_syntax_callback
= NULL
;
44 static void *log_syntax_callback_userdata
= NULL
;
46 static LogTarget log_target
= LOG_TARGET_CONSOLE
;
47 static int log_max_level
= LOG_INFO
;
48 static int log_facility
= LOG_DAEMON
;
50 static int console_fd
= STDERR_FILENO
;
51 static int syslog_fd
= -EBADF
;
52 static int kmsg_fd
= -EBADF
;
53 static int journal_fd
= -EBADF
;
55 static bool syslog_is_stream
= false;
57 static int show_color
= -1; /* tristate */
58 static bool show_location
= false;
59 static bool show_time
= false;
60 static bool show_tid
= false;
62 static bool upgrade_syslog_to_journal
= false;
63 static bool always_reopen_console
= false;
64 static bool open_when_needed
= false;
65 static bool prohibit_ipc
= false;
67 /* Akin to glibc's __abort_msg; which is private and we hence cannot
69 static char *log_abort_msg
= NULL
;
71 #if LOG_MESSAGE_VERIFICATION || defined(__COVERITY__)
72 bool _log_message_dummy
= false; /* Always false */
75 /* An assert to use in logging functions that does not call recursively
76 * into our logging functions (since that might lead to a loop). */
77 #define assert_raw(expr) \
79 if (_unlikely_(!(expr))) { \
80 fputs(#expr "\n", stderr); \
85 static void log_close_console(void) {
86 console_fd
= safe_close_above_stdio(console_fd
);
89 static int log_open_console(void) {
91 if (!always_reopen_console
) {
92 console_fd
= STDERR_FILENO
;
99 fd
= open_terminal("/dev/console", O_WRONLY
|O_NOCTTY
|O_CLOEXEC
);
103 console_fd
= fd_move_above_stdio(fd
);
109 static void log_close_kmsg(void) {
110 kmsg_fd
= safe_close(kmsg_fd
);
113 static int log_open_kmsg(void) {
118 kmsg_fd
= open("/dev/kmsg", O_WRONLY
|O_NOCTTY
|O_CLOEXEC
);
122 kmsg_fd
= fd_move_above_stdio(kmsg_fd
);
126 static void log_close_syslog(void) {
127 syslog_fd
= safe_close(syslog_fd
);
130 static int create_log_socket(int type
) {
134 fd
= socket(AF_UNIX
, type
|SOCK_CLOEXEC
, 0);
138 fd
= fd_move_above_stdio(fd
);
139 (void) fd_inc_sndbuf(fd
, SNDBUF_SIZE
);
141 /* We need a blocking fd here since we'd otherwise lose messages way too early. However, let's not hang forever
142 * in the unlikely case of a deadlock. */
143 if (getpid_cached() == 1)
144 timeval_store(&tv
, 10 * USEC_PER_MSEC
);
146 timeval_store(&tv
, 10 * USEC_PER_SEC
);
147 (void) setsockopt(fd
, SOL_SOCKET
, SO_SNDTIMEO
, &tv
, sizeof(tv
));
152 static int log_open_syslog(void) {
158 syslog_fd
= create_log_socket(SOCK_DGRAM
);
164 r
= connect_unix_path(syslog_fd
, AT_FDCWD
, "/dev/log");
166 safe_close(syslog_fd
);
168 /* Some legacy syslog systems still use stream sockets. They really shouldn't. But what can
170 syslog_fd
= create_log_socket(SOCK_STREAM
);
176 r
= connect_unix_path(syslog_fd
, AT_FDCWD
, "/dev/log");
180 syslog_is_stream
= true;
182 syslog_is_stream
= false;
191 static void log_close_journal(void) {
192 journal_fd
= safe_close(journal_fd
);
195 static int log_open_journal(void) {
201 journal_fd
= create_log_socket(SOCK_DGRAM
);
202 if (journal_fd
< 0) {
207 r
= connect_unix_path(journal_fd
, AT_FDCWD
, "/run/systemd/journal/socket");
218 static bool stderr_is_journal(void) {
219 _cleanup_free_
char *w
= NULL
;
224 e
= getenv("JOURNAL_STREAM");
228 if (extract_first_word(&e
, &w
, ":", EXTRACT_DONT_COALESCE_SEPARATORS
) <= 0)
233 if (safe_atou64(w
, &dev
) < 0)
235 if (safe_atou64(e
, &ino
) < 0)
238 if (fstat(STDERR_FILENO
, &st
) < 0)
241 return st
.st_dev
== dev
&& st
.st_ino
== ino
;
247 /* Do not call from library code. */
249 /* This function is often called in preparation for logging. Let's make sure we don't clobber errno,
250 * so that a call to a logging function immediately following a log_open() call can still easily
251 * reference an error that happened immediately before the log_open() call. */
254 /* If we don't use the console, we close it here to not get killed by SAK. If we don't use syslog, we
255 * close it here too, so that we are not confused by somebody deleting the socket in the fs, and to
256 * make sure we don't use it if prohibit_ipc is set. If we don't use /dev/kmsg we still keep it open,
257 * because there is no reason to close it. */
259 if (log_target
== LOG_TARGET_NULL
) {
266 if (getpid_cached() == 1 ||
267 stderr_is_journal() ||
271 LOG_TARGET_JOURNAL_OR_KMSG
,
273 LOG_TARGET_SYSLOG_OR_KMSG
)) {
276 if (IN_SET(log_target
,
278 LOG_TARGET_JOURNAL_OR_KMSG
,
279 LOG_TARGET_JOURNAL
)) {
281 r
= log_open_journal();
289 if (IN_SET(log_target
,
290 LOG_TARGET_SYSLOG_OR_KMSG
,
291 LOG_TARGET_SYSLOG
)) {
293 r
= log_open_syslog();
302 if (IN_SET(log_target
, LOG_TARGET_AUTO
,
303 LOG_TARGET_JOURNAL_OR_KMSG
,
304 LOG_TARGET_SYSLOG_OR_KMSG
,
319 return log_open_console();
322 void log_set_target(LogTarget target
) {
324 assert(target
< _LOG_TARGET_MAX
);
326 if (upgrade_syslog_to_journal
) {
327 if (target
== LOG_TARGET_SYSLOG
)
328 target
= LOG_TARGET_JOURNAL
;
329 else if (target
== LOG_TARGET_SYSLOG_OR_KMSG
)
330 target
= LOG_TARGET_JOURNAL_OR_KMSG
;
336 void log_close(void) {
337 /* Do not call from library code. */
345 void log_forget_fds(void) {
346 /* Do not call from library code. */
348 console_fd
= kmsg_fd
= syslog_fd
= journal_fd
= -EBADF
;
351 void log_set_max_level(int level
) {
352 assert(level
== LOG_NULL
|| (level
& LOG_PRIMASK
) == level
);
354 log_max_level
= level
;
357 void log_set_facility(int facility
) {
358 log_facility
= facility
;
361 static int write_to_console(
367 const char *buffer
) {
370 header_time
[FORMAT_TIMESTAMP_MAX
],
371 prefix
[1 + DECIMAL_STR_MAX(int) + 2],
372 tid_string
[3 + DECIMAL_STR_MAX(pid_t
) + 1];
373 struct iovec iovec
[9];
374 const char *on
= NULL
, *off
= NULL
;
380 if (log_target
== LOG_TARGET_CONSOLE_PREFIXED
) {
381 xsprintf(prefix
, "<%i>", level
);
382 iovec
[n
++] = IOVEC_MAKE_STRING(prefix
);
386 format_timestamp(header_time
, sizeof(header_time
), now(CLOCK_REALTIME
))) {
387 iovec
[n
++] = IOVEC_MAKE_STRING(header_time
);
388 iovec
[n
++] = IOVEC_MAKE_STRING(" ");
392 xsprintf(tid_string
, "(" PID_FMT
") ", gettid());
393 iovec
[n
++] = IOVEC_MAKE_STRING(tid_string
);
396 if (log_get_show_color())
397 get_log_colors(LOG_PRI(level
), &on
, &off
, NULL
);
400 const char *lon
= "", *loff
= "";
401 if (log_get_show_color()) {
402 lon
= ansi_highlight_yellow4();
403 loff
= ansi_normal();
406 (void) snprintf(location
, sizeof location
, "%s%s:%i%s: ", lon
, file
, line
, loff
);
407 iovec
[n
++] = IOVEC_MAKE_STRING(location
);
411 iovec
[n
++] = IOVEC_MAKE_STRING(on
);
412 iovec
[n
++] = IOVEC_MAKE_STRING(buffer
);
414 iovec
[n
++] = IOVEC_MAKE_STRING(off
);
415 iovec
[n
++] = IOVEC_MAKE_STRING("\n");
417 if (writev(console_fd
, iovec
, n
) < 0) {
419 if (errno
== EIO
&& getpid_cached() == 1) {
421 /* If somebody tried to kick us from our console tty (via vhangup() or suchlike), try
425 (void) log_open_console();
429 if (writev(console_fd
, iovec
, n
) < 0)
438 static int write_to_syslog(
444 const char *buffer
) {
446 char header_priority
[2 + DECIMAL_STR_MAX(int) + 1],
448 header_pid
[4 + DECIMAL_STR_MAX(pid_t
) + 1];
455 xsprintf(header_priority
, "<%i>", level
);
457 t
= (time_t) (now(CLOCK_REALTIME
) / USEC_PER_SEC
);
458 if (!localtime_r(&t
, &tm
))
461 if (strftime(header_time
, sizeof(header_time
), "%h %e %T ", &tm
) <= 0)
464 xsprintf(header_pid
, "["PID_FMT
"]: ", getpid_cached());
466 struct iovec iovec
[] = {
467 IOVEC_MAKE_STRING(header_priority
),
468 IOVEC_MAKE_STRING(header_time
),
469 IOVEC_MAKE_STRING(program_invocation_short_name
),
470 IOVEC_MAKE_STRING(header_pid
),
471 IOVEC_MAKE_STRING(buffer
),
473 const struct msghdr msghdr
= {
475 .msg_iovlen
= ELEMENTSOF(iovec
),
478 /* When using syslog via SOCK_STREAM separate the messages by NUL chars */
479 if (syslog_is_stream
)
480 iovec
[ELEMENTSOF(iovec
) - 1].iov_len
++;
485 n
= sendmsg(syslog_fd
, &msghdr
, MSG_NOSIGNAL
);
489 if (!syslog_is_stream
)
492 if (IOVEC_INCREMENT(iovec
, ELEMENTSOF(iovec
), n
))
499 static int write_to_kmsg(
505 const char *buffer
) {
507 /* Set a ratelimit on the amount of messages logged to /dev/kmsg. This is mostly supposed to be a
508 * safety catch for the case where start indiscriminately logging in a loop. It will not catch cases
509 * where we log excessively, but not in a tight loop.
511 * Note that this ratelimit is per-emitter, so we might still overwhelm /dev/kmsg with multiple
514 static thread_local RateLimit ratelimit
= { 5 * USEC_PER_SEC
, 200 };
516 char header_priority
[2 + DECIMAL_STR_MAX(int) + 1],
517 header_pid
[4 + DECIMAL_STR_MAX(pid_t
) + 1];
522 if (!ratelimit_below(&ratelimit
))
525 xsprintf(header_priority
, "<%i>", level
);
526 xsprintf(header_pid
, "["PID_FMT
"]: ", getpid_cached());
528 const struct iovec iovec
[] = {
529 IOVEC_MAKE_STRING(header_priority
),
530 IOVEC_MAKE_STRING(program_invocation_short_name
),
531 IOVEC_MAKE_STRING(header_pid
),
532 IOVEC_MAKE_STRING(buffer
),
533 IOVEC_MAKE_STRING("\n"),
536 if (writev(kmsg_fd
, iovec
, ELEMENTSOF(iovec
)) < 0)
542 static int log_do_header(
547 const char *file
, int line
, const char *func
,
548 const char *object_field
, const char *object
,
549 const char *extra_field
, const char *extra
) {
552 error
= IS_SYNTHETIC_ERRNO(error
) ? 0 : ERRNO_VALUE(error
);
554 r
= snprintf(header
, size
,
556 "SYSLOG_FACILITY=%i\n"
558 "%s%.256s%s" /* CODE_FILE */
559 "%s%.*i%s" /* CODE_LINE */
560 "%s%.256s%s" /* CODE_FUNC */
561 "%s%.*i%s" /* ERRNO */
562 "%s%.256s%s" /* object */
563 "%s%.256s%s" /* extra */
564 "SYSLOG_IDENTIFIER=%.256s\n",
568 isempty(file
) ? "" : "CODE_FILE=",
569 isempty(file
) ? "" : file
,
570 isempty(file
) ? "" : "\n",
571 line
? "CODE_LINE=" : "",
572 line
? 1 : 0, line
, /* %.0d means no output too, special case for 0 */
574 isempty(func
) ? "" : "CODE_FUNC=",
575 isempty(func
) ? "" : func
,
576 isempty(func
) ? "" : "\n",
577 error
? "ERRNO=" : "",
578 error
? 1 : 0, error
,
580 isempty(object
) ? "" : object_field
,
581 isempty(object
) ? "" : object
,
582 isempty(object
) ? "" : "\n",
583 isempty(extra
) ? "" : extra_field
,
584 isempty(extra
) ? "" : extra
,
585 isempty(extra
) ? "" : "\n",
586 program_invocation_short_name
);
587 assert_raw((size_t) r
< size
);
592 static int write_to_journal(
598 const char *object_field
,
600 const char *extra_field
,
602 const char *buffer
) {
604 char header
[LINE_MAX
];
609 log_do_header(header
, sizeof(header
), level
, error
, file
, line
, func
, object_field
, object
, extra_field
, extra
);
611 struct iovec iovec
[4] = {
612 IOVEC_MAKE_STRING(header
),
613 IOVEC_MAKE_STRING("MESSAGE="),
614 IOVEC_MAKE_STRING(buffer
),
615 IOVEC_MAKE_STRING("\n"),
617 const struct msghdr msghdr
= {
619 .msg_iovlen
= ELEMENTSOF(iovec
),
622 if (sendmsg(journal_fd
, &msghdr
, MSG_NOSIGNAL
) < 0)
628 int log_dispatch_internal(
634 const char *object_field
,
636 const char *extra_field
,
642 if (log_target
== LOG_TARGET_NULL
)
643 return -ERRNO_VALUE(error
);
645 /* Patch in LOG_DAEMON facility if necessary */
646 if ((level
& LOG_FACMASK
) == 0)
647 level
|= log_facility
;
649 if (open_when_needed
)
656 buffer
+= strspn(buffer
, NEWLINE
);
661 if ((e
= strpbrk(buffer
, NEWLINE
)))
664 if (IN_SET(log_target
, LOG_TARGET_AUTO
,
665 LOG_TARGET_JOURNAL_OR_KMSG
,
666 LOG_TARGET_JOURNAL
)) {
668 k
= write_to_journal(level
, error
, file
, line
, func
, object_field
, object
, extra_field
, extra
, buffer
);
669 if (k
< 0 && k
!= -EAGAIN
)
673 if (IN_SET(log_target
, LOG_TARGET_SYSLOG_OR_KMSG
,
674 LOG_TARGET_SYSLOG
)) {
676 k
= write_to_syslog(level
, error
, file
, line
, func
, buffer
);
677 if (k
< 0 && k
!= -EAGAIN
)
682 IN_SET(log_target
, LOG_TARGET_AUTO
,
683 LOG_TARGET_SYSLOG_OR_KMSG
,
684 LOG_TARGET_JOURNAL_OR_KMSG
,
690 k
= write_to_kmsg(level
, error
, file
, line
, func
, buffer
);
693 (void) log_open_console();
698 (void) write_to_console(level
, error
, file
, line
, func
, buffer
);
703 if (open_when_needed
)
706 return -ERRNO_VALUE(error
);
709 int log_dump_internal(
719 /* This modifies the buffer... */
721 if (_likely_(LOG_PRI(level
) > log_max_level
))
722 return -ERRNO_VALUE(error
);
724 return log_dispatch_internal(level
, error
, file
, line
, func
, NULL
, NULL
, NULL
, NULL
, buffer
);
736 if (_likely_(LOG_PRI(level
) > log_max_level
))
737 return -ERRNO_VALUE(error
);
739 /* Make sure that %m maps to the specified error (or "Success"). */
740 char buffer
[LINE_MAX
];
741 LOCAL_ERRNO(ERRNO_VALUE(error
));
743 (void) vsnprintf(buffer
, sizeof buffer
, format
, ap
);
745 return log_dispatch_internal(level
, error
, file
, line
, func
, NULL
, NULL
, NULL
, NULL
, buffer
);
754 const char *format
, ...) {
759 va_start(ap
, format
);
760 r
= log_internalv(level
, error
, file
, line
, func
, format
, ap
);
766 int log_object_internalv(
772 const char *object_field
,
774 const char *extra_field
,
781 if (_likely_(LOG_PRI(level
) > log_max_level
))
782 return -ERRNO_VALUE(error
);
784 /* Make sure that %m maps to the specified error (or "Success"). */
785 LOCAL_ERRNO(ERRNO_VALUE(error
));
787 /* Prepend the object name before the message */
792 buffer
= newa(char, n
+ 2 + LINE_MAX
);
793 b
= stpcpy(stpcpy(buffer
, object
), ": ");
795 b
= buffer
= newa(char, LINE_MAX
);
797 (void) vsnprintf(b
, LINE_MAX
, format
, ap
);
799 return log_dispatch_internal(level
, error
, file
, line
, func
,
800 object_field
, object
, extra_field
, extra
, buffer
);
803 int log_object_internal(
809 const char *object_field
,
811 const char *extra_field
,
813 const char *format
, ...) {
818 va_start(ap
, format
);
819 r
= log_object_internalv(level
, error
, file
, line
, func
, object_field
, object
, extra_field
, extra
, format
, ap
);
825 static void log_assert(
831 const char *format
) {
833 static char buffer
[LINE_MAX
];
835 if (_likely_(LOG_PRI(level
) > log_max_level
))
838 DISABLE_WARNING_FORMAT_NONLITERAL
;
839 (void) snprintf(buffer
, sizeof buffer
, format
, text
, file
, line
, func
);
842 log_abort_msg
= buffer
;
844 log_dispatch_internal(level
, 0, file
, line
, func
, NULL
, NULL
, NULL
, NULL
, buffer
);
847 _noreturn_
void log_assert_failed(
852 log_assert(LOG_CRIT
, text
, file
, line
, func
,
853 "Assertion '%s' failed at %s:%u, function %s(). Aborting.");
857 _noreturn_
void log_assert_failed_unreachable(
861 log_assert(LOG_CRIT
, "Code should not be reached", file
, line
, func
,
862 "%s at %s:%u, function %s(). Aborting. 💥");
866 void log_assert_failed_return(
872 log_assert(LOG_DEBUG
, text
, file
, line
, func
,
873 "Assertion '%s' failed at %s:%u, function %s(). Ignoring.");
876 int log_oom_internal(int level
, const char *file
, int line
, const char *func
) {
877 return log_internal(level
, ENOMEM
, file
, line
, func
, "Out of memory.");
880 int log_format_iovec(
884 bool newline_separator
,
889 static const char nl
= '\n';
891 while (format
&& *n
+ 1 < iovec_len
) {
896 /* We need to copy the va_list structure,
897 * since vasprintf() leaves it afterwards at
898 * an undefined location */
900 errno
= ERRNO_VALUE(error
);
903 r
= vasprintf(&m
, format
, aq
);
908 /* Now, jump enough ahead, so that we point to
909 * the next format string */
910 VA_FORMAT_ADVANCE(format
, ap
);
912 iovec
[(*n
)++] = IOVEC_MAKE_STRING(m
);
913 if (newline_separator
)
914 iovec
[(*n
)++] = IOVEC_MAKE((char *)&nl
, 1);
916 format
= va_arg(ap
, char *);
921 int log_struct_internal(
927 const char *format
, ...) {
934 if (_likely_(LOG_PRI(level
) > log_max_level
) ||
935 log_target
== LOG_TARGET_NULL
)
936 return -ERRNO_VALUE(error
);
938 if ((level
& LOG_FACMASK
) == 0)
939 level
|= log_facility
;
941 if (IN_SET(log_target
,
943 LOG_TARGET_JOURNAL_OR_KMSG
,
944 LOG_TARGET_JOURNAL
)) {
946 if (open_when_needed
)
949 if (journal_fd
>= 0) {
950 char header
[LINE_MAX
];
951 struct iovec iovec
[17];
954 bool fallback
= false;
956 /* If the journal is available do structured logging.
957 * Do not report the errno if it is synthetic. */
958 log_do_header(header
, sizeof(header
), level
, error
, file
, line
, func
, NULL
, NULL
, NULL
, NULL
);
959 iovec
[n
++] = IOVEC_MAKE_STRING(header
);
961 va_start(ap
, format
);
962 r
= log_format_iovec(iovec
, ELEMENTSOF(iovec
), &n
, true, error
, format
, ap
);
966 const struct msghdr msghdr
= {
971 (void) sendmsg(journal_fd
, &msghdr
, MSG_NOSIGNAL
);
975 for (size_t i
= 1; i
< n
; i
+= 2)
976 free(iovec
[i
].iov_base
);
979 if (open_when_needed
)
982 return -ERRNO_VALUE(error
);
987 /* Fallback if journal logging is not available or didn't work. */
989 va_start(ap
, format
);
993 errno
= ERRNO_VALUE(error
);
996 (void) vsnprintf(buf
, sizeof buf
, format
, aq
);
999 if (startswith(buf
, "MESSAGE=")) {
1004 VA_FORMAT_ADVANCE(format
, ap
);
1006 format
= va_arg(ap
, char *);
1011 if (open_when_needed
)
1014 return -ERRNO_VALUE(error
);
1017 return log_dispatch_internal(level
, error
, file
, line
, func
, NULL
, NULL
, NULL
, NULL
, buf
+ 8);
1020 int log_struct_iovec_internal(
1026 const struct iovec input_iovec
[],
1027 size_t n_input_iovec
) {
1031 if (_likely_(LOG_PRI(level
) > log_max_level
) ||
1032 log_target
== LOG_TARGET_NULL
)
1033 return -ERRNO_VALUE(error
);
1035 if ((level
& LOG_FACMASK
) == 0)
1036 level
|= log_facility
;
1038 if (IN_SET(log_target
, LOG_TARGET_AUTO
,
1039 LOG_TARGET_JOURNAL_OR_KMSG
,
1040 LOG_TARGET_JOURNAL
) &&
1043 char header
[LINE_MAX
];
1044 log_do_header(header
, sizeof(header
), level
, error
, file
, line
, func
, NULL
, NULL
, NULL
, NULL
);
1046 struct iovec iovec
[1 + n_input_iovec
*2];
1047 iovec
[0] = IOVEC_MAKE_STRING(header
);
1048 for (size_t i
= 0; i
< n_input_iovec
; i
++) {
1049 iovec
[1+i
*2] = input_iovec
[i
];
1050 iovec
[1+i
*2+1] = IOVEC_MAKE_STRING("\n");
1053 const struct msghdr msghdr
= {
1055 .msg_iovlen
= 1 + n_input_iovec
*2,
1058 if (sendmsg(journal_fd
, &msghdr
, MSG_NOSIGNAL
) >= 0)
1059 return -ERRNO_VALUE(error
);
1062 for (size_t i
= 0; i
< n_input_iovec
; i
++)
1063 if (memory_startswith(input_iovec
[i
].iov_base
, input_iovec
[i
].iov_len
, "MESSAGE=")) {
1066 m
= strndupa_safe((char*) input_iovec
[i
].iov_base
+ STRLEN("MESSAGE="),
1067 input_iovec
[i
].iov_len
- STRLEN("MESSAGE="));
1069 return log_dispatch_internal(level
, error
, file
, line
, func
, NULL
, NULL
, NULL
, NULL
, m
);
1072 /* Couldn't find MESSAGE=. */
1073 return -ERRNO_VALUE(error
);
1076 int log_set_target_from_string(const char *e
) {
1079 t
= log_target_from_string(e
);
1087 int log_set_max_level_from_string(const char *e
) {
1090 t
= log_level_from_string(e
);
1094 log_set_max_level(t
);
1098 static int parse_proc_cmdline_item(const char *key
, const char *value
, void *data
) {
1101 * The systemd.log_xyz= settings are parsed by all tools, and
1104 * However, "quiet" is only parsed by PID 1, and only turns of
1105 * status output to /dev/console, but does not alter the log
1109 if (streq(key
, "debug") && !value
)
1110 log_set_max_level(LOG_DEBUG
);
1112 else if (proc_cmdline_key_streq(key
, "systemd.log_target")) {
1114 if (proc_cmdline_value_missing(key
, value
))
1117 if (log_set_target_from_string(value
) < 0)
1118 log_warning("Failed to parse log target '%s'. Ignoring.", value
);
1120 } else if (proc_cmdline_key_streq(key
, "systemd.log_level")) {
1122 if (proc_cmdline_value_missing(key
, value
))
1125 if (log_set_max_level_from_string(value
) < 0)
1126 log_warning("Failed to parse log level '%s'. Ignoring.", value
);
1128 } else if (proc_cmdline_key_streq(key
, "systemd.log_color")) {
1130 if (log_show_color_from_string(value
?: "1") < 0)
1131 log_warning("Failed to parse log color setting '%s'. Ignoring.", value
);
1133 } else if (proc_cmdline_key_streq(key
, "systemd.log_location")) {
1135 if (log_show_location_from_string(value
?: "1") < 0)
1136 log_warning("Failed to parse log location setting '%s'. Ignoring.", value
);
1138 } else if (proc_cmdline_key_streq(key
, "systemd.log_tid")) {
1140 if (log_show_tid_from_string(value
?: "1") < 0)
1141 log_warning("Failed to parse log tid setting '%s'. Ignoring.", value
);
1143 } else if (proc_cmdline_key_streq(key
, "systemd.log_time")) {
1145 if (log_show_time_from_string(value
?: "1") < 0)
1146 log_warning("Failed to parse log time setting '%s'. Ignoring.", value
);
1153 static bool should_parse_proc_cmdline(void) {
1154 /* PID1 always reads the kernel command line. */
1155 if (getpid_cached() == 1)
1158 /* Otherwise, parse the commandline if invoked directly by systemd. */
1159 return invoked_by_systemd();
1162 void log_parse_environment_variables(void) {
1165 e
= getenv("SYSTEMD_LOG_TARGET");
1166 if (e
&& log_set_target_from_string(e
) < 0)
1167 log_warning("Failed to parse log target '%s'. Ignoring.", e
);
1169 e
= getenv("SYSTEMD_LOG_LEVEL");
1170 if (e
&& log_set_max_level_from_string(e
) < 0)
1171 log_warning("Failed to parse log level '%s'. Ignoring.", e
);
1173 e
= getenv("SYSTEMD_LOG_COLOR");
1174 if (e
&& log_show_color_from_string(e
) < 0)
1175 log_warning("Failed to parse log color '%s'. Ignoring.", e
);
1177 e
= getenv("SYSTEMD_LOG_LOCATION");
1178 if (e
&& log_show_location_from_string(e
) < 0)
1179 log_warning("Failed to parse log location '%s'. Ignoring.", e
);
1181 e
= getenv("SYSTEMD_LOG_TIME");
1182 if (e
&& log_show_time_from_string(e
) < 0)
1183 log_warning("Failed to parse log time '%s'. Ignoring.", e
);
1185 e
= getenv("SYSTEMD_LOG_TID");
1186 if (e
&& log_show_tid_from_string(e
) < 0)
1187 log_warning("Failed to parse log tid '%s'. Ignoring.", e
);
1190 void log_parse_environment(void) {
1191 /* Do not call from library code. */
1193 if (should_parse_proc_cmdline())
1194 (void) proc_cmdline_parse(parse_proc_cmdline_item
, NULL
, PROC_CMDLINE_STRIP_RD_PREFIX
);
1196 log_parse_environment_variables();
1199 LogTarget
log_get_target(void) {
1203 int log_get_max_level(void) {
1204 return log_max_level
;
1207 void log_show_color(bool b
) {
1211 bool log_get_show_color(void) {
1212 return show_color
> 0; /* Defaults to false. */
1215 void log_show_location(bool b
) {
1219 bool log_get_show_location(void) {
1220 return show_location
;
1223 void log_show_time(bool b
) {
1227 bool log_get_show_time(void) {
1231 void log_show_tid(bool b
) {
1235 bool log_get_show_tid(void) {
1239 int log_show_color_from_string(const char *e
) {
1242 t
= parse_boolean(e
);
1250 int log_show_location_from_string(const char *e
) {
1253 t
= parse_boolean(e
);
1257 log_show_location(t
);
1261 int log_show_time_from_string(const char *e
) {
1264 t
= parse_boolean(e
);
1272 int log_show_tid_from_string(const char *e
) {
1275 t
= parse_boolean(e
);
1283 bool log_on_console(void) {
1284 if (IN_SET(log_target
, LOG_TARGET_CONSOLE
,
1285 LOG_TARGET_CONSOLE_PREFIXED
))
1288 return syslog_fd
< 0 && kmsg_fd
< 0 && journal_fd
< 0;
1291 static const char *const log_target_table
[_LOG_TARGET_MAX
] = {
1292 [LOG_TARGET_CONSOLE
] = "console",
1293 [LOG_TARGET_CONSOLE_PREFIXED
] = "console-prefixed",
1294 [LOG_TARGET_KMSG
] = "kmsg",
1295 [LOG_TARGET_JOURNAL
] = "journal",
1296 [LOG_TARGET_JOURNAL_OR_KMSG
] = "journal-or-kmsg",
1297 [LOG_TARGET_SYSLOG
] = "syslog",
1298 [LOG_TARGET_SYSLOG_OR_KMSG
] = "syslog-or-kmsg",
1299 [LOG_TARGET_AUTO
] = "auto",
1300 [LOG_TARGET_NULL
] = "null",
1303 DEFINE_STRING_TABLE_LOOKUP(log_target
, LogTarget
);
1305 void log_received_signal(int level
, const struct signalfd_siginfo
*si
) {
1308 if (pid_is_valid(si
->ssi_pid
)) {
1309 _cleanup_free_
char *p
= NULL
;
1311 (void) get_process_comm(si
->ssi_pid
, &p
);
1314 "Received SIG%s from PID %"PRIu32
" (%s).",
1315 signal_to_string(si
->ssi_signo
),
1316 si
->ssi_pid
, strna(p
));
1320 signal_to_string(si
->ssi_signo
));
1323 void set_log_syntax_callback(log_syntax_callback_t cb
, void *userdata
) {
1324 assert(!log_syntax_callback
|| !cb
);
1325 assert(!log_syntax_callback_userdata
|| !userdata
);
1327 log_syntax_callback
= cb
;
1328 log_syntax_callback_userdata
= userdata
;
1331 int log_syntax_internal(
1334 const char *config_file
,
1335 unsigned config_line
,
1340 const char *format
, ...) {
1344 if (log_syntax_callback
)
1345 log_syntax_callback(unit
, level
, log_syntax_callback_userdata
);
1347 if (_likely_(LOG_PRI(level
) > log_max_level
) ||
1348 log_target
== LOG_TARGET_NULL
)
1349 return -ERRNO_VALUE(error
);
1351 char buffer
[LINE_MAX
];
1353 const char *unit_fmt
= NULL
;
1355 errno
= ERRNO_VALUE(error
);
1357 va_start(ap
, format
);
1358 (void) vsnprintf(buffer
, sizeof buffer
, format
, ap
);
1362 unit_fmt
= getpid_cached() == 1 ? "UNIT=%s" : "USER_UNIT=%s";
1365 if (config_line
> 0)
1366 return log_struct_internal(
1370 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR
,
1371 "CONFIG_FILE=%s", config_file
,
1372 "CONFIG_LINE=%u", config_line
,
1373 LOG_MESSAGE("%s:%u: %s", config_file
, config_line
, buffer
),
1377 return log_struct_internal(
1381 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR
,
1382 "CONFIG_FILE=%s", config_file
,
1383 LOG_MESSAGE("%s: %s", config_file
, buffer
),
1387 return log_struct_internal(
1391 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR
,
1392 LOG_MESSAGE("%s: %s", unit
, buffer
),
1396 return log_struct_internal(
1400 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR
,
1401 LOG_MESSAGE("%s", buffer
),
1405 int log_syntax_invalid_utf8_internal(
1408 const char *config_file
,
1409 unsigned config_line
,
1413 const char *rvalue
) {
1415 _cleanup_free_
char *p
= NULL
;
1418 p
= utf8_escape_invalid(rvalue
);
1420 return log_syntax_internal(unit
, level
, config_file
, config_line
,
1421 SYNTHETIC_ERRNO(EINVAL
), file
, line
, func
,
1422 "String is not UTF-8 clean, ignoring assignment: %s", strna(p
));
1425 void log_set_upgrade_syslog_to_journal(bool b
) {
1426 upgrade_syslog_to_journal
= b
;
1428 /* Make the change effective immediately */
1430 if (log_target
== LOG_TARGET_SYSLOG
)
1431 log_target
= LOG_TARGET_JOURNAL
;
1432 else if (log_target
== LOG_TARGET_SYSLOG_OR_KMSG
)
1433 log_target
= LOG_TARGET_JOURNAL_OR_KMSG
;
1437 void log_set_always_reopen_console(bool b
) {
1438 always_reopen_console
= b
;
1441 void log_set_open_when_needed(bool b
) {
1442 open_when_needed
= b
;
1445 void log_set_prohibit_ipc(bool b
) {
1449 int log_emergency_level(void) {
1450 /* Returns the log level to use for log_emergency() logging. We use LOG_EMERG only when we are PID 1, as only
1451 * then the system of the whole system is obviously affected. */
1453 return getpid_cached() == 1 ? LOG_EMERG
: LOG_ERR
;
1456 int log_dup_console(void) {
1459 /* Duplicate the fd we use for fd logging if it's < 3 and use the copy from now on. This call is useful
1460 * whenever we want to continue logging through the original fd, but want to rearrange stderr. */
1462 if (console_fd
< 0 || console_fd
>= 3)
1465 copy
= fcntl(console_fd
, F_DUPFD_CLOEXEC
, 3);
1473 void log_setup(void) {
1474 log_set_target(LOG_TARGET_AUTO
);
1475 log_parse_environment();
1477 if (log_on_console() && show_color
< 0)
1478 log_show_color(true);