chiark / gitweb /
Fix service file to match installed elogind binary location
[elogind.git] / src / basic / log.c
index 08aa986a0ec3f3826a27a645ca4c4502fe16ce07..3924ed71f10680261e680f5ba9a39f47a7051444 100644 (file)
@@ -37,7 +37,7 @@
 
 #include "alloc-util.h"
 #include "fd-util.h"
-#include "formats-util.h"
+#include "format-util.h"
 #include "io-util.h"
 #include "log.h"
 #include "macro.h"
@@ -58,7 +58,8 @@
 #define SNDBUF_SIZE (8*1024*1024)
 
 static LogTarget log_target = LOG_TARGET_CONSOLE;
-static int log_max_level = LOG_INFO;
+static int log_max_level[] = {LOG_INFO, LOG_INFO};
+assert_cc(ELEMENTSOF(log_max_level) == _LOG_REALM_MAX);
 static int log_facility = LOG_DAEMON;
 
 static int console_fd = STDERR_FILENO;
@@ -71,7 +72,10 @@ static bool syslog_is_stream = false;
 static bool show_color = false;
 static bool show_location = false;
 
-/// UNNEEDED by elogind  static bool upgrade_syslog_to_journal = false;
+#if 0 /// UNNEEDED by elogind
+static bool upgrade_syslog_to_journal = false;
+#endif // 0
+static bool always_reopen_console = false;
 
 /* Akin to glibc's __abort_msg; which is private and we hence cannot
  * use here. */
@@ -95,7 +99,7 @@ static int log_open_console(void) {
         if (console_fd >= 0)
                 return 0;
 
-        if (getpid() == 1) {
+        if (always_reopen_console) {
                 console_fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
                 if (console_fd < 0)
                         return console_fd;
@@ -133,7 +137,7 @@ static int create_log_socket(int type) {
         if (fd < 0)
                 return -errno;
 
-        fd_inc_sndbuf(fd, SNDBUF_SIZE);
+        (void) fd_inc_sndbuf(fd, SNDBUF_SIZE);
 
         /* We need a blocking fd here since we'd otherwise lose
         messages way too early. However, let's not hang forever in the
@@ -193,11 +197,13 @@ fail:
         return r;
 }
 
-#if 0 /// UNNEEDED by elogind
 void log_close_journal(void) {
+#if 0 /// elogind does not support journald
         journal_fd = safe_close(journal_fd);
+#endif // 0
 }
 
+#if 0 /// UNNEEDED by elogind
 static int log_open_journal(void) {
 
         static const union sockaddr_union sa = {
@@ -232,6 +238,8 @@ fail:
 int log_open(void) {
         int r;
 
+        /* Do not call from library code. */
+
         /* If we don't use the console we close it here, to not get
          * killed by SAK. If we don't use syslog we close it here so
          * that we are not confused by somebody deleting the socket in
@@ -239,20 +247,20 @@ int log_open(void) {
          * because there is no reason to close it. */
 
         if (log_target == LOG_TARGET_NULL) {
-                /// UNNEEDED by elogind log_close_journal();
+                log_close_journal();
                 log_close_syslog();
                 log_close_console();
                 return 0;
         }
 
-        if ((log_target != LOG_TARGET_AUTO && log_target != LOG_TARGET_SAFE) ||
+        if (!IN_SET(log_target, LOG_TARGET_AUTO, LOG_TARGET_SAFE) ||
             getpid() == 1 ||
             isatty(STDERR_FILENO) <= 0) {
 
 #if 0 /// elogind does not support logging to systemd-journald
-                if (log_target == LOG_TARGET_AUTO ||
-                    log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
-                    log_target == LOG_TARGET_JOURNAL) {
+                if (IN_SET(log_target, LOG_TARGET_AUTO,
+                                       LOG_TARGET_JOURNAL_OR_KMSG,
+                                       LOG_TARGET_JOURNAL)) {
                         r = log_open_journal();
                         if (r >= 0) {
                                 log_close_syslog();
@@ -261,24 +269,25 @@ int log_open(void) {
                         }
                 }
 #endif // 0
-                if (log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
-                    log_target == LOG_TARGET_SYSLOG) {
+
+                if (IN_SET(log_target, LOG_TARGET_SYSLOG_OR_KMSG,
+                                       LOG_TARGET_SYSLOG)) {
                         r = log_open_syslog();
                         if (r >= 0) {
-                                /// UNNEEDED by elogind log_close_journal();
+                                log_close_journal();
                                 log_close_console();
                                 return r;
                         }
                 }
 
-                if (log_target == LOG_TARGET_AUTO ||
-                    log_target == LOG_TARGET_SAFE ||
-                    /// UNNEEDED by elogind log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
-                    log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
-                    log_target == LOG_TARGET_KMSG) {
+                if (IN_SET(log_target, LOG_TARGET_AUTO,
+                                       LOG_TARGET_SAFE,
+                                       LOG_TARGET_JOURNAL_OR_KMSG,
+                                       LOG_TARGET_SYSLOG_OR_KMSG,
+                                       LOG_TARGET_KMSG)) {
                         r = log_open_kmsg();
                         if (r >= 0) {
-                                /// UNNEEDED by elogind log_close_journal();
+                                log_close_journal();
                                 log_close_syslog();
                                 log_close_console();
                                 return r;
@@ -286,7 +295,7 @@ int log_open(void) {
                 }
         }
 
-        /// UNNEEDED by elogind log_close_journal();
+        log_close_journal();
         log_close_syslog();
 
         return log_open_console();
@@ -309,7 +318,9 @@ void log_set_target(LogTarget target) {
 }
 
 void log_close(void) {
-        /// UNNEDED by elogind log_close_journal();
+        /* Do not call from library code. */
+
+        log_close_journal();
         log_close_syslog();
         log_close_kmsg();
         log_close_console();
@@ -317,14 +328,17 @@ void log_close(void) {
 
 #if 0 /// UNNEEDED by elogind
 void log_forget_fds(void) {
+        /* Do not call from library code. */
+
         console_fd = kmsg_fd = syslog_fd = journal_fd = -1;
 }
 #endif // 0
 
-void log_set_max_level(int level) {
+void log_set_max_level_realm(LogRealm realm, int level) {
         assert((level & LOG_PRIMASK) == level);
+        assert(realm < ELEMENTSOF(log_max_level));
 
-        log_max_level = level;
+        log_max_level[realm] = level;
 }
 
 void log_set_facility(int facility) {
@@ -337,11 +351,9 @@ static int write_to_console(
                 const char *file,
                 int line,
                 const char *func,
-                const char *object_field,
-                const char *object,
                 const char *buffer) {
 
-        char location[64], prefix[1 + DECIMAL_STR_MAX(int) + 2];
+        char location[256], prefix[1 + DECIMAL_STR_MAX(int) + 2];
         struct iovec iovec[6] = {};
         unsigned n = 0;
         bool highlight;
@@ -350,14 +362,14 @@ static int write_to_console(
                 return 0;
 
         if (log_target == LOG_TARGET_CONSOLE_PREFIXED) {
-                sprintf(prefix, "<%i>", level);
+                xsprintf(prefix, "<%i>", level);
                 IOVEC_SET_STRING(iovec[n++], prefix);
         }
 
         highlight = LOG_PRI(level) <= LOG_ERR && show_color;
 
         if (show_location) {
-                xsprintf(location, "(%s:%i) ", file, line);
+                snprintf(location, sizeof(location), "(%s:%i) ", file, line);
                 IOVEC_SET_STRING(iovec[n++], location);
         }
 
@@ -397,8 +409,6 @@ static int write_to_syslog(
                 const char *file,
                 int line,
                 const char *func,
-                const char *object_field,
-                const char *object,
                 const char *buffer) {
 
         char header_priority[2 + DECIMAL_STR_MAX(int) + 1],
@@ -460,8 +470,6 @@ static int write_to_kmsg(
                 const char *file,
                 int line,
                 const char *func,
-                const char *object_field,
-                const char *object,
                 const char *buffer) {
 
         char header_priority[2 + DECIMAL_STR_MAX(int) + 1],
@@ -493,7 +501,8 @@ static int log_do_header(
                 int level,
                 int error,
                 const char *file, int line, const char *func,
-                const char *object_field, const char *object) {
+                const char *object_field, const char *object,
+                const char *extra_field, const char *extra) {
 
         snprintf(header, size,
                  "PRIORITY=%i\n"
@@ -503,6 +512,7 @@ static int log_do_header(
                  "%s%s%s"
                  "%s%.*i%s"
                  "%s%s%s"
+                 "%s%s%s"
                  "SYSLOG_IDENTIFIER=%s\n",
                  LOG_PRI(level),
                  LOG_FAC(level),
@@ -512,7 +522,7 @@ static int log_do_header(
                  line ? "CODE_LINE=" : "",
                  line ? 1 : 0, line, /* %.0d means no output too, special case for 0 */
                  line ? "\n" : "",
-                 isempty(func) ? "" : "CODE_FUNCTION=",
+                 isempty(func) ? "" : "CODE_FUNC=",
                  isempty(func) ? "" : func,
                  isempty(func) ? "" : "\n",
                  error ? "ERRNO=" : "",
@@ -521,6 +531,9 @@ static int log_do_header(
                  isempty(object) ? "" : object_field,
                  isempty(object) ? "" : object,
                  isempty(object) ? "" : "\n",
+                 isempty(extra) ? "" : extra_field,
+                 isempty(extra) ? "" : extra,
+                 isempty(extra) ? "" : "\n",
                  program_invocation_short_name);
 
         return 0;
@@ -534,6 +547,8 @@ static int write_to_journal(
                 const char *func,
                 const char *object_field,
                 const char *object,
+                const char *extra_field,
+                const char *extra,
                 const char *buffer) {
 
         char header[LINE_MAX];
@@ -543,7 +558,7 @@ static int write_to_journal(
         if (journal_fd < 0)
                 return 0;
 
-        log_do_header(header, sizeof(header), level, error, file, line, func, object_field, object);
+        log_do_header(header, sizeof(header), level, error, file, line, func, object_field, object, extra_field, extra);
 
         IOVEC_SET_STRING(iovec[0], header);
         IOVEC_SET_STRING(iovec[1], "MESSAGE=");
@@ -560,7 +575,7 @@ static int write_to_journal(
 }
 #endif // 0
 
-static int log_dispatch(
+int log_dispatch_internal(
                 int level,
                 int error,
                 const char *file,
@@ -568,10 +583,15 @@ static int log_dispatch(
                 const char *func,
                 const char *object_field,
                 const char *object,
+                const char *extra,
+                const char *extra_field,
                 char *buffer) {
 
         assert(buffer);
 
+        if (error < 0)
+                error = -error;
+
         if (log_target == LOG_TARGET_NULL)
                 return -error;
 
@@ -579,9 +599,6 @@ static int log_dispatch(
         if ((level & LOG_FACMASK) == 0)
                 level = log_facility | LOG_PRI(level);
 
-        if (error < 0)
-                error = -error;
-
         do {
                 char *e;
                 int k = 0;
@@ -595,11 +612,11 @@ static int log_dispatch(
                         *(e++) = 0;
 
 #if 0 /// elogind does not support logging to systemd-journald
-                if (log_target == LOG_TARGET_AUTO ||
-                    log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
-                    log_target == LOG_TARGET_JOURNAL) {
+                if (IN_SET(log_target, LOG_TARGET_AUTO,
+                                       LOG_TARGET_JOURNAL_OR_KMSG,
+                                       LOG_TARGET_JOURNAL)) {
 
-                        k = write_to_journal(level, error, file, line, func, object_field, object, buffer);
+                        k = write_to_journal(level, error, file, line, func, object_field, object, extra_field, extra, buffer);
                         if (k < 0) {
                                 if (k != -EAGAIN)
                                         log_close_journal();
@@ -608,10 +625,10 @@ static int log_dispatch(
                 }
 #endif // 0
 
-                if (log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
-                    log_target == LOG_TARGET_SYSLOG) {
+                if (IN_SET(log_target, LOG_TARGET_SYSLOG_OR_KMSG,
+                                       LOG_TARGET_SYSLOG)) {
 
-                        k = write_to_syslog(level, error, file, line, func, object_field, object, buffer);
+                        k = write_to_syslog(level, error, file, line, func, buffer);
                         if (k < 0) {
                                 if (k != -EAGAIN)
                                         log_close_syslog();
@@ -620,13 +637,13 @@ static int log_dispatch(
                 }
 
                 if (k <= 0 &&
-                    (log_target == LOG_TARGET_AUTO ||
-                     log_target == LOG_TARGET_SAFE ||
-                     log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
-                     /// UNNEEDED by elogind log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
-                     log_target == LOG_TARGET_KMSG)) {
+                    IN_SET(log_target, LOG_TARGET_AUTO,
+                                       LOG_TARGET_SAFE,
+                                       LOG_TARGET_SYSLOG_OR_KMSG,
+                                       LOG_TARGET_JOURNAL_OR_KMSG,
+                                       LOG_TARGET_KMSG)) {
 
-                        k = write_to_kmsg(level, error, file, line, func, object_field, object, buffer);
+                        k = write_to_kmsg(level, error, file, line, func, buffer);
                         if (k < 0) {
                                 log_close_kmsg();
                                 log_open_console();
@@ -634,7 +651,7 @@ static int log_dispatch(
                 }
 
                 if (k <= 0)
-                        (void) write_to_console(level, error, file, line, func, object_field, object, buffer);
+                        (void) write_to_console(level, error, file, line, func, buffer);
 
                 buffer = e;
         } while (buffer);
@@ -643,13 +660,14 @@ static int log_dispatch(
 }
 
 int log_dump_internal(
-        int level,
-        int error,
-        const char *file,
-        int line,
-        const char *func,
-        char *buffer) {
+                int level,
+                int error,
+                const char *file,
+                int line,
+                const char *func,
+                char *buffer) {
 
+        LogRealm realm = LOG_REALM_REMOVE_LEVEL(level);
         PROTECT_ERRNO;
 
         /* This modifies the buffer... */
@@ -657,13 +675,13 @@ int log_dump_internal(
         if (error < 0)
                 error = -error;
 
-        if (_likely_(LOG_PRI(level) > log_max_level))
+        if (_likely_(LOG_PRI(level) > log_max_level[realm]))
                 return -error;
 
-        return log_dispatch(level, error, file, line, func, NULL, NULL, buffer);
+        return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buffer);
 }
 
-int log_internalv(
+int log_internalv_realm(
                 int level,
                 int error,
                 const char *file,
@@ -672,13 +690,14 @@ int log_internalv(
                 const char *format,
                 va_list ap) {
 
-        PROTECT_ERRNO;
+        LogRealm realm = LOG_REALM_REMOVE_LEVEL(level);
         char buffer[LINE_MAX];
+        PROTECT_ERRNO;
 
         if (error < 0)
                 error = -error;
 
-        if (_likely_(LOG_PRI(level) > log_max_level))
+        if (_likely_(LOG_PRI(level) > log_max_level[realm]))
                 return -error;
 
         /* Make sure that %m maps to the specified error */
@@ -687,10 +706,10 @@ int log_internalv(
 
         vsnprintf(buffer, sizeof(buffer), format, ap);
 
-        return log_dispatch(level, error, file, line, func, NULL, NULL, buffer);
+        return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buffer);
 }
 
-int log_internal(
+int log_internal_realm(
                 int level,
                 int error,
                 const char *file,
@@ -702,7 +721,7 @@ int log_internal(
         int r;
 
         va_start(ap, format);
-        r = log_internalv(level, error, file, line, func, format, ap);
+        r = log_internalv_realm(level, error, file, line, func, format, ap);
         va_end(ap);
 
         return r;
@@ -716,17 +735,18 @@ int log_object_internalv(
                 const char *func,
                 const char *object_field,
                 const char *object,
+                const char *extra_field,
+                const char *extra,
                 const char *format,
                 va_list ap) {
 
         PROTECT_ERRNO;
         char *buffer, *b;
-        size_t l;
 
         if (error < 0)
                 error = -error;
 
-        if (_likely_(LOG_PRI(level) > log_max_level))
+        if (_likely_(LOG_PRI(level) > log_max_level[LOG_REALM_SYSTEMD]))
                 return -error;
 
         /* Make sure that %m maps to the specified error */
@@ -738,18 +758,15 @@ int log_object_internalv(
                 size_t n;
 
                 n = strlen(object);
-                l = n + 2 + LINE_MAX;
-
-                buffer = newa(char, l);
+                buffer = newa(char, n + 2 + LINE_MAX);
                 b = stpcpy(stpcpy(buffer, object), ": ");
-        } else {
-                l = LINE_MAX;
-                b = buffer = newa(char, l);
-        }
+        } else
+                b = buffer = newa(char, LINE_MAX);
 
-        vsnprintf(b, l, format, ap);
+        vsnprintf(b, LINE_MAX, format, ap);
 
-        return log_dispatch(level, error, file, line, func, object_field, object, buffer);
+        return log_dispatch_internal(level, error, file, line, func,
+                                     object_field, object, extra_field, extra, buffer);
 }
 
 int log_object_internal(
@@ -760,13 +777,15 @@ int log_object_internal(
                 const char *func,
                 const char *object_field,
                 const char *object,
+                const char *extra_field,
+                const char *extra,
                 const char *format, ...) {
 
         va_list ap;
         int r;
 
         va_start(ap, format);
-        r = log_object_internalv(level, error, file, line, func, object_field, object, format, ap);
+        r = log_object_internalv(level, error, file, line, func, object_field, object, extra_field, extra, format, ap);
         va_end(ap);
 
         return r;
@@ -781,36 +800,56 @@ static void log_assert(
                 const char *format) {
 
         static char buffer[LINE_MAX];
+        LogRealm realm = LOG_REALM_REMOVE_LEVEL(level);
 
-        if (_likely_(LOG_PRI(level) > log_max_level))
+        if (_likely_(LOG_PRI(level) > log_max_level[realm]))
                 return;
 
         DISABLE_WARNING_FORMAT_NONLITERAL;
-        xsprintf(buffer, format, text, file, line, func);
+        snprintf(buffer, sizeof buffer, format, text, file, line, func);
         REENABLE_WARNING;
 
         log_abort_msg = buffer;
 
-        log_dispatch(level, 0, file, line, func, NULL, NULL, buffer);
+        log_dispatch_internal(level, 0, file, line, func, NULL, NULL, NULL, NULL, buffer);
 }
 
-noreturn void log_assert_failed(const char *text, const char *file, int line, const char *func) {
-        log_assert(LOG_CRIT, text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Aborting.");
+noreturn void log_assert_failed_realm(
+                LogRealm realm,
+                const char *text,
+                const char *file,
+                int line,
+                const char *func) {
+        log_assert(LOG_REALM_PLUS_LEVEL(realm, LOG_CRIT), text, file, line, func,
+                   "Assertion '%s' failed at %s:%u, function %s(). Aborting.");
         abort();
 }
 
-noreturn void log_assert_failed_unreachable(const char *text, const char *file, int line, const char *func) {
-        log_assert(LOG_CRIT, text, file, line, func, "Code should not be reached '%s' at %s:%u, function %s(). Aborting.");
+noreturn void log_assert_failed_unreachable_realm(
+                LogRealm realm,
+                const char *text,
+                const char *file,
+                int line,
+                const char *func) {
+        log_assert(LOG_REALM_PLUS_LEVEL(realm, LOG_CRIT), text, file, line, func,
+                   "Code should not be reached '%s' at %s:%u, function %s(). Aborting.");
         abort();
 }
 
-void log_assert_failed_return(const char *text, const char *file, int line, const char *func) {
+void log_assert_failed_return_realm(
+                LogRealm realm,
+                const char *text,
+                const char *file,
+                int line,
+                const char *func) {
         PROTECT_ERRNO;
-        log_assert(LOG_DEBUG, text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Ignoring.");
+        log_assert(LOG_REALM_PLUS_LEVEL(realm, LOG_DEBUG), text, file, line, func,
+                   "Assertion '%s' failed at %s:%u, function %s(). Ignoring.");
 }
 
-int log_oom_internal(const char *file, int line, const char *func) {
-        log_internal(LOG_ERR, ENOMEM, file, line, func, "Out of memory.");
+int log_oom_internal(LogRealm realm, const char *file, int line, const char *func) {
+        log_internal_realm(LOG_REALM_PLUS_LEVEL(realm, LOG_ERR),
+                           ENOMEM, file, line, func, "Out of memory.");
         return -ENOMEM;
 }
 
@@ -870,13 +909,14 @@ int log_struct_internal(
 
         char buf[LINE_MAX];
         bool found = false;
+        LogRealm realm = LOG_REALM_REMOVE_LEVEL(level);
         PROTECT_ERRNO;
         va_list ap;
 
         if (error < 0)
                 error = -error;
 
-        if (_likely_(LOG_PRI(level) > log_max_level))
+        if (_likely_(LOG_PRI(level) > log_max_level[realm]))
                 return -error;
 
         if (log_target == LOG_TARGET_NULL)
@@ -886,9 +926,9 @@ int log_struct_internal(
                 level = log_facility | LOG_PRI(level);
 
 #if 0 /// elogind does not support logging to systemd-journald
-        if ((log_target == LOG_TARGET_AUTO ||
-             log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
-             log_target == LOG_TARGET_JOURNAL) &&
+        if (IN_SET(log_target, LOG_TARGET_AUTO,
+                               LOG_TARGET_JOURNAL_OR_KMSG,
+                               LOG_TARGET_JOURNAL) &&
             journal_fd >= 0) {
                 char header[LINE_MAX];
                 struct iovec iovec[17] = {};
@@ -900,7 +940,7 @@ int log_struct_internal(
                 bool fallback = false;
 
                 /* If the journal is available do structured logging */
-                log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL);
+                log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL, NULL, NULL);
                 IOVEC_SET_STRING(iovec[n++], header);
 
                 va_start(ap, format);
@@ -948,7 +988,7 @@ int log_struct_internal(
         if (!found)
                 return -error;
 
-        return log_dispatch(level, error, file, line, func, NULL, NULL, buf + 8);
+        return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buf + 8);
 }
 
 int log_set_target_from_string(const char *e) {
@@ -962,18 +1002,18 @@ int log_set_target_from_string(const char *e) {
         return 0;
 }
 
-int log_set_max_level_from_string(const char *e) {
+int log_set_max_level_from_string_realm(LogRealm realm, const char *e) {
         int t;
 
         t = log_level_from_string(e);
         if (t < 0)
                 return -EINVAL;
 
-        log_set_max_level(t);
+        log_set_max_level_realm(realm, t);
         return 0;
 }
 
-static int parse_proc_cmdline_item(const char *key, const char *value) {
+static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
 
         /*
          * The systemd.log_xyz= settings are parsed by all tools, and
@@ -987,52 +1027,59 @@ static int parse_proc_cmdline_item(const char *key, const char *value) {
         if (streq(key, "debug") && !value)
                 log_set_max_level(LOG_DEBUG);
 
-        else if (streq(key, "systemd.log_target") && value) {
+        else if (proc_cmdline_key_streq(key, "systemd.log_target")) {
+
+                if (proc_cmdline_value_missing(key, value))
+                        return 0;
 
                 if (log_set_target_from_string(value) < 0)
                         log_warning("Failed to parse log target '%s'. Ignoring.", value);
 
-        } else if (streq(key, "systemd.log_level") && value) {
+        } else if (proc_cmdline_key_streq(key, "systemd.log_level")) {
+
+                if (proc_cmdline_value_missing(key, value))
+                        return 0;
 
                 if (log_set_max_level_from_string(value) < 0)
                         log_warning("Failed to parse log level '%s'. Ignoring.", value);
 
-        } else if (streq(key, "systemd.log_color") && value) {
+        } else if (proc_cmdline_key_streq(key, "systemd.log_color")) {
 
-                if (log_show_color_from_string(value) < 0)
+                if (log_show_color_from_string(value ?: "1") < 0)
                         log_warning("Failed to parse log color setting '%s'. Ignoring.", value);
 
-        } else if (streq(key, "systemd.log_location") && value) {
+        } else if (proc_cmdline_key_streq(key, "systemd.log_location")) {
 
-                if (log_show_location_from_string(value) < 0)
+                if (log_show_location_from_string(value ?: "1") < 0)
                         log_warning("Failed to parse log location setting '%s'. Ignoring.", value);
         }
 
         return 0;
 }
 
-void log_parse_environment(void) {
+void log_parse_environment_realm(LogRealm realm) {
+        /* Do not call from library code. */
+
         const char *e;
 
         if (get_ctty_devnr(0, NULL) < 0)
-                /* Only try to read the command line in daemons.
-                   We assume that anything that has a controlling
-                   tty is user stuff. */
-                (void) parse_proc_cmdline(parse_proc_cmdline_item);
+                /* Only try to read the command line in daemons.  We assume that anything that has a controlling tty is
+                   user stuff. */
+                (void) proc_cmdline_parse(parse_proc_cmdline_item, NULL, PROC_CMDLINE_STRIP_RD_PREFIX);
 
-        e = secure_getenv("SYSTEMD_LOG_TARGET");
+        e = getenv("SYSTEMD_LOG_TARGET");
         if (e && log_set_target_from_string(e) < 0)
                 log_warning("Failed to parse log target '%s'. Ignoring.", e);
 
-        e = secure_getenv("SYSTEMD_LOG_LEVEL");
-        if (e && log_set_max_level_from_string(e) < 0)
+        e = getenv("SYSTEMD_LOG_LEVEL");
+        if (e && log_set_max_level_from_string_realm(realm, e) < 0)
                 log_warning("Failed to parse log level '%s'. Ignoring.", e);
 
-        e = secure_getenv("SYSTEMD_LOG_COLOR");
+        e = getenv("SYSTEMD_LOG_COLOR");
         if (e && log_show_color_from_string(e) < 0)
                 log_warning("Failed to parse bool '%s'. Ignoring.", e);
 
-        e = secure_getenv("SYSTEMD_LOG_LOCATION");
+        e = getenv("SYSTEMD_LOG_LOCATION");
         if (e && log_show_location_from_string(e) < 0)
                 log_warning("Failed to parse bool '%s'. Ignoring.", e);
 }
@@ -1041,8 +1088,8 @@ LogTarget log_get_target(void) {
         return log_target;
 }
 
-int log_get_max_level(void) {
-        return log_max_level;
+int log_get_max_level_realm(LogRealm realm) {
+        return log_max_level[realm];
 }
 
 void log_show_color(bool b) {
@@ -1084,8 +1131,8 @@ int log_show_location_from_string(const char *e) {
 }
 
 bool log_on_console(void) {
-        if (log_target == LOG_TARGET_CONSOLE ||
-            log_target == LOG_TARGET_CONSOLE_PREFIXED)
+        if (IN_SET(log_target, LOG_TARGET_CONSOLE,
+                               LOG_TARGET_CONSOLE_PREFIXED))
                 return true;
 
         return syslog_fd < 0 && kmsg_fd < 0 && journal_fd < 0;
@@ -1144,13 +1191,13 @@ int log_syntax_internal(
 
         PROTECT_ERRNO;
         char buffer[LINE_MAX];
-        int r;
         va_list ap;
+        const char *unit_fmt = NULL;
 
         if (error < 0)
                 error = -error;
 
-        if (_likely_(LOG_PRI(level) > log_max_level))
+        if (_likely_(LOG_PRI(level) > log_max_level[LOG_REALM_SYSTEMD]))
                 return -error;
 
         if (log_target == LOG_TARGET_NULL)
@@ -1164,24 +1211,22 @@ int log_syntax_internal(
         va_end(ap);
 
         if (unit)
-                r = log_struct_internal(
-                                level, error,
-                                file, line, func,
-                                getpid() == 1 ? "UNIT=%s" : "USER_UNIT=%s", unit,
-                                LOG_MESSAGE_ID(SD_MESSAGE_INVALID_CONFIGURATION),
-                                "CONFIG_FILE=%s", config_file,
-                                "CONFIG_LINE=%u", config_line,
-                                LOG_MESSAGE("[%s:%u] %s", config_file, config_line, buffer),
-                                NULL);
-        else
-                r = log_struct_internal(
-                                level, error,
-                                file, line, func,
-                                LOG_MESSAGE_ID(SD_MESSAGE_INVALID_CONFIGURATION),
-                                "CONFIG_FILE=%s", config_file,
-                                "CONFIG_LINE=%u", config_line,
-                                LOG_MESSAGE("[%s:%u] %s", config_file, config_line, buffer),
-                                NULL);
+                unit_fmt = getpid() == 1 ? "UNIT=%s" : "USER_UNIT=%s";
+
+        return log_struct_internal(
+                        LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, level),
+                        error,
+                        file, line, func,
+                        "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
+                        "CONFIG_FILE=%s", config_file,
+                        "CONFIG_LINE=%u", config_line,
+                        LOG_MESSAGE("%s:%u: %s", config_file, config_line, buffer),
+                        unit_fmt, unit,
+                        NULL);
+}
 
-        return r;
+#if 0 /// UNNEEDED by elogind
+void log_set_always_reopen_console(bool b) {
+        always_reopen_console = b;
 }
+#endif // 0