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 static void log_close_console(void) {
94 safe_close(console_fd);
99 static int log_open_console(void) {
101 if (!always_reopen_console) {
102 console_fd = STDERR_FILENO;
106 if (console_fd < 3) {
107 console_fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
111 console_fd = fd_move_above_stdio(console_fd);
117 static void log_close_kmsg(void) {
118 kmsg_fd = safe_close(kmsg_fd);
121 static int log_open_kmsg(void) {
126 kmsg_fd = open("/dev/kmsg", O_WRONLY|O_NOCTTY|O_CLOEXEC);
130 kmsg_fd = fd_move_above_stdio(kmsg_fd);
134 static void log_close_syslog(void) {
135 syslog_fd = safe_close(syslog_fd);
138 static int create_log_socket(int type) {
142 fd = socket(AF_UNIX, type|SOCK_CLOEXEC, 0);
146 fd = fd_move_above_stdio(fd);
147 (void) fd_inc_sndbuf(fd, SNDBUF_SIZE);
149 /* We need a blocking fd here since we'd otherwise lose messages way too early. However, let's not hang forever
150 * in the unlikely case of a deadlock. */
151 if (getpid_cached() == 1)
152 timeval_store(&tv, 10 * USEC_PER_MSEC);
154 timeval_store(&tv, 10 * USEC_PER_SEC);
155 (void) setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
160 static int log_open_syslog(void) {
162 static const union sockaddr_union sa = {
163 .un.sun_family = AF_UNIX,
164 .un.sun_path = "/dev/log",
172 syslog_fd = create_log_socket(SOCK_DGRAM);
178 if (connect(syslog_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
179 safe_close(syslog_fd);
181 /* Some legacy syslog systems still use stream
182 * sockets. They really shouldn't. But what can we
184 syslog_fd = create_log_socket(SOCK_STREAM);
190 if (connect(syslog_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
195 syslog_is_stream = true;
197 syslog_is_stream = false;
206 static void log_close_journal(void) {
207 #if 0 /// elogind does not support journald
208 journal_fd = safe_close(journal_fd);
212 #if 0 /// UNNEEDED by elogind
213 static int log_open_journal(void) {
215 static const union sockaddr_union sa = {
216 .un.sun_family = AF_UNIX,
217 .un.sun_path = "/run/systemd/journal/socket",
225 journal_fd = create_log_socket(SOCK_DGRAM);
226 if (journal_fd < 0) {
231 if (connect(journal_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
247 /* Do not call from library code. */
249 /* If we don't use the console we close it here, to not get
250 * killed by SAK. If we don't use syslog we close it here so
251 * that we are not confused by somebody deleting the socket in
252 * the fs, and to make sure we don't use it if prohibit_ipc is
253 * set. If we don't use /dev/kmsg we still keep it open,
254 * because there is no reason to close it. */
256 if (log_target == LOG_TARGET_NULL) {
263 if (log_target != LOG_TARGET_AUTO ||
264 getpid_cached() == 1 ||
265 isatty(STDERR_FILENO) <= 0) {
267 #if 0 /// elogind does not support logging to systemd-journald
269 IN_SET(log_target, LOG_TARGET_AUTO,
270 LOG_TARGET_JOURNAL_OR_KMSG,
271 LOG_TARGET_JOURNAL)) {
272 r = log_open_journal();
282 IN_SET(log_target, LOG_TARGET_SYSLOG_OR_KMSG,
283 LOG_TARGET_SYSLOG)) {
284 r = log_open_syslog();
292 if (IN_SET(log_target, LOG_TARGET_AUTO,
293 LOG_TARGET_JOURNAL_OR_KMSG,
294 LOG_TARGET_SYSLOG_OR_KMSG,
309 return log_open_console();
312 void log_set_target(LogTarget target) {
314 assert(target < _LOG_TARGET_MAX);
316 #if 0 /// elogind does not support logging to systemd-journald
317 if (upgrade_syslog_to_journal) {
318 if (target == LOG_TARGET_SYSLOG)
319 target = LOG_TARGET_JOURNAL;
320 else if (target == LOG_TARGET_SYSLOG_OR_KMSG)
321 target = LOG_TARGET_JOURNAL_OR_KMSG;
328 void log_close(void) {
329 /* Do not call from library code. */
337 #if 0 /// UNNEEDED by elogind
338 void log_forget_fds(void) {
339 /* Do not call from library code. */
341 console_fd = kmsg_fd = syslog_fd = journal_fd = -1;
345 void log_set_max_level_realm(LogRealm realm, int level) {
346 assert((level & LOG_PRIMASK) == level);
347 assert(realm < ELEMENTSOF(log_max_level));
349 log_max_level[realm] = level;
352 void log_set_facility(int facility) {
353 log_facility = facility;
356 static int write_to_console(
362 const char *buffer) {
364 char location[256], prefix[1 + DECIMAL_STR_MAX(int) + 2];
365 struct iovec iovec[6] = {};
372 if (log_target == LOG_TARGET_CONSOLE_PREFIXED) {
373 xsprintf(prefix, "<%i>", level);
374 iovec[n++] = IOVEC_MAKE_STRING(prefix);
377 highlight = LOG_PRI(level) <= LOG_ERR && show_color;
380 (void) snprintf(location, sizeof location, "(%s:%i) ", file, line);
381 iovec[n++] = IOVEC_MAKE_STRING(location);
385 iovec[n++] = IOVEC_MAKE_STRING(ANSI_HIGHLIGHT_RED);
386 iovec[n++] = IOVEC_MAKE_STRING(buffer);
388 iovec[n++] = IOVEC_MAKE_STRING(ANSI_NORMAL);
389 iovec[n++] = IOVEC_MAKE_STRING("\n");
391 if (writev(console_fd, iovec, n) < 0) {
393 if (errno == EIO && getpid_cached() == 1) {
395 /* If somebody tried to kick us from our
396 * console tty (via vhangup() or suchlike),
397 * try to reconnect */
405 if (writev(console_fd, iovec, n) < 0)
414 static int write_to_syslog(
420 const char *buffer) {
422 char header_priority[2 + DECIMAL_STR_MAX(int) + 1],
424 header_pid[4 + DECIMAL_STR_MAX(pid_t) + 1];
425 struct iovec iovec[5] = {};
426 struct msghdr msghdr = {
428 .msg_iovlen = ELEMENTSOF(iovec),
436 xsprintf(header_priority, "<%i>", level);
438 t = (time_t) (now(CLOCK_REALTIME) / USEC_PER_SEC);
443 if (strftime(header_time, sizeof(header_time), "%h %e %T ", tm) <= 0)
446 xsprintf(header_pid, "["PID_FMT"]: ", getpid_cached());
448 iovec[0] = IOVEC_MAKE_STRING(header_priority);
449 iovec[1] = IOVEC_MAKE_STRING(header_time);
450 iovec[2] = IOVEC_MAKE_STRING(program_invocation_short_name);
451 iovec[3] = IOVEC_MAKE_STRING(header_pid);
452 iovec[4] = IOVEC_MAKE_STRING(buffer);
454 /* When using syslog via SOCK_STREAM separate the messages by NUL chars */
455 if (syslog_is_stream)
461 n = sendmsg(syslog_fd, &msghdr, MSG_NOSIGNAL);
465 if (!syslog_is_stream ||
466 (size_t) n >= IOVEC_TOTAL_SIZE(iovec, ELEMENTSOF(iovec)))
469 IOVEC_INCREMENT(iovec, ELEMENTSOF(iovec), n);
475 static int write_to_kmsg(
481 const char *buffer) {
483 char header_priority[2 + DECIMAL_STR_MAX(int) + 1],
484 header_pid[4 + DECIMAL_STR_MAX(pid_t) + 1];
485 struct iovec iovec[5] = {};
490 xsprintf(header_priority, "<%i>", level);
491 xsprintf(header_pid, "["PID_FMT"]: ", getpid_cached());
493 iovec[0] = IOVEC_MAKE_STRING(header_priority);
494 iovec[1] = IOVEC_MAKE_STRING(program_invocation_short_name);
495 iovec[2] = IOVEC_MAKE_STRING(header_pid);
496 iovec[3] = IOVEC_MAKE_STRING(buffer);
497 iovec[4] = IOVEC_MAKE_STRING("\n");
499 if (writev(kmsg_fd, iovec, ELEMENTSOF(iovec)) < 0)
505 static int log_do_header(
510 const char *file, int line, const char *func,
511 const char *object_field, const char *object,
512 const char *extra_field, const char *extra) {
514 snprintf(header, size,
516 "SYSLOG_FACILITY=%i\n"
523 "SYSLOG_IDENTIFIER=%s\n",
526 isempty(file) ? "" : "CODE_FILE=",
527 isempty(file) ? "" : file,
528 isempty(file) ? "" : "\n",
529 line ? "CODE_LINE=" : "",
530 line ? 1 : 0, line, /* %.0d means no output too, special case for 0 */
532 isempty(func) ? "" : "CODE_FUNC=",
533 isempty(func) ? "" : func,
534 isempty(func) ? "" : "\n",
535 error ? "ERRNO=" : "",
536 error ? 1 : 0, error,
538 isempty(object) ? "" : object_field,
539 isempty(object) ? "" : object,
540 isempty(object) ? "" : "\n",
541 isempty(extra) ? "" : extra_field,
542 isempty(extra) ? "" : extra,
543 isempty(extra) ? "" : "\n",
544 program_invocation_short_name);
549 #if 0 /// UNNEEDED by elogind
550 static int write_to_journal(
556 const char *object_field,
558 const char *extra_field,
560 const char *buffer) {
562 char header[LINE_MAX];
563 struct iovec iovec[4] = {};
564 struct msghdr mh = {};
569 log_do_header(header, sizeof(header), level, error, file, line, func, object_field, object, extra_field, extra);
571 iovec[0] = IOVEC_MAKE_STRING(header);
572 iovec[1] = IOVEC_MAKE_STRING("MESSAGE=");
573 iovec[2] = IOVEC_MAKE_STRING(buffer);
574 iovec[3] = IOVEC_MAKE_STRING("\n");
577 mh.msg_iovlen = ELEMENTSOF(iovec);
579 if (sendmsg(journal_fd, &mh, MSG_NOSIGNAL) < 0)
586 int log_dispatch_internal(
592 const char *object_field,
594 const char *extra_field,
603 if (log_target == LOG_TARGET_NULL)
606 /* Patch in LOG_DAEMON facility if necessary */
607 if ((level & LOG_FACMASK) == 0)
608 level = log_facility | LOG_PRI(level);
610 if (open_when_needed)
617 buffer += strspn(buffer, NEWLINE);
622 if ((e = strpbrk(buffer, NEWLINE)))
625 #if 0 /// elogind does not support logging to systemd-journald
626 if (IN_SET(log_target, LOG_TARGET_AUTO,
627 LOG_TARGET_JOURNAL_OR_KMSG,
628 LOG_TARGET_JOURNAL)) {
630 k = write_to_journal(level, error, file, line, func, object_field, object, extra_field, extra, buffer);
631 if (k < 0 && k != -EAGAIN)
636 if (IN_SET(log_target, LOG_TARGET_SYSLOG_OR_KMSG,
637 LOG_TARGET_SYSLOG)) {
639 k = write_to_syslog(level, error, file, line, func, buffer);
640 if (k < 0 && k != -EAGAIN)
645 IN_SET(log_target, LOG_TARGET_AUTO,
646 LOG_TARGET_SYSLOG_OR_KMSG,
647 LOG_TARGET_JOURNAL_OR_KMSG,
653 k = write_to_kmsg(level, error, file, line, func, buffer);
661 (void) write_to_console(level, error, file, line, func, buffer);
666 if (open_when_needed)
672 int log_dump_internal(
680 LogRealm realm = LOG_REALM_REMOVE_LEVEL(level);
683 /* This modifies the buffer... */
688 if (_likely_(LOG_PRI(level) > log_max_level[realm]))
691 return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buffer);
694 int log_internalv_realm(
703 LogRealm realm = LOG_REALM_REMOVE_LEVEL(level);
704 char buffer[LINE_MAX];
710 if (_likely_(LOG_PRI(level) > log_max_level[realm]))
713 /* Make sure that %m maps to the specified error */
717 (void) vsnprintf(buffer, sizeof buffer, format, ap);
719 return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buffer);
722 int log_internal_realm(
728 const char *format, ...) {
733 va_start(ap, format);
734 r = log_internalv_realm(level, error, file, line, func, format, ap);
741 static int log_object_internalv(
747 const char *object_field,
749 const char *extra_field,
760 if (_likely_(LOG_PRI(level) > log_max_level[LOG_REALM_SYSTEMD]))
763 /* Make sure that %m maps to the specified error */
767 /* Prepend the object name before the message */
772 buffer = newa(char, n + 2 + LINE_MAX);
773 b = stpcpy(stpcpy(buffer, object), ": ");
775 b = buffer = newa(char, LINE_MAX);
777 (void) vsnprintf(b, LINE_MAX, format, ap);
779 return log_dispatch_internal(level, error, file, line, func,
780 object_field, object, extra_field, extra, buffer);
783 int log_object_internal(
789 const char *object_field,
791 const char *extra_field,
793 const char *format, ...) {
798 va_start(ap, format);
799 r = log_object_internalv(level, error, file, line, func, object_field, object, extra_field, extra, format, ap);
805 static void log_assert(
811 const char *format) {
813 static char buffer[LINE_MAX];
814 LogRealm realm = LOG_REALM_REMOVE_LEVEL(level);
816 if (_likely_(LOG_PRI(level) > log_max_level[realm]))
819 DISABLE_WARNING_FORMAT_NONLITERAL;
820 (void) snprintf(buffer, sizeof buffer, format, text, file, line, func);
823 log_abort_msg = buffer;
825 log_dispatch_internal(level, 0, file, line, func, NULL, NULL, NULL, NULL, buffer);
828 noreturn void log_assert_failed_realm(
835 log_assert(LOG_REALM_PLUS_LEVEL(realm, LOG_CRIT), text, file, line, func,
836 "Assertion '%s' failed at %s:%u, function %s(). Aborting.");
840 noreturn void log_assert_failed_unreachable_realm(
847 log_assert(LOG_REALM_PLUS_LEVEL(realm, LOG_CRIT), text, file, line, func,
848 "Code should not be reached '%s' at %s:%u, function %s(). Aborting.");
852 void log_assert_failed_return_realm(
859 log_assert(LOG_REALM_PLUS_LEVEL(realm, LOG_DEBUG), text, file, line, func,
860 "Assertion '%s' failed at %s:%u, function %s(). Ignoring.");
863 int log_oom_internal(LogRealm realm, const char *file, int line, const char *func) {
864 return log_internal_realm(LOG_REALM_PLUS_LEVEL(realm, LOG_ERR),
865 ENOMEM, file, line, func, "Out of memory.");
868 int log_format_iovec(
872 bool newline_separator,
877 static const char nl = '\n';
879 while (format && *n + 1 < iovec_len) {
884 /* We need to copy the va_list structure,
885 * since vasprintf() leaves it afterwards at
886 * an undefined location */
892 r = vasprintf(&m, format, aq);
897 /* Now, jump enough ahead, so that we point to
898 * the next format string */
899 VA_FORMAT_ADVANCE(format, ap);
901 iovec[(*n)++] = IOVEC_MAKE_STRING(m);
903 if (newline_separator) {
904 iovec[*n].iov_base = (char*) &nl;
905 iovec[*n].iov_len = 1;
909 format = va_arg(ap, char *);
914 int log_struct_internal(
920 const char *format, ...) {
922 LogRealm realm = LOG_REALM_REMOVE_LEVEL(level);
931 if (_likely_(LOG_PRI(level) > log_max_level[realm]))
934 if (log_target == LOG_TARGET_NULL)
937 if ((level & LOG_FACMASK) == 0)
938 level = log_facility | LOG_PRI(level);
940 #if 0 /// elogind does not support logging to systemd-journald
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] = {};
957 bool fallback = false;
959 /* If the journal is available do structured logging */
960 log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL, NULL, NULL);
961 iovec[n++] = IOVEC_MAKE_STRING(header);
963 va_start(ap, format);
964 r = log_format_iovec(iovec, ELEMENTSOF(iovec), &n, true, error, format, ap);
969 (void) sendmsg(journal_fd, &mh, MSG_NOSIGNAL);
973 for (i = 1; i < n; i += 2)
974 free(iovec[i].iov_base);
977 if (open_when_needed)
986 /* Fallback if journal logging is not available or didn't work. */
988 va_start(ap, format);
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)
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) {
1029 LogRealm realm = LOG_REALM_REMOVE_LEVEL(level);
1037 if (_likely_(LOG_PRI(level) > log_max_level[realm]))
1040 if (log_target == LOG_TARGET_NULL)
1043 if ((level & LOG_FACMASK) == 0)
1044 level = log_facility | LOG_PRI(level);
1046 if (IN_SET(log_target, LOG_TARGET_AUTO,
1047 LOG_TARGET_JOURNAL_OR_KMSG,
1048 LOG_TARGET_JOURNAL) &&
1051 struct iovec iovec[1 + n_input_iovec*2];
1052 char header[LINE_MAX];
1053 struct msghdr mh = {
1055 .msg_iovlen = 1 + n_input_iovec*2,
1058 log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL, NULL, NULL);
1059 iovec[0] = IOVEC_MAKE_STRING(header);
1061 for (i = 0; i < n_input_iovec; i++) {
1062 iovec[1+i*2] = input_iovec[i];
1063 iovec[1+i*2+1] = IOVEC_MAKE_STRING("\n");
1066 if (sendmsg(journal_fd, &mh, MSG_NOSIGNAL) >= 0)
1070 for (i = 0; i < n_input_iovec; i++) {
1071 if (input_iovec[i].iov_len < STRLEN("MESSAGE="))
1074 if (memcmp(input_iovec[i].iov_base, "MESSAGE=", STRLEN("MESSAGE=")) == 0)
1078 if (_unlikely_(i >= n_input_iovec)) /* Couldn't find MESSAGE=? */
1081 m = strndupa(input_iovec[i].iov_base + STRLEN("MESSAGE="),
1082 input_iovec[i].iov_len - STRLEN("MESSAGE="));
1084 return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, m);
1087 int log_set_target_from_string(const char *e) {
1090 t = log_target_from_string(e);
1098 int log_set_max_level_from_string_realm(LogRealm realm, const char *e) {
1101 t = log_level_from_string(e);
1105 log_set_max_level_realm(realm, t);
1109 static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
1112 * The systemd.log_xyz= settings are parsed by all tools, and
1115 * However, "quiet" is only parsed by PID 1, and only turns of
1116 * status output to /dev/console, but does not alter the log
1120 if (streq(key, "debug") && !value)
1121 log_set_max_level(LOG_DEBUG);
1123 else if (proc_cmdline_key_streq(key, "systemd.log_target")) {
1125 if (proc_cmdline_value_missing(key, value))
1128 if (log_set_target_from_string(value) < 0)
1129 log_warning("Failed to parse log target '%s'. Ignoring.", value);
1131 } else if (proc_cmdline_key_streq(key, "systemd.log_level")) {
1133 if (proc_cmdline_value_missing(key, value))
1136 if (log_set_max_level_from_string(value) < 0)
1137 log_warning("Failed to parse log level '%s'. Ignoring.", value);
1139 } else if (proc_cmdline_key_streq(key, "systemd.log_color")) {
1141 if (log_show_color_from_string(value ?: "1") < 0)
1142 log_warning("Failed to parse log color setting '%s'. Ignoring.", value);
1144 } else if (proc_cmdline_key_streq(key, "systemd.log_location")) {
1146 if (log_show_location_from_string(value ?: "1") < 0)
1147 log_warning("Failed to parse log location setting '%s'. Ignoring.", value);
1153 void log_parse_environment_realm(LogRealm realm) {
1154 /* Do not call from library code. */
1158 if (get_ctty_devnr(0, NULL) < 0)
1159 /* Only try to read the command line in daemons. We assume that anything that has a controlling tty is
1161 (void) proc_cmdline_parse(parse_proc_cmdline_item, NULL, PROC_CMDLINE_STRIP_RD_PREFIX);
1163 e = getenv("SYSTEMD_LOG_TARGET");
1164 if (e && log_set_target_from_string(e) < 0)
1165 log_warning("Failed to parse log target '%s'. Ignoring.", e);
1167 e = getenv("SYSTEMD_LOG_LEVEL");
1168 if (e && log_set_max_level_from_string_realm(realm, e) < 0)
1169 log_warning("Failed to parse log level '%s'. Ignoring.", e);
1171 e = getenv("SYSTEMD_LOG_COLOR");
1172 if (e && log_show_color_from_string(e) < 0)
1173 log_warning("Failed to parse bool '%s'. Ignoring.", e);
1175 e = getenv("SYSTEMD_LOG_LOCATION");
1176 if (e && log_show_location_from_string(e) < 0)
1177 log_warning("Failed to parse bool '%s'. Ignoring.", e);
1180 LogTarget log_get_target(void) {
1184 int log_get_max_level_realm(LogRealm realm) {
1185 return log_max_level[realm];
1188 void log_show_color(bool b) {
1192 bool log_get_show_color(void) {
1196 void log_show_location(bool b) {
1200 bool log_get_show_location(void) {
1201 return show_location;
1204 int log_show_color_from_string(const char *e) {
1207 t = parse_boolean(e);
1215 int log_show_location_from_string(const char *e) {
1218 t = parse_boolean(e);
1222 log_show_location(t);
1226 bool log_on_console(void) {
1227 if (IN_SET(log_target, LOG_TARGET_CONSOLE,
1228 LOG_TARGET_CONSOLE_PREFIXED))
1231 return syslog_fd < 0 && kmsg_fd < 0 && journal_fd < 0;
1234 static const char *const log_target_table[_LOG_TARGET_MAX] = {
1235 [LOG_TARGET_CONSOLE] = "console",
1236 [LOG_TARGET_CONSOLE_PREFIXED] = "console-prefixed",
1237 [LOG_TARGET_KMSG] = "kmsg",
1238 #if 0 /// elogind does not support logging to systemd-journald
1239 [LOG_TARGET_JOURNAL] = "journal",
1240 [LOG_TARGET_JOURNAL_OR_KMSG] = "journal-or-kmsg",
1242 [LOG_TARGET_SYSLOG] = "syslog",
1243 [LOG_TARGET_SYSLOG_OR_KMSG] = "syslog-or-kmsg",
1244 [LOG_TARGET_AUTO] = "auto",
1245 [LOG_TARGET_NULL] = "null",
1248 DEFINE_STRING_TABLE_LOOKUP(log_target, LogTarget);
1250 #if 0 /// UNNEEDED by elogind
1251 void log_received_signal(int level, const struct signalfd_siginfo *si) {
1254 if (pid_is_valid(si->ssi_pid)) {
1255 _cleanup_free_ char *p = NULL;
1257 (void) get_process_comm(si->ssi_pid, &p);
1260 "Received SIG%s from PID %"PRIu32" (%s).",
1261 signal_to_string(si->ssi_signo),
1262 si->ssi_pid, strna(p));
1266 signal_to_string(si->ssi_signo));
1270 int log_syntax_internal(
1273 const char *config_file,
1274 unsigned config_line,
1279 const char *format, ...) {
1282 char buffer[LINE_MAX];
1284 const char *unit_fmt = NULL;
1289 if (_likely_(LOG_PRI(level) > log_max_level[LOG_REALM_SYSTEMD]))
1292 if (log_target == LOG_TARGET_NULL)
1298 va_start(ap, format);
1299 (void) vsnprintf(buffer, sizeof buffer, format, ap);
1303 unit_fmt = getpid_cached() == 1 ? "UNIT=%s" : "USER_UNIT=%s";
1305 return log_struct_internal(
1306 LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, level),
1309 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
1310 "CONFIG_FILE=%s", config_file,
1311 "CONFIG_LINE=%u", config_line,
1312 LOG_MESSAGE("%s:%u: %s", config_file, config_line, buffer),
1317 int log_syntax_invalid_utf8_internal(
1320 const char *config_file,
1321 unsigned config_line,
1325 const char *rvalue) {
1327 _cleanup_free_ char *p = NULL;
1330 p = utf8_escape_invalid(rvalue);
1332 log_syntax_internal(unit, level, config_file, config_line, 0, file, line, func,
1333 "String is not UTF-8 clean, ignoring assignment: %s", strna(p));
1338 #if 0 /// UNNEEDED by elogind
1339 void log_set_upgrade_syslog_to_journal(bool b) {
1340 upgrade_syslog_to_journal = b;
1342 /* Make the change effective immediately */
1344 if (log_target == LOG_TARGET_SYSLOG)
1345 log_target = LOG_TARGET_JOURNAL;
1346 else if (log_target == LOG_TARGET_SYSLOG_OR_KMSG)
1347 log_target = LOG_TARGET_JOURNAL_OR_KMSG;
1351 void log_set_always_reopen_console(bool b) {
1352 always_reopen_console = b;
1356 void log_set_open_when_needed(bool b) {
1357 open_when_needed = b;
1360 void log_set_prohibit_ipc(bool b) {
1364 int log_emergency_level(void) {
1365 /* Returns the log level to use for log_emergency() logging. We use LOG_EMERG only when we are PID 1, as only
1366 * then the system of the whole system is obviously affected. */
1368 return getpid_cached() == 1 ? LOG_EMERG : LOG_ERR;