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 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,
595 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 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);
740 int log_object_internalv(
746 const char *object_field,
748 const char *extra_field,
759 if (_likely_(LOG_PRI(level) > log_max_level[LOG_REALM_SYSTEMD]))
762 /* Make sure that %m maps to the specified error */
766 /* Prepend the object name before the message */
771 buffer = newa(char, n + 2 + LINE_MAX);
772 b = stpcpy(stpcpy(buffer, object), ": ");
774 b = buffer = newa(char, LINE_MAX);
776 vsnprintf(b, LINE_MAX, format, ap);
778 return log_dispatch_internal(level, error, file, line, func,
779 object_field, object, extra_field, extra, buffer);
782 int log_object_internal(
788 const char *object_field,
790 const char *extra_field,
792 const char *format, ...) {
797 va_start(ap, format);
798 r = log_object_internalv(level, error, file, line, func, object_field, object, extra_field, extra, format, ap);
804 static void log_assert(
810 const char *format) {
812 static char buffer[LINE_MAX];
813 LogRealm realm = LOG_REALM_REMOVE_LEVEL(level);
815 if (_likely_(LOG_PRI(level) > log_max_level[realm]))
818 DISABLE_WARNING_FORMAT_NONLITERAL;
819 snprintf(buffer, sizeof buffer, format, text, file, line, func);
822 log_abort_msg = buffer;
824 log_dispatch_internal(level, 0, file, line, func, NULL, NULL, NULL, NULL, buffer);
827 noreturn void log_assert_failed_realm(
834 log_assert(LOG_REALM_PLUS_LEVEL(realm, LOG_CRIT), text, file, line, func,
835 "Assertion '%s' failed at %s:%u, function %s(). Aborting.");
839 noreturn void log_assert_failed_unreachable_realm(
846 log_assert(LOG_REALM_PLUS_LEVEL(realm, LOG_CRIT), text, file, line, func,
847 "Code should not be reached '%s' at %s:%u, function %s(). Aborting.");
851 void log_assert_failed_return_realm(
858 log_assert(LOG_REALM_PLUS_LEVEL(realm, LOG_DEBUG), text, file, line, func,
859 "Assertion '%s' failed at %s:%u, function %s(). Ignoring.");
862 int log_oom_internal(LogRealm realm, const char *file, int line, const char *func) {
863 return log_internal_realm(LOG_REALM_PLUS_LEVEL(realm, LOG_ERR),
864 ENOMEM, file, line, func, "Out of memory.");
867 int log_format_iovec(
871 bool newline_separator,
876 static const char nl = '\n';
878 while (format && *n + 1 < iovec_len) {
883 /* We need to copy the va_list structure,
884 * since vasprintf() leaves it afterwards at
885 * an undefined location */
891 r = vasprintf(&m, format, aq);
896 /* Now, jump enough ahead, so that we point to
897 * the next format string */
898 VA_FORMAT_ADVANCE(format, ap);
900 iovec[(*n)++] = IOVEC_MAKE_STRING(m);
902 if (newline_separator) {
903 iovec[*n].iov_base = (char*) &nl;
904 iovec[*n].iov_len = 1;
908 format = va_arg(ap, char *);
913 int log_struct_internal(
919 const char *format, ...) {
921 LogRealm realm = LOG_REALM_REMOVE_LEVEL(level);
930 if (_likely_(LOG_PRI(level) > log_max_level[realm]))
933 if (log_target == LOG_TARGET_NULL)
936 if ((level & LOG_FACMASK) == 0)
937 level = log_facility | LOG_PRI(level);
939 #if 0 /// elogind does not support logging to systemd-journald
940 if (IN_SET(log_target,
942 LOG_TARGET_JOURNAL_OR_KMSG,
943 LOG_TARGET_JOURNAL)) {
945 if (open_when_needed)
948 if (journal_fd >= 0) {
949 char header[LINE_MAX];
950 struct iovec iovec[17] = {};
956 bool fallback = false;
958 /* If the journal is available do structured logging */
959 log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL, NULL, NULL);
960 iovec[n++] = IOVEC_MAKE_STRING(header);
962 va_start(ap, format);
963 r = log_format_iovec(iovec, ELEMENTSOF(iovec), &n, true, error, format, ap);
968 (void) sendmsg(journal_fd, &mh, MSG_NOSIGNAL);
972 for (i = 1; i < n; i += 2)
973 free(iovec[i].iov_base);
976 if (open_when_needed)
985 /* Fallback if journal logging is not available or didn't work. */
987 va_start(ap, format);
995 vsnprintf(buf, sizeof(buf), format, aq);
998 if (startswith(buf, "MESSAGE=")) {
1003 VA_FORMAT_ADVANCE(format, ap);
1005 format = va_arg(ap, char *);
1010 if (open_when_needed)
1016 return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buf + 8);
1019 int log_struct_iovec_internal(
1025 const struct iovec input_iovec[],
1026 size_t n_input_iovec) {
1028 LogRealm realm = LOG_REALM_REMOVE_LEVEL(level);
1036 if (_likely_(LOG_PRI(level) > log_max_level[realm]))
1039 if (log_target == LOG_TARGET_NULL)
1042 if ((level & LOG_FACMASK) == 0)
1043 level = log_facility | LOG_PRI(level);
1045 if (IN_SET(log_target, LOG_TARGET_AUTO,
1046 LOG_TARGET_JOURNAL_OR_KMSG,
1047 LOG_TARGET_JOURNAL) &&
1050 struct iovec iovec[1 + n_input_iovec*2];
1051 char header[LINE_MAX];
1052 struct msghdr mh = {
1054 .msg_iovlen = 1 + n_input_iovec*2,
1057 log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL, NULL, NULL);
1058 iovec[0] = IOVEC_MAKE_STRING(header);
1060 for (i = 0; i < n_input_iovec; i++) {
1061 iovec[1+i*2] = input_iovec[i];
1062 iovec[1+i*2+1] = IOVEC_MAKE_STRING("\n");
1065 if (sendmsg(journal_fd, &mh, MSG_NOSIGNAL) >= 0)
1069 for (i = 0; i < n_input_iovec; i++) {
1070 if (input_iovec[i].iov_len < STRLEN("MESSAGE="))
1073 if (memcmp(input_iovec[i].iov_base, "MESSAGE=", STRLEN("MESSAGE=")) == 0)
1077 if (_unlikely_(i >= n_input_iovec)) /* Couldn't find MESSAGE=? */
1080 m = strndupa(input_iovec[i].iov_base + STRLEN("MESSAGE="),
1081 input_iovec[i].iov_len - STRLEN("MESSAGE="));
1083 return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, m);
1086 int log_set_target_from_string(const char *e) {
1089 t = log_target_from_string(e);
1097 int log_set_max_level_from_string_realm(LogRealm realm, const char *e) {
1100 t = log_level_from_string(e);
1104 log_set_max_level_realm(realm, t);
1108 static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
1111 * The systemd.log_xyz= settings are parsed by all tools, and
1114 * However, "quiet" is only parsed by PID 1, and only turns of
1115 * status output to /dev/console, but does not alter the log
1119 if (streq(key, "debug") && !value)
1120 log_set_max_level(LOG_DEBUG);
1122 else if (proc_cmdline_key_streq(key, "systemd.log_target")) {
1124 if (proc_cmdline_value_missing(key, value))
1127 if (log_set_target_from_string(value) < 0)
1128 log_warning("Failed to parse log target '%s'. Ignoring.", value);
1130 } else if (proc_cmdline_key_streq(key, "systemd.log_level")) {
1132 if (proc_cmdline_value_missing(key, value))
1135 if (log_set_max_level_from_string(value) < 0)
1136 log_warning("Failed to parse log level '%s'. Ignoring.", value);
1138 } else if (proc_cmdline_key_streq(key, "systemd.log_color")) {
1140 if (log_show_color_from_string(value ?: "1") < 0)
1141 log_warning("Failed to parse log color setting '%s'. Ignoring.", value);
1143 } else if (proc_cmdline_key_streq(key, "systemd.log_location")) {
1145 if (log_show_location_from_string(value ?: "1") < 0)
1146 log_warning("Failed to parse log location setting '%s'. Ignoring.", value);
1152 void log_parse_environment_realm(LogRealm realm) {
1153 /* Do not call from library code. */
1157 if (get_ctty_devnr(0, NULL) < 0)
1158 /* Only try to read the command line in daemons. We assume that anything that has a controlling tty is
1160 (void) proc_cmdline_parse(parse_proc_cmdline_item, NULL, PROC_CMDLINE_STRIP_RD_PREFIX);
1162 e = getenv("SYSTEMD_LOG_TARGET");
1163 if (e && log_set_target_from_string(e) < 0)
1164 log_warning("Failed to parse log target '%s'. Ignoring.", e);
1166 e = getenv("SYSTEMD_LOG_LEVEL");
1167 if (e && log_set_max_level_from_string_realm(realm, e) < 0)
1168 log_warning("Failed to parse log level '%s'. Ignoring.", e);
1170 e = getenv("SYSTEMD_LOG_COLOR");
1171 if (e && log_show_color_from_string(e) < 0)
1172 log_warning("Failed to parse bool '%s'. Ignoring.", e);
1174 e = getenv("SYSTEMD_LOG_LOCATION");
1175 if (e && log_show_location_from_string(e) < 0)
1176 log_warning("Failed to parse bool '%s'. Ignoring.", e);
1179 LogTarget log_get_target(void) {
1183 int log_get_max_level_realm(LogRealm realm) {
1184 return log_max_level[realm];
1187 void log_show_color(bool b) {
1191 bool log_get_show_color(void) {
1195 void log_show_location(bool b) {
1199 bool log_get_show_location(void) {
1200 return show_location;
1203 int log_show_color_from_string(const char *e) {
1206 t = parse_boolean(e);
1214 int log_show_location_from_string(const char *e) {
1217 t = parse_boolean(e);
1221 log_show_location(t);
1225 bool log_on_console(void) {
1226 if (IN_SET(log_target, LOG_TARGET_CONSOLE,
1227 LOG_TARGET_CONSOLE_PREFIXED))
1230 return syslog_fd < 0 && kmsg_fd < 0 && journal_fd < 0;
1233 static const char *const log_target_table[_LOG_TARGET_MAX] = {
1234 [LOG_TARGET_CONSOLE] = "console",
1235 [LOG_TARGET_CONSOLE_PREFIXED] = "console-prefixed",
1236 [LOG_TARGET_KMSG] = "kmsg",
1237 #if 0 /// elogind does not support logging to systemd-journald
1238 [LOG_TARGET_JOURNAL] = "journal",
1239 [LOG_TARGET_JOURNAL_OR_KMSG] = "journal-or-kmsg",
1241 [LOG_TARGET_SYSLOG] = "syslog",
1242 [LOG_TARGET_SYSLOG_OR_KMSG] = "syslog-or-kmsg",
1243 [LOG_TARGET_AUTO] = "auto",
1244 [LOG_TARGET_NULL] = "null",
1247 DEFINE_STRING_TABLE_LOOKUP(log_target, LogTarget);
1249 #if 0 /// UNNEEDED by elogind
1250 void log_received_signal(int level, const struct signalfd_siginfo *si) {
1253 if (pid_is_valid(si->ssi_pid)) {
1254 _cleanup_free_ char *p = NULL;
1256 (void) get_process_comm(si->ssi_pid, &p);
1259 "Received SIG%s from PID %"PRIu32" (%s).",
1260 signal_to_string(si->ssi_signo),
1261 si->ssi_pid, strna(p));
1265 signal_to_string(si->ssi_signo));
1269 int log_syntax_internal(
1272 const char *config_file,
1273 unsigned config_line,
1278 const char *format, ...) {
1281 char buffer[LINE_MAX];
1283 const char *unit_fmt = NULL;
1288 if (_likely_(LOG_PRI(level) > log_max_level[LOG_REALM_SYSTEMD]))
1291 if (log_target == LOG_TARGET_NULL)
1297 va_start(ap, format);
1298 vsnprintf(buffer, sizeof(buffer), format, ap);
1302 unit_fmt = getpid_cached() == 1 ? "UNIT=%s" : "USER_UNIT=%s";
1304 return log_struct_internal(
1305 LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, level),
1308 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
1309 "CONFIG_FILE=%s", config_file,
1310 "CONFIG_LINE=%u", config_line,
1311 LOG_MESSAGE("%s:%u: %s", config_file, config_line, buffer),
1316 int log_syntax_invalid_utf8_internal(
1319 const char *config_file,
1320 unsigned config_line,
1324 const char *rvalue) {
1326 _cleanup_free_ char *p = NULL;
1329 p = utf8_escape_invalid(rvalue);
1331 log_syntax_internal(unit, level, config_file, config_line, 0, file, line, func,
1332 "String is not UTF-8 clean, ignoring assignment: %s", strna(p));
1337 #if 0 /// UNNEEDED by elogind
1338 void log_set_upgrade_syslog_to_journal(bool b) {
1339 upgrade_syslog_to_journal = b;
1341 /* Make the change effective immediately */
1343 if (log_target == LOG_TARGET_SYSLOG)
1344 log_target = LOG_TARGET_JOURNAL;
1345 else if (log_target == LOG_TARGET_SYSLOG_OR_KMSG)
1346 log_target = LOG_TARGET_JOURNAL_OR_KMSG;
1350 void log_set_always_reopen_console(bool b) {
1351 always_reopen_console = b;
1355 void log_set_open_when_needed(bool b) {
1356 open_when_needed = b;
1359 void log_set_prohibit_ipc(bool b) {
1363 int log_emergency_level(void) {
1364 /* Returns the log level to use for log_emergency() logging. We use LOG_EMERG only when we are PID 1, as only
1365 * then the system of the whole system is obviously affected. */
1367 return getpid_cached() == 1 ? LOG_EMERG : LOG_ERR;