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 #if 0 /// UNNEEDED by elogind
78 static bool upgrade_syslog_to_journal = false;
80 static bool always_reopen_console = false;
81 static bool open_when_needed = false;
82 static bool prohibit_ipc = false;
84 /* Akin to glibc's __abort_msg; which is private and we hence cannot
86 static char *log_abort_msg = NULL;
88 void log_close_console(void) {
93 if (getpid_cached() == 1) {
95 safe_close(console_fd);
101 static int log_open_console(void) {
106 if (always_reopen_console) {
107 console_fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
111 console_fd = STDERR_FILENO;
116 void log_close_kmsg(void) {
117 kmsg_fd = safe_close(kmsg_fd);
120 static int log_open_kmsg(void) {
125 kmsg_fd = open("/dev/kmsg", O_WRONLY|O_NOCTTY|O_CLOEXEC);
132 void log_close_syslog(void) {
133 syslog_fd = safe_close(syslog_fd);
136 static int create_log_socket(int type) {
140 fd = socket(AF_UNIX, type|SOCK_CLOEXEC, 0);
144 (void) fd_inc_sndbuf(fd, SNDBUF_SIZE);
146 /* We need a blocking fd here since we'd otherwise lose
147 messages way too early. However, let's not hang forever in the
148 unlikely case of a deadlock. */
149 if (getpid_cached() == 1)
150 timeval_store(&tv, 10 * USEC_PER_MSEC);
152 timeval_store(&tv, 10 * USEC_PER_SEC);
153 (void) setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
158 static int log_open_syslog(void) {
160 static const union sockaddr_union sa = {
161 .un.sun_family = AF_UNIX,
162 .un.sun_path = "/dev/log",
170 syslog_fd = create_log_socket(SOCK_DGRAM);
176 if (connect(syslog_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
177 safe_close(syslog_fd);
179 /* Some legacy syslog systems still use stream
180 * sockets. They really shouldn't. But what can we
182 syslog_fd = create_log_socket(SOCK_STREAM);
188 if (connect(syslog_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
193 syslog_is_stream = true;
195 syslog_is_stream = false;
204 void log_close_journal(void) {
205 #if 0 /// elogind does not support journald
206 journal_fd = safe_close(journal_fd);
210 #if 0 /// UNNEEDED by elogind
211 static int log_open_journal(void) {
213 static const union sockaddr_union sa = {
214 .un.sun_family = AF_UNIX,
215 .un.sun_path = "/run/systemd/journal/socket",
223 journal_fd = create_log_socket(SOCK_DGRAM);
224 if (journal_fd < 0) {
229 if (connect(journal_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
245 /* Do not call from library code. */
247 /* If we don't use the console we close it here, to not get
248 * killed by SAK. If we don't use syslog we close it here so
249 * that we are not confused by somebody deleting the socket in
250 * the fs. If we don't use /dev/kmsg we still keep it open,
251 * because there is no reason to close it. */
253 if (log_target == LOG_TARGET_NULL) {
260 if (!IN_SET(log_target, LOG_TARGET_AUTO, LOG_TARGET_SAFE) ||
261 getpid_cached() == 1 ||
262 isatty(STDERR_FILENO) <= 0) {
264 #if 0 /// elogind does not support logging to systemd-journald
266 IN_SET(log_target, LOG_TARGET_AUTO,
267 LOG_TARGET_JOURNAL_OR_KMSG,
268 LOG_TARGET_JOURNAL)) {
269 r = log_open_journal();
279 IN_SET(log_target, LOG_TARGET_SYSLOG_OR_KMSG,
280 LOG_TARGET_SYSLOG)) {
281 r = log_open_syslog();
289 if (IN_SET(log_target, LOG_TARGET_AUTO,
291 LOG_TARGET_JOURNAL_OR_KMSG,
292 LOG_TARGET_SYSLOG_OR_KMSG,
307 return log_open_console();
310 void log_set_target(LogTarget target) {
312 assert(target < _LOG_TARGET_MAX);
314 #if 0 /// elogind does not support logging to systemd-journald
315 if (upgrade_syslog_to_journal) {
316 if (target == LOG_TARGET_SYSLOG)
317 target = LOG_TARGET_JOURNAL;
318 else if (target == LOG_TARGET_SYSLOG_OR_KMSG)
319 target = LOG_TARGET_JOURNAL_OR_KMSG;
326 void log_close(void) {
327 /* Do not call from library code. */
335 #if 0 /// UNNEEDED by elogind
336 void log_forget_fds(void) {
337 /* Do not call from library code. */
339 console_fd = kmsg_fd = syslog_fd = journal_fd = -1;
343 void log_set_max_level_realm(LogRealm realm, int level) {
344 assert((level & LOG_PRIMASK) == level);
345 assert(realm < ELEMENTSOF(log_max_level));
347 log_max_level[realm] = level;
350 void log_set_facility(int facility) {
351 log_facility = facility;
354 static int write_to_console(
360 const char *buffer) {
362 char location[256], prefix[1 + DECIMAL_STR_MAX(int) + 2];
363 struct iovec iovec[6] = {};
370 if (log_target == LOG_TARGET_CONSOLE_PREFIXED) {
371 xsprintf(prefix, "<%i>", level);
372 iovec[n++] = IOVEC_MAKE_STRING(prefix);
375 highlight = LOG_PRI(level) <= LOG_ERR && show_color;
378 xsprintf(location, "(%s:%i) ", file, line);
379 iovec[n++] = IOVEC_MAKE_STRING(location);
383 iovec[n++] = IOVEC_MAKE_STRING(ANSI_HIGHLIGHT_RED);
384 iovec[n++] = IOVEC_MAKE_STRING(buffer);
386 iovec[n++] = IOVEC_MAKE_STRING(ANSI_NORMAL);
387 iovec[n++] = IOVEC_MAKE_STRING("\n");
389 if (writev(console_fd, iovec, n) < 0) {
391 if (errno == EIO && getpid_cached() == 1) {
393 /* If somebody tried to kick us from our
394 * console tty (via vhangup() or suchlike),
395 * try to reconnect */
403 if (writev(console_fd, iovec, n) < 0)
412 static int write_to_syslog(
418 const char *buffer) {
420 char header_priority[2 + DECIMAL_STR_MAX(int) + 1],
422 header_pid[4 + DECIMAL_STR_MAX(pid_t) + 1];
423 struct iovec iovec[5] = {};
424 struct msghdr msghdr = {
426 .msg_iovlen = ELEMENTSOF(iovec),
434 xsprintf(header_priority, "<%i>", level);
436 t = (time_t) (now(CLOCK_REALTIME) / USEC_PER_SEC);
441 if (strftime(header_time, sizeof(header_time), "%h %e %T ", tm) <= 0)
444 xsprintf(header_pid, "["PID_FMT"]: ", getpid_cached());
446 iovec[0] = IOVEC_MAKE_STRING(header_priority);
447 iovec[1] = IOVEC_MAKE_STRING(header_time);
448 iovec[2] = IOVEC_MAKE_STRING(program_invocation_short_name);
449 iovec[3] = IOVEC_MAKE_STRING(header_pid);
450 iovec[4] = IOVEC_MAKE_STRING(buffer);
452 /* When using syslog via SOCK_STREAM separate the messages by NUL chars */
453 if (syslog_is_stream)
459 n = sendmsg(syslog_fd, &msghdr, MSG_NOSIGNAL);
463 if (!syslog_is_stream ||
464 (size_t) n >= IOVEC_TOTAL_SIZE(iovec, ELEMENTSOF(iovec)))
467 IOVEC_INCREMENT(iovec, ELEMENTSOF(iovec), n);
473 static int write_to_kmsg(
479 const char *buffer) {
481 char header_priority[2 + DECIMAL_STR_MAX(int) + 1],
482 header_pid[4 + DECIMAL_STR_MAX(pid_t) + 1];
483 struct iovec iovec[5] = {};
488 xsprintf(header_priority, "<%i>", level);
489 xsprintf(header_pid, "["PID_FMT"]: ", getpid_cached());
491 iovec[0] = IOVEC_MAKE_STRING(header_priority);
492 iovec[1] = IOVEC_MAKE_STRING(program_invocation_short_name);
493 iovec[2] = IOVEC_MAKE_STRING(header_pid);
494 iovec[3] = IOVEC_MAKE_STRING(buffer);
495 iovec[4] = IOVEC_MAKE_STRING("\n");
497 if (writev(kmsg_fd, iovec, ELEMENTSOF(iovec)) < 0)
503 static int log_do_header(
508 const char *file, int line, const char *func,
509 const char *object_field, const char *object,
510 const char *extra_field, const char *extra) {
512 snprintf(header, size,
514 "SYSLOG_FACILITY=%i\n"
521 "SYSLOG_IDENTIFIER=%s\n",
524 isempty(file) ? "" : "CODE_FILE=",
525 isempty(file) ? "" : file,
526 isempty(file) ? "" : "\n",
527 line ? "CODE_LINE=" : "",
528 line ? 1 : 0, line, /* %.0d means no output too, special case for 0 */
530 isempty(func) ? "" : "CODE_FUNC=",
531 isempty(func) ? "" : func,
532 isempty(func) ? "" : "\n",
533 error ? "ERRNO=" : "",
534 error ? 1 : 0, error,
536 isempty(object) ? "" : object_field,
537 isempty(object) ? "" : object,
538 isempty(object) ? "" : "\n",
539 isempty(extra) ? "" : extra_field,
540 isempty(extra) ? "" : extra,
541 isempty(extra) ? "" : "\n",
542 program_invocation_short_name);
547 #if 0 /// UNNEEDED by elogind
548 static int write_to_journal(
554 const char *object_field,
556 const char *extra_field,
558 const char *buffer) {
560 char header[LINE_MAX];
561 struct iovec iovec[4] = {};
562 struct msghdr mh = {};
567 log_do_header(header, sizeof(header), level, error, file, line, func, object_field, object, extra_field, extra);
569 iovec[0] = IOVEC_MAKE_STRING(header);
570 iovec[1] = IOVEC_MAKE_STRING("MESSAGE=");
571 iovec[2] = IOVEC_MAKE_STRING(buffer);
572 iovec[3] = IOVEC_MAKE_STRING("\n");
575 mh.msg_iovlen = ELEMENTSOF(iovec);
577 if (sendmsg(journal_fd, &mh, MSG_NOSIGNAL) < 0)
584 int log_dispatch_internal(
590 const char *object_field,
593 const char *extra_field,
601 if (log_target == LOG_TARGET_NULL)
604 /* Patch in LOG_DAEMON facility if necessary */
605 if ((level & LOG_FACMASK) == 0)
606 level = log_facility | LOG_PRI(level);
608 if (open_when_needed)
615 buffer += strspn(buffer, NEWLINE);
620 if ((e = strpbrk(buffer, NEWLINE)))
623 #if 0 /// elogind does not support logging to systemd-journald
624 if (IN_SET(log_target, LOG_TARGET_AUTO,
625 LOG_TARGET_JOURNAL_OR_KMSG,
626 LOG_TARGET_JOURNAL)) {
628 k = write_to_journal(level, error, file, line, func, object_field, object, extra_field, extra, buffer);
637 if (IN_SET(log_target, LOG_TARGET_SYSLOG_OR_KMSG,
638 LOG_TARGET_SYSLOG)) {
640 k = write_to_syslog(level, error, file, line, func, buffer);
649 IN_SET(log_target, LOG_TARGET_AUTO,
651 LOG_TARGET_SYSLOG_OR_KMSG,
652 LOG_TARGET_JOURNAL_OR_KMSG,
655 k = write_to_kmsg(level, error, file, line, func, buffer);
663 (void) write_to_console(level, error, file, line, func, buffer);
668 if (open_when_needed)
674 int log_dump_internal(
682 LogRealm realm = LOG_REALM_REMOVE_LEVEL(level);
685 /* This modifies the buffer... */
690 if (_likely_(LOG_PRI(level) > log_max_level[realm]))
693 return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buffer);
696 int log_internalv_realm(
705 LogRealm realm = LOG_REALM_REMOVE_LEVEL(level);
706 char buffer[LINE_MAX];
712 if (_likely_(LOG_PRI(level) > log_max_level[realm]))
715 /* Make sure that %m maps to the specified error */
719 vsnprintf(buffer, sizeof(buffer), format, ap);
721 return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buffer);
724 int log_internal_realm(
730 const char *format, ...) {
735 va_start(ap, format);
736 r = log_internalv_realm(level, error, file, line, func, format, ap);
742 int log_object_internalv(
748 const char *object_field,
750 const char *extra_field,
761 if (_likely_(LOG_PRI(level) > log_max_level[LOG_REALM_SYSTEMD]))
764 /* Make sure that %m maps to the specified error */
768 /* Prepend the object name before the message */
773 buffer = newa(char, n + 2 + LINE_MAX);
774 b = stpcpy(stpcpy(buffer, object), ": ");
776 b = buffer = newa(char, LINE_MAX);
778 vsnprintf(b, LINE_MAX, format, ap);
780 return log_dispatch_internal(level, error, file, line, func,
781 object_field, object, extra_field, extra, buffer);
784 int log_object_internal(
790 const char *object_field,
792 const char *extra_field,
794 const char *format, ...) {
799 va_start(ap, format);
800 r = log_object_internalv(level, error, file, line, func, object_field, object, extra_field, extra, format, ap);
806 static void log_assert(
812 const char *format) {
814 static char buffer[LINE_MAX];
815 LogRealm realm = LOG_REALM_REMOVE_LEVEL(level);
817 if (_likely_(LOG_PRI(level) > log_max_level[realm]))
820 DISABLE_WARNING_FORMAT_NONLITERAL;
821 xsprintf(buffer, format, text, file, line, func);
824 log_abort_msg = buffer;
826 log_dispatch_internal(level, 0, file, line, func, NULL, NULL, NULL, NULL, buffer);
829 noreturn void log_assert_failed_realm(
836 log_assert(LOG_REALM_PLUS_LEVEL(realm, LOG_CRIT), text, file, line, func,
837 "Assertion '%s' failed at %s:%u, function %s(). Aborting.");
841 noreturn void log_assert_failed_unreachable_realm(
848 log_assert(LOG_REALM_PLUS_LEVEL(realm, LOG_CRIT), text, file, line, func,
849 "Code should not be reached '%s' at %s:%u, function %s(). Aborting.");
853 void log_assert_failed_return_realm(
860 log_assert(LOG_REALM_PLUS_LEVEL(realm, LOG_DEBUG), text, file, line, func,
861 "Assertion '%s' failed at %s:%u, function %s(). Ignoring.");
864 int log_oom_internal(LogRealm realm, const char *file, int line, const char *func) {
865 return log_internal_realm(LOG_REALM_PLUS_LEVEL(realm, LOG_ERR),
866 ENOMEM, file, line, func, "Out of memory.");
869 int log_format_iovec(
873 bool newline_separator,
878 static const char nl = '\n';
880 while (format && *n + 1 < iovec_len) {
885 /* We need to copy the va_list structure,
886 * since vasprintf() leaves it afterwards at
887 * an undefined location */
893 r = vasprintf(&m, format, aq);
898 /* Now, jump enough ahead, so that we point to
899 * the next format string */
900 VA_FORMAT_ADVANCE(format, ap);
902 iovec[(*n)++] = IOVEC_MAKE_STRING(m);
904 if (newline_separator) {
905 iovec[*n].iov_base = (char*) &nl;
906 iovec[*n].iov_len = 1;
910 format = va_arg(ap, char *);
915 int log_struct_internal(
921 const char *format, ...) {
923 LogRealm realm = LOG_REALM_REMOVE_LEVEL(level);
932 if (_likely_(LOG_PRI(level) > log_max_level[realm]))
935 if (log_target == LOG_TARGET_NULL)
938 if ((level & LOG_FACMASK) == 0)
939 level = log_facility | LOG_PRI(level);
941 #if 0 /// elogind does not support logging to systemd-journald
942 if (IN_SET(log_target,
944 LOG_TARGET_JOURNAL_OR_KMSG,
945 LOG_TARGET_JOURNAL)) {
947 if (open_when_needed)
950 if (journal_fd >= 0) {
951 char header[LINE_MAX];
952 struct iovec iovec[17] = {};
958 bool fallback = false;
960 /* If the journal is available do structured logging */
961 log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL, NULL, NULL);
962 iovec[n++] = IOVEC_MAKE_STRING(header);
964 va_start(ap, format);
965 r = log_format_iovec(iovec, ELEMENTSOF(iovec), &n, true, error, format, ap);
970 (void) sendmsg(journal_fd, &mh, MSG_NOSIGNAL);
974 for (i = 1; i < n; i += 2)
975 free(iovec[i].iov_base);
978 if (open_when_needed)
987 /* Fallback if journal logging is not available or didn't work. */
989 va_start(ap, format);
997 vsnprintf(buf, sizeof(buf), format, aq);
1000 if (startswith(buf, "MESSAGE=")) {
1005 VA_FORMAT_ADVANCE(format, ap);
1007 format = va_arg(ap, char *);
1012 if (open_when_needed)
1018 return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buf + 8);
1021 int log_struct_iovec_internal(
1027 const struct iovec input_iovec[],
1028 size_t n_input_iovec) {
1030 LogRealm realm = LOG_REALM_REMOVE_LEVEL(level);
1038 if (_likely_(LOG_PRI(level) > log_max_level[realm]))
1041 if (log_target == LOG_TARGET_NULL)
1044 if ((level & LOG_FACMASK) == 0)
1045 level = log_facility | LOG_PRI(level);
1047 if (IN_SET(log_target, LOG_TARGET_AUTO,
1048 LOG_TARGET_JOURNAL_OR_KMSG,
1049 LOG_TARGET_JOURNAL) &&
1052 struct iovec iovec[1 + n_input_iovec*2];
1053 char header[LINE_MAX];
1054 struct msghdr mh = {
1056 .msg_iovlen = 1 + n_input_iovec*2,
1059 log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL, NULL, NULL);
1060 iovec[0] = IOVEC_MAKE_STRING(header);
1062 for (i = 0; i < n_input_iovec; i++) {
1063 iovec[1+i*2] = input_iovec[i];
1064 iovec[1+i*2+1] = IOVEC_MAKE_STRING("\n");
1067 if (sendmsg(journal_fd, &mh, MSG_NOSIGNAL) >= 0)
1071 for (i = 0; i < n_input_iovec; i++) {
1072 if (input_iovec[i].iov_len < STRLEN("MESSAGE="))
1075 if (memcmp(input_iovec[i].iov_base, "MESSAGE=", STRLEN("MESSAGE=")) == 0)
1079 if (_unlikely_(i >= n_input_iovec)) /* Couldn't find MESSAGE=? */
1082 m = strndupa(input_iovec[i].iov_base + STRLEN("MESSAGE="),
1083 input_iovec[i].iov_len - STRLEN("MESSAGE="));
1085 return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, m);
1088 int log_set_target_from_string(const char *e) {
1091 t = log_target_from_string(e);
1099 int log_set_max_level_from_string_realm(LogRealm realm, const char *e) {
1102 t = log_level_from_string(e);
1106 log_set_max_level_realm(realm, t);
1110 static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
1113 * The systemd.log_xyz= settings are parsed by all tools, and
1116 * However, "quiet" is only parsed by PID 1, and only turns of
1117 * status output to /dev/console, but does not alter the log
1121 if (streq(key, "debug") && !value)
1122 log_set_max_level(LOG_DEBUG);
1124 else if (proc_cmdline_key_streq(key, "systemd.log_target")) {
1126 if (proc_cmdline_value_missing(key, value))
1129 if (log_set_target_from_string(value) < 0)
1130 log_warning("Failed to parse log target '%s'. Ignoring.", value);
1132 } else if (proc_cmdline_key_streq(key, "systemd.log_level")) {
1134 if (proc_cmdline_value_missing(key, value))
1137 if (log_set_max_level_from_string(value) < 0)
1138 log_warning("Failed to parse log level '%s'. Ignoring.", value);
1140 } else if (proc_cmdline_key_streq(key, "systemd.log_color")) {
1142 if (log_show_color_from_string(value ?: "1") < 0)
1143 log_warning("Failed to parse log color setting '%s'. Ignoring.", value);
1145 } else if (proc_cmdline_key_streq(key, "systemd.log_location")) {
1147 if (log_show_location_from_string(value ?: "1") < 0)
1148 log_warning("Failed to parse log location setting '%s'. Ignoring.", value);
1154 void log_parse_environment_realm(LogRealm realm) {
1155 /* Do not call from library code. */
1159 if (get_ctty_devnr(0, NULL) < 0)
1160 /* Only try to read the command line in daemons. We assume that anything that has a controlling tty is
1162 (void) proc_cmdline_parse(parse_proc_cmdline_item, NULL, PROC_CMDLINE_STRIP_RD_PREFIX);
1164 e = getenv("SYSTEMD_LOG_TARGET");
1165 if (e && log_set_target_from_string(e) < 0)
1166 log_warning("Failed to parse log target '%s'. Ignoring.", e);
1168 e = getenv("SYSTEMD_LOG_LEVEL");
1169 if (e && log_set_max_level_from_string_realm(realm, e) < 0)
1170 log_warning("Failed to parse log level '%s'. Ignoring.", e);
1172 e = getenv("SYSTEMD_LOG_COLOR");
1173 if (e && log_show_color_from_string(e) < 0)
1174 log_warning("Failed to parse bool '%s'. Ignoring.", e);
1176 e = getenv("SYSTEMD_LOG_LOCATION");
1177 if (e && log_show_location_from_string(e) < 0)
1178 log_warning("Failed to parse bool '%s'. Ignoring.", e);
1181 LogTarget log_get_target(void) {
1185 int log_get_max_level_realm(LogRealm realm) {
1186 return log_max_level[realm];
1189 void log_show_color(bool b) {
1193 bool log_get_show_color(void) {
1197 void log_show_location(bool b) {
1201 bool log_get_show_location(void) {
1202 return show_location;
1205 int log_show_color_from_string(const char *e) {
1208 t = parse_boolean(e);
1216 int log_show_location_from_string(const char *e) {
1219 t = parse_boolean(e);
1223 log_show_location(t);
1227 bool log_on_console(void) {
1228 if (IN_SET(log_target, LOG_TARGET_CONSOLE,
1229 LOG_TARGET_CONSOLE_PREFIXED))
1232 return syslog_fd < 0 && kmsg_fd < 0 && journal_fd < 0;
1235 static const char *const log_target_table[_LOG_TARGET_MAX] = {
1236 [LOG_TARGET_CONSOLE] = "console",
1237 [LOG_TARGET_CONSOLE_PREFIXED] = "console-prefixed",
1238 [LOG_TARGET_KMSG] = "kmsg",
1239 #if 0 /// elogind does not support logging to systemd-journald
1240 [LOG_TARGET_JOURNAL] = "journal",
1241 [LOG_TARGET_JOURNAL_OR_KMSG] = "journal-or-kmsg",
1243 [LOG_TARGET_SYSLOG] = "syslog",
1244 [LOG_TARGET_SYSLOG_OR_KMSG] = "syslog-or-kmsg",
1245 [LOG_TARGET_AUTO] = "auto",
1246 [LOG_TARGET_SAFE] = "safe",
1247 [LOG_TARGET_NULL] = "null"
1250 DEFINE_STRING_TABLE_LOOKUP(log_target, LogTarget);
1252 #if 0 /// UNNEEDED by elogind
1253 void log_received_signal(int level, const struct signalfd_siginfo *si) {
1256 if (pid_is_valid(si->ssi_pid)) {
1257 _cleanup_free_ char *p = NULL;
1259 (void) get_process_comm(si->ssi_pid, &p);
1262 "Received SIG%s from PID %"PRIu32" (%s).",
1263 signal_to_string(si->ssi_signo),
1264 si->ssi_pid, strna(p));
1268 signal_to_string(si->ssi_signo));
1272 int log_syntax_internal(
1275 const char *config_file,
1276 unsigned config_line,
1281 const char *format, ...) {
1284 char buffer[LINE_MAX];
1286 const char *unit_fmt = NULL;
1291 if (_likely_(LOG_PRI(level) > log_max_level[LOG_REALM_SYSTEMD]))
1294 if (log_target == LOG_TARGET_NULL)
1300 va_start(ap, format);
1301 vsnprintf(buffer, sizeof(buffer), format, ap);
1305 unit_fmt = getpid_cached() == 1 ? "UNIT=%s" : "USER_UNIT=%s";
1307 return log_struct_internal(
1308 LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, level),
1311 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
1312 "CONFIG_FILE=%s", config_file,
1313 "CONFIG_LINE=%u", config_line,
1314 LOG_MESSAGE("%s:%u: %s", config_file, config_line, buffer),
1319 int log_syntax_invalid_utf8_internal(
1322 const char *config_file,
1323 unsigned config_line,
1327 const char *rvalue) {
1329 _cleanup_free_ char *p = NULL;
1332 p = utf8_escape_invalid(rvalue);
1334 log_syntax_internal(unit, level, config_file, config_line, 0, file, line, func,
1335 "String is not UTF-8 clean, ignoring assignment: %s", strna(p));
1340 #if 0 /// UNNEEDED by elogind
1341 void log_set_upgrade_syslog_to_journal(bool b) {
1342 upgrade_syslog_to_journal = b;
1344 /* Make the change effective immediately */
1346 if (log_target == LOG_TARGET_SYSLOG)
1347 log_target = LOG_TARGET_JOURNAL;
1348 else if (log_target == LOG_TARGET_SYSLOG_OR_KMSG)
1349 log_target = LOG_TARGET_JOURNAL_OR_KMSG;
1353 void log_set_always_reopen_console(bool b) {
1354 always_reopen_console = b;
1358 void log_set_open_when_needed(bool b) {
1359 open_when_needed = b;
1362 void log_set_prohibit_ipc(bool b) {
1366 int log_emergency_level(void) {
1367 /* Returns the log level to use for log_emergency() logging. We use LOG_EMERG only when we are PID 1, as only
1368 * then the system of the whole system is obviously affected. */
1370 return getpid_cached() == 1 ? LOG_EMERG : LOG_ERR;