1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2010 Lennart Poettering
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
29 #include <sys/signalfd.h>
30 #include <sys/socket.h>
37 #include "sd-messages.h"
39 #include "alloc-util.h"
41 #include "format-util.h"
46 #include "parse-util.h"
47 #include "proc-cmdline.h"
48 #include "process-util.h"
49 #include "signal-util.h"
50 #include "socket-util.h"
51 #include "stdio-util.h"
52 #include "string-table.h"
53 #include "string-util.h"
54 #include "syslog-util.h"
55 #include "terminal-util.h"
56 #include "time-util.h"
60 #define SNDBUF_SIZE (8*1024*1024)
62 static LogTarget log_target
= LOG_TARGET_CONSOLE
;
63 static int log_max_level
[] = {LOG_INFO
, LOG_INFO
};
64 assert_cc(ELEMENTSOF(log_max_level
) == _LOG_REALM_MAX
);
65 static int log_facility
= LOG_DAEMON
;
67 static int console_fd
= STDERR_FILENO
;
68 static int syslog_fd
= -1;
69 static int kmsg_fd
= -1;
70 static int journal_fd
= -1;
72 static bool syslog_is_stream
= false;
74 static bool show_color
= false;
75 static bool show_location
= false;
77 static bool upgrade_syslog_to_journal
= false;
78 static bool always_reopen_console
= false;
79 static bool open_when_needed
= false;
81 /* Akin to glibc's __abort_msg; which is private and we hence cannot
83 static char *log_abort_msg
= NULL
;
85 void log_close_console(void) {
90 if (getpid_cached() == 1) {
92 safe_close(console_fd
);
98 static int log_open_console(void) {
103 if (always_reopen_console
) {
104 console_fd
= open_terminal("/dev/console", O_WRONLY
|O_NOCTTY
|O_CLOEXEC
);
108 console_fd
= STDERR_FILENO
;
113 void log_close_kmsg(void) {
114 kmsg_fd
= safe_close(kmsg_fd
);
117 static int log_open_kmsg(void) {
122 kmsg_fd
= open("/dev/kmsg", O_WRONLY
|O_NOCTTY
|O_CLOEXEC
);
129 void log_close_syslog(void) {
130 syslog_fd
= safe_close(syslog_fd
);
133 static int create_log_socket(int type
) {
137 fd
= socket(AF_UNIX
, type
|SOCK_CLOEXEC
, 0);
141 (void) fd_inc_sndbuf(fd
, SNDBUF_SIZE
);
143 /* We need a blocking fd here since we'd otherwise lose
144 messages way too early. However, let's not hang forever in the
145 unlikely case of a deadlock. */
146 if (getpid_cached() == 1)
147 timeval_store(&tv
, 10 * USEC_PER_MSEC
);
149 timeval_store(&tv
, 10 * USEC_PER_SEC
);
150 (void) setsockopt(fd
, SOL_SOCKET
, SO_SNDTIMEO
, &tv
, sizeof(tv
));
155 static int log_open_syslog(void) {
157 static const union sockaddr_union sa
= {
158 .un
.sun_family
= AF_UNIX
,
159 .un
.sun_path
= "/dev/log",
167 syslog_fd
= create_log_socket(SOCK_DGRAM
);
173 if (connect(syslog_fd
, &sa
.sa
, SOCKADDR_UN_LEN(sa
.un
)) < 0) {
174 safe_close(syslog_fd
);
176 /* Some legacy syslog systems still use stream
177 * sockets. They really shouldn't. But what can we
179 syslog_fd
= create_log_socket(SOCK_STREAM
);
185 if (connect(syslog_fd
, &sa
.sa
, SOCKADDR_UN_LEN(sa
.un
)) < 0) {
190 syslog_is_stream
= true;
192 syslog_is_stream
= false;
201 void log_close_journal(void) {
202 journal_fd
= safe_close(journal_fd
);
205 static int log_open_journal(void) {
207 static const union sockaddr_union sa
= {
208 .un
.sun_family
= AF_UNIX
,
209 .un
.sun_path
= "/run/systemd/journal/socket",
217 journal_fd
= create_log_socket(SOCK_DGRAM
);
218 if (journal_fd
< 0) {
223 if (connect(journal_fd
, &sa
.sa
, SOCKADDR_UN_LEN(sa
.un
)) < 0) {
238 /* Do not call from library code. */
240 /* If we don't use the console we close it here, to not get
241 * killed by SAK. If we don't use syslog we close it here so
242 * that we are not confused by somebody deleting the socket in
243 * the fs. If we don't use /dev/kmsg we still keep it open,
244 * because there is no reason to close it. */
246 if (log_target
== LOG_TARGET_NULL
) {
253 if (!IN_SET(log_target
, LOG_TARGET_AUTO
, LOG_TARGET_SAFE
) ||
254 getpid_cached() == 1 ||
255 isatty(STDERR_FILENO
) <= 0) {
257 if (IN_SET(log_target
, LOG_TARGET_AUTO
,
258 LOG_TARGET_JOURNAL_OR_KMSG
,
259 LOG_TARGET_JOURNAL
)) {
260 r
= log_open_journal();
268 if (IN_SET(log_target
, LOG_TARGET_SYSLOG_OR_KMSG
,
269 LOG_TARGET_SYSLOG
)) {
270 r
= log_open_syslog();
278 if (IN_SET(log_target
, LOG_TARGET_AUTO
,
280 LOG_TARGET_JOURNAL_OR_KMSG
,
281 LOG_TARGET_SYSLOG_OR_KMSG
,
296 return log_open_console();
299 void log_set_target(LogTarget target
) {
301 assert(target
< _LOG_TARGET_MAX
);
303 if (upgrade_syslog_to_journal
) {
304 if (target
== LOG_TARGET_SYSLOG
)
305 target
= LOG_TARGET_JOURNAL
;
306 else if (target
== LOG_TARGET_SYSLOG_OR_KMSG
)
307 target
= LOG_TARGET_JOURNAL_OR_KMSG
;
313 void log_close(void) {
314 /* Do not call from library code. */
322 void log_forget_fds(void) {
323 /* Do not call from library code. */
325 console_fd
= kmsg_fd
= syslog_fd
= journal_fd
= -1;
328 void log_set_max_level_realm(LogRealm realm
, int level
) {
329 assert((level
& LOG_PRIMASK
) == level
);
330 assert(realm
< ELEMENTSOF(log_max_level
));
332 log_max_level
[realm
] = level
;
335 void log_set_facility(int facility
) {
336 log_facility
= facility
;
339 static int write_to_console(
345 const char *buffer
) {
347 char location
[256], prefix
[1 + DECIMAL_STR_MAX(int) + 2];
348 struct iovec iovec
[6] = {};
355 if (log_target
== LOG_TARGET_CONSOLE_PREFIXED
) {
356 xsprintf(prefix
, "<%i>", level
);
357 iovec
[n
++] = IOVEC_MAKE_STRING(prefix
);
360 highlight
= LOG_PRI(level
) <= LOG_ERR
&& show_color
;
363 xsprintf(location
, "(%s:%i) ", file
, line
);
364 iovec
[n
++] = IOVEC_MAKE_STRING(location
);
368 iovec
[n
++] = IOVEC_MAKE_STRING(ANSI_HIGHLIGHT_RED
);
369 iovec
[n
++] = IOVEC_MAKE_STRING(buffer
);
371 iovec
[n
++] = IOVEC_MAKE_STRING(ANSI_NORMAL
);
372 iovec
[n
++] = IOVEC_MAKE_STRING("\n");
374 if (writev(console_fd
, iovec
, n
) < 0) {
376 if (errno
== EIO
&& getpid_cached() == 1) {
378 /* If somebody tried to kick us from our
379 * console tty (via vhangup() or suchlike),
380 * try to reconnect */
388 if (writev(console_fd
, iovec
, n
) < 0)
397 static int write_to_syslog(
403 const char *buffer
) {
405 char header_priority
[2 + DECIMAL_STR_MAX(int) + 1],
407 header_pid
[4 + DECIMAL_STR_MAX(pid_t
) + 1];
408 struct iovec iovec
[5] = {};
409 struct msghdr msghdr
= {
411 .msg_iovlen
= ELEMENTSOF(iovec
),
419 xsprintf(header_priority
, "<%i>", level
);
421 t
= (time_t) (now(CLOCK_REALTIME
) / USEC_PER_SEC
);
426 if (strftime(header_time
, sizeof(header_time
), "%h %e %T ", tm
) <= 0)
429 xsprintf(header_pid
, "["PID_FMT
"]: ", getpid_cached());
431 iovec
[0] = IOVEC_MAKE_STRING(header_priority
);
432 iovec
[1] = IOVEC_MAKE_STRING(header_time
);
433 iovec
[2] = IOVEC_MAKE_STRING(program_invocation_short_name
);
434 iovec
[3] = IOVEC_MAKE_STRING(header_pid
);
435 iovec
[4] = IOVEC_MAKE_STRING(buffer
);
437 /* When using syslog via SOCK_STREAM separate the messages by NUL chars */
438 if (syslog_is_stream
)
444 n
= sendmsg(syslog_fd
, &msghdr
, MSG_NOSIGNAL
);
448 if (!syslog_is_stream
||
449 (size_t) n
>= IOVEC_TOTAL_SIZE(iovec
, ELEMENTSOF(iovec
)))
452 IOVEC_INCREMENT(iovec
, ELEMENTSOF(iovec
), n
);
458 static int write_to_kmsg(
464 const char *buffer
) {
466 char header_priority
[2 + DECIMAL_STR_MAX(int) + 1],
467 header_pid
[4 + DECIMAL_STR_MAX(pid_t
) + 1];
468 struct iovec iovec
[5] = {};
473 xsprintf(header_priority
, "<%i>", level
);
474 xsprintf(header_pid
, "["PID_FMT
"]: ", getpid_cached());
476 iovec
[0] = IOVEC_MAKE_STRING(header_priority
);
477 iovec
[1] = IOVEC_MAKE_STRING(program_invocation_short_name
);
478 iovec
[2] = IOVEC_MAKE_STRING(header_pid
);
479 iovec
[3] = IOVEC_MAKE_STRING(buffer
);
480 iovec
[4] = IOVEC_MAKE_STRING("\n");
482 if (writev(kmsg_fd
, iovec
, ELEMENTSOF(iovec
)) < 0)
488 static int log_do_header(
493 const char *file
, int line
, const char *func
,
494 const char *object_field
, const char *object
,
495 const char *extra_field
, const char *extra
) {
497 snprintf(header
, size
,
499 "SYSLOG_FACILITY=%i\n"
506 "SYSLOG_IDENTIFIER=%s\n",
509 isempty(file
) ? "" : "CODE_FILE=",
510 isempty(file
) ? "" : file
,
511 isempty(file
) ? "" : "\n",
512 line
? "CODE_LINE=" : "",
513 line
? 1 : 0, line
, /* %.0d means no output too, special case for 0 */
515 isempty(func
) ? "" : "CODE_FUNC=",
516 isempty(func
) ? "" : func
,
517 isempty(func
) ? "" : "\n",
518 error
? "ERRNO=" : "",
519 error
? 1 : 0, error
,
521 isempty(object
) ? "" : object_field
,
522 isempty(object
) ? "" : object
,
523 isempty(object
) ? "" : "\n",
524 isempty(extra
) ? "" : extra_field
,
525 isempty(extra
) ? "" : extra
,
526 isempty(extra
) ? "" : "\n",
527 program_invocation_short_name
);
532 static int write_to_journal(
538 const char *object_field
,
540 const char *extra_field
,
542 const char *buffer
) {
544 char header
[LINE_MAX
];
545 struct iovec iovec
[4] = {};
546 struct msghdr mh
= {};
551 log_do_header(header
, sizeof(header
), level
, error
, file
, line
, func
, object_field
, object
, extra_field
, extra
);
553 iovec
[0] = IOVEC_MAKE_STRING(header
);
554 iovec
[1] = IOVEC_MAKE_STRING("MESSAGE=");
555 iovec
[2] = IOVEC_MAKE_STRING(buffer
);
556 iovec
[3] = IOVEC_MAKE_STRING("\n");
559 mh
.msg_iovlen
= ELEMENTSOF(iovec
);
561 if (sendmsg(journal_fd
, &mh
, MSG_NOSIGNAL
) < 0)
567 int log_dispatch_internal(
573 const char *object_field
,
576 const char *extra_field
,
584 if (log_target
== LOG_TARGET_NULL
)
587 /* Patch in LOG_DAEMON facility if necessary */
588 if ((level
& LOG_FACMASK
) == 0)
589 level
= log_facility
| LOG_PRI(level
);
591 if (open_when_needed
)
598 buffer
+= strspn(buffer
, NEWLINE
);
603 if ((e
= strpbrk(buffer
, NEWLINE
)))
606 if (IN_SET(log_target
, LOG_TARGET_AUTO
,
607 LOG_TARGET_JOURNAL_OR_KMSG
,
608 LOG_TARGET_JOURNAL
)) {
610 k
= write_to_journal(level
, error
, file
, line
, func
, object_field
, object
, extra_field
, extra
, buffer
);
618 if (IN_SET(log_target
, LOG_TARGET_SYSLOG_OR_KMSG
,
619 LOG_TARGET_SYSLOG
)) {
621 k
= write_to_syslog(level
, error
, file
, line
, func
, buffer
);
630 IN_SET(log_target
, LOG_TARGET_AUTO
,
632 LOG_TARGET_SYSLOG_OR_KMSG
,
633 LOG_TARGET_JOURNAL_OR_KMSG
,
636 k
= write_to_kmsg(level
, error
, file
, line
, func
, buffer
);
644 (void) write_to_console(level
, error
, file
, line
, func
, buffer
);
649 if (open_when_needed
)
655 int log_dump_internal(
663 LogRealm realm
= LOG_REALM_REMOVE_LEVEL(level
);
666 /* This modifies the buffer... */
671 if (_likely_(LOG_PRI(level
) > log_max_level
[realm
]))
674 return log_dispatch_internal(level
, error
, file
, line
, func
, NULL
, NULL
, NULL
, NULL
, buffer
);
677 int log_internalv_realm(
686 LogRealm realm
= LOG_REALM_REMOVE_LEVEL(level
);
687 char buffer
[LINE_MAX
];
693 if (_likely_(LOG_PRI(level
) > log_max_level
[realm
]))
696 /* Make sure that %m maps to the specified error */
700 vsnprintf(buffer
, sizeof(buffer
), format
, ap
);
702 return log_dispatch_internal(level
, error
, file
, line
, func
, NULL
, NULL
, NULL
, NULL
, buffer
);
705 int log_internal_realm(
711 const char *format
, ...) {
716 va_start(ap
, format
);
717 r
= log_internalv_realm(level
, error
, file
, line
, func
, format
, ap
);
723 int log_object_internalv(
729 const char *object_field
,
731 const char *extra_field
,
742 if (_likely_(LOG_PRI(level
) > log_max_level
[LOG_REALM_SYSTEMD
]))
745 /* Make sure that %m maps to the specified error */
749 /* Prepend the object name before the message */
754 buffer
= newa(char, n
+ 2 + LINE_MAX
);
755 b
= stpcpy(stpcpy(buffer
, object
), ": ");
757 b
= buffer
= newa(char, LINE_MAX
);
759 vsnprintf(b
, LINE_MAX
, format
, ap
);
761 return log_dispatch_internal(level
, error
, file
, line
, func
,
762 object_field
, object
, extra_field
, extra
, buffer
);
765 int log_object_internal(
771 const char *object_field
,
773 const char *extra_field
,
775 const char *format
, ...) {
780 va_start(ap
, format
);
781 r
= log_object_internalv(level
, error
, file
, line
, func
, object_field
, object
, extra_field
, extra
, format
, ap
);
787 static void log_assert(
793 const char *format
) {
795 static char buffer
[LINE_MAX
];
796 LogRealm realm
= LOG_REALM_REMOVE_LEVEL(level
);
798 if (_likely_(LOG_PRI(level
) > log_max_level
[realm
]))
801 DISABLE_WARNING_FORMAT_NONLITERAL
;
802 xsprintf(buffer
, format
, text
, file
, line
, func
);
805 log_abort_msg
= buffer
;
807 log_dispatch_internal(level
, 0, file
, line
, func
, NULL
, NULL
, NULL
, NULL
, buffer
);
810 noreturn
void log_assert_failed_realm(
817 log_assert(LOG_REALM_PLUS_LEVEL(realm
, LOG_CRIT
), text
, file
, line
, func
,
818 "Assertion '%s' failed at %s:%u, function %s(). Aborting.");
822 noreturn
void log_assert_failed_unreachable_realm(
829 log_assert(LOG_REALM_PLUS_LEVEL(realm
, LOG_CRIT
), text
, file
, line
, func
,
830 "Code should not be reached '%s' at %s:%u, function %s(). Aborting.");
834 void log_assert_failed_return_realm(
841 log_assert(LOG_REALM_PLUS_LEVEL(realm
, LOG_DEBUG
), text
, file
, line
, func
,
842 "Assertion '%s' failed at %s:%u, function %s(). Ignoring.");
845 int log_oom_internal(LogRealm realm
, const char *file
, int line
, const char *func
) {
846 return log_internal_realm(LOG_REALM_PLUS_LEVEL(realm
, LOG_ERR
),
847 ENOMEM
, file
, line
, func
, "Out of memory.");
850 int log_format_iovec(
854 bool newline_separator
,
859 static const char nl
= '\n';
861 while (format
&& *n
+ 1 < iovec_len
) {
866 /* We need to copy the va_list structure,
867 * since vasprintf() leaves it afterwards at
868 * an undefined location */
874 r
= vasprintf(&m
, format
, aq
);
879 /* Now, jump enough ahead, so that we point to
880 * the next format string */
881 VA_FORMAT_ADVANCE(format
, ap
);
883 iovec
[(*n
)++] = IOVEC_MAKE_STRING(m
);
885 if (newline_separator
) {
886 iovec
[*n
].iov_base
= (char*) &nl
;
887 iovec
[*n
].iov_len
= 1;
891 format
= va_arg(ap
, char *);
896 int log_struct_internal(
902 const char *format
, ...) {
904 LogRealm realm
= LOG_REALM_REMOVE_LEVEL(level
);
913 if (_likely_(LOG_PRI(level
) > log_max_level
[realm
]))
916 if (log_target
== LOG_TARGET_NULL
)
919 if ((level
& LOG_FACMASK
) == 0)
920 level
= log_facility
| LOG_PRI(level
);
922 if (IN_SET(log_target
,
924 LOG_TARGET_JOURNAL_OR_KMSG
,
925 LOG_TARGET_JOURNAL
)) {
927 if (open_when_needed
)
930 if (journal_fd
>= 0) {
931 char header
[LINE_MAX
];
932 struct iovec iovec
[17] = {};
938 bool fallback
= false;
940 /* If the journal is available do structured logging */
941 log_do_header(header
, sizeof(header
), level
, error
, file
, line
, func
, NULL
, NULL
, NULL
, NULL
);
942 iovec
[n
++] = IOVEC_MAKE_STRING(header
);
944 va_start(ap
, format
);
945 r
= log_format_iovec(iovec
, ELEMENTSOF(iovec
), &n
, true, error
, format
, ap
);
950 (void) sendmsg(journal_fd
, &mh
, MSG_NOSIGNAL
);
954 for (i
= 1; i
< n
; i
+= 2)
955 free(iovec
[i
].iov_base
);
958 if (open_when_needed
)
966 /* Fallback if journal logging is not available or didn't work. */
968 va_start(ap
, format
);
976 vsnprintf(buf
, sizeof(buf
), format
, aq
);
979 if (startswith(buf
, "MESSAGE=")) {
984 VA_FORMAT_ADVANCE(format
, ap
);
986 format
= va_arg(ap
, char *);
991 if (open_when_needed
)
997 return log_dispatch_internal(level
, error
, file
, line
, func
, NULL
, NULL
, NULL
, NULL
, buf
+ 8);
1000 int log_struct_iovec_internal(
1006 const struct iovec input_iovec
[],
1007 size_t n_input_iovec
) {
1009 LogRealm realm
= LOG_REALM_REMOVE_LEVEL(level
);
1017 if (_likely_(LOG_PRI(level
) > log_max_level
[realm
]))
1020 if (log_target
== LOG_TARGET_NULL
)
1023 if ((level
& LOG_FACMASK
) == 0)
1024 level
= log_facility
| LOG_PRI(level
);
1026 if (IN_SET(log_target
, LOG_TARGET_AUTO
,
1027 LOG_TARGET_JOURNAL_OR_KMSG
,
1028 LOG_TARGET_JOURNAL
) &&
1031 struct iovec iovec
[1 + n_input_iovec
*2];
1032 char header
[LINE_MAX
];
1033 struct msghdr mh
= {
1035 .msg_iovlen
= 1 + n_input_iovec
*2,
1038 log_do_header(header
, sizeof(header
), level
, error
, file
, line
, func
, NULL
, NULL
, NULL
, NULL
);
1039 iovec
[0] = IOVEC_MAKE_STRING(header
);
1041 for (i
= 0; i
< n_input_iovec
; i
++) {
1042 iovec
[1+i
*2] = input_iovec
[i
];
1043 iovec
[1+i
*2+1] = IOVEC_MAKE_STRING("\n");
1046 if (sendmsg(journal_fd
, &mh
, MSG_NOSIGNAL
) >= 0)
1050 for (i
= 0; i
< n_input_iovec
; i
++) {
1051 if (input_iovec
[i
].iov_len
< STRLEN("MESSAGE="))
1054 if (memcmp(input_iovec
[i
].iov_base
, "MESSAGE=", STRLEN("MESSAGE=")) == 0)
1058 if (_unlikely_(i
>= n_input_iovec
)) /* Couldn't find MESSAGE=? */
1061 m
= strndupa(input_iovec
[i
].iov_base
+ STRLEN("MESSAGE="),
1062 input_iovec
[i
].iov_len
- STRLEN("MESSAGE="));
1064 return log_dispatch_internal(level
, error
, file
, line
, func
, NULL
, NULL
, NULL
, NULL
, m
);
1067 int log_set_target_from_string(const char *e
) {
1070 t
= log_target_from_string(e
);
1078 int log_set_max_level_from_string_realm(LogRealm realm
, const char *e
) {
1081 t
= log_level_from_string(e
);
1085 log_set_max_level_realm(realm
, t
);
1089 static int parse_proc_cmdline_item(const char *key
, const char *value
, void *data
) {
1092 * The systemd.log_xyz= settings are parsed by all tools, and
1095 * However, "quiet" is only parsed by PID 1, and only turns of
1096 * status output to /dev/console, but does not alter the log
1100 if (streq(key
, "debug") && !value
)
1101 log_set_max_level(LOG_DEBUG
);
1103 else if (proc_cmdline_key_streq(key
, "systemd.log_target")) {
1105 if (proc_cmdline_value_missing(key
, value
))
1108 if (log_set_target_from_string(value
) < 0)
1109 log_warning("Failed to parse log target '%s'. Ignoring.", value
);
1111 } else if (proc_cmdline_key_streq(key
, "systemd.log_level")) {
1113 if (proc_cmdline_value_missing(key
, value
))
1116 if (log_set_max_level_from_string(value
) < 0)
1117 log_warning("Failed to parse log level '%s'. Ignoring.", value
);
1119 } else if (proc_cmdline_key_streq(key
, "systemd.log_color")) {
1121 if (log_show_color_from_string(value
?: "1") < 0)
1122 log_warning("Failed to parse log color setting '%s'. Ignoring.", value
);
1124 } else if (proc_cmdline_key_streq(key
, "systemd.log_location")) {
1126 if (log_show_location_from_string(value
?: "1") < 0)
1127 log_warning("Failed to parse log location setting '%s'. Ignoring.", value
);
1133 void log_parse_environment_realm(LogRealm realm
) {
1134 /* Do not call from library code. */
1138 if (get_ctty_devnr(0, NULL
) < 0)
1139 /* Only try to read the command line in daemons. We assume that anything that has a controlling tty is
1141 (void) proc_cmdline_parse(parse_proc_cmdline_item
, NULL
, PROC_CMDLINE_STRIP_RD_PREFIX
);
1143 e
= getenv("SYSTEMD_LOG_TARGET");
1144 if (e
&& log_set_target_from_string(e
) < 0)
1145 log_warning("Failed to parse log target '%s'. Ignoring.", e
);
1147 e
= getenv("SYSTEMD_LOG_LEVEL");
1148 if (e
&& log_set_max_level_from_string_realm(realm
, e
) < 0)
1149 log_warning("Failed to parse log level '%s'. Ignoring.", e
);
1151 e
= getenv("SYSTEMD_LOG_COLOR");
1152 if (e
&& log_show_color_from_string(e
) < 0)
1153 log_warning("Failed to parse bool '%s'. Ignoring.", e
);
1155 e
= getenv("SYSTEMD_LOG_LOCATION");
1156 if (e
&& log_show_location_from_string(e
) < 0)
1157 log_warning("Failed to parse bool '%s'. Ignoring.", e
);
1160 LogTarget
log_get_target(void) {
1164 int log_get_max_level_realm(LogRealm realm
) {
1165 return log_max_level
[realm
];
1168 void log_show_color(bool b
) {
1172 bool log_get_show_color(void) {
1176 void log_show_location(bool b
) {
1180 bool log_get_show_location(void) {
1181 return show_location
;
1184 int log_show_color_from_string(const char *e
) {
1187 t
= parse_boolean(e
);
1195 int log_show_location_from_string(const char *e
) {
1198 t
= parse_boolean(e
);
1202 log_show_location(t
);
1206 bool log_on_console(void) {
1207 if (IN_SET(log_target
, LOG_TARGET_CONSOLE
,
1208 LOG_TARGET_CONSOLE_PREFIXED
))
1211 return syslog_fd
< 0 && kmsg_fd
< 0 && journal_fd
< 0;
1214 static const char *const log_target_table
[_LOG_TARGET_MAX
] = {
1215 [LOG_TARGET_CONSOLE
] = "console",
1216 [LOG_TARGET_CONSOLE_PREFIXED
] = "console-prefixed",
1217 [LOG_TARGET_KMSG
] = "kmsg",
1218 [LOG_TARGET_JOURNAL
] = "journal",
1219 [LOG_TARGET_JOURNAL_OR_KMSG
] = "journal-or-kmsg",
1220 [LOG_TARGET_SYSLOG
] = "syslog",
1221 [LOG_TARGET_SYSLOG_OR_KMSG
] = "syslog-or-kmsg",
1222 [LOG_TARGET_AUTO
] = "auto",
1223 [LOG_TARGET_SAFE
] = "safe",
1224 [LOG_TARGET_NULL
] = "null"
1227 DEFINE_STRING_TABLE_LOOKUP(log_target
, LogTarget
);
1229 void log_received_signal(int level
, const struct signalfd_siginfo
*si
) {
1232 if (pid_is_valid(si
->ssi_pid
)) {
1233 _cleanup_free_
char *p
= NULL
;
1235 (void) get_process_comm(si
->ssi_pid
, &p
);
1238 "Received SIG%s from PID %"PRIu32
" (%s).",
1239 signal_to_string(si
->ssi_signo
),
1240 si
->ssi_pid
, strna(p
));
1244 signal_to_string(si
->ssi_signo
));
1247 int log_syntax_internal(
1250 const char *config_file
,
1251 unsigned config_line
,
1256 const char *format
, ...) {
1259 char buffer
[LINE_MAX
];
1261 const char *unit_fmt
= NULL
;
1266 if (_likely_(LOG_PRI(level
) > log_max_level
[LOG_REALM_SYSTEMD
]))
1269 if (log_target
== LOG_TARGET_NULL
)
1275 va_start(ap
, format
);
1276 vsnprintf(buffer
, sizeof(buffer
), format
, ap
);
1280 unit_fmt
= getpid_cached() == 1 ? "UNIT=%s" : "USER_UNIT=%s";
1282 return log_struct_internal(
1283 LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD
, level
),
1286 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR
,
1287 "CONFIG_FILE=%s", config_file
,
1288 "CONFIG_LINE=%u", config_line
,
1289 LOG_MESSAGE("%s:%u: %s", config_file
, config_line
, buffer
),
1294 int log_syntax_invalid_utf8_internal(
1297 const char *config_file
,
1298 unsigned config_line
,
1302 const char *rvalue
) {
1304 _cleanup_free_
char *p
= NULL
;
1307 p
= utf8_escape_invalid(rvalue
);
1309 log_syntax_internal(unit
, level
, config_file
, config_line
, 0, file
, line
, func
,
1310 "String is not UTF-8 clean, ignoring assignment: %s", strna(p
));
1315 void log_set_upgrade_syslog_to_journal(bool b
) {
1316 upgrade_syslog_to_journal
= b
;
1319 void log_set_always_reopen_console(bool b
) {
1320 always_reopen_console
= b
;
1323 void log_set_open_when_needed(bool b
) {
1324 open_when_needed
= b
;
1327 int log_emergency_level(void) {
1328 /* Returns the log level to use for log_emergency() logging. We use LOG_EMERG only when we are PID 1, as only
1329 * then the system of the whole system is obviously affected. */
1331 return getpid_cached() == 1 ? LOG_EMERG
: LOG_ERR
;