chiark / gitweb /
log: unify log env var prefix
[elogind.git] / src / log.c
index 5d17955e7ebbd9ddb25a933b8faebac4192bb9fe..a47285cb2129130e463ed822767ac1fa501d3088 100644 (file)
--- a/src/log.c
+++ b/src/log.c
 #define LOG_BUFFER_MAX 1024
 
 static LogTarget log_target = LOG_TARGET_CONSOLE;
-static int log_max_level = LOG_DEBUG;
+static int log_max_level = LOG_INFO;
 
 static int console_fd = STDERR_FILENO;
 static int syslog_fd = -1;
 static int kmsg_fd = -1;
 
+static bool show_color = false;
+static bool show_location = false;
+
 /* Akin to glibc's __abort_msg; which is private and we hance cannot
  * use here. */
 static char *log_abort_msg = NULL;
@@ -50,8 +53,10 @@ void log_close_console(void) {
         if (console_fd < 0)
                 return;
 
-        if (getpid() == 1 || console_fd != STDERR_FILENO) {
-                close_nointr_nofail(console_fd);
+        if (getpid() == 1) {
+                if (console_fd >= 3)
+                        close_nointr_nofail(console_fd);
+
                 console_fd = -1;
         }
 }
@@ -160,6 +165,12 @@ int log_open(void) {
          * the fs. If we don't use /dev/kmsg we still keep it open,
          * because there is no reason to close it. */
 
+        if (log_target == LOG_TARGET_NULL) {
+                log_close_syslog();
+                log_close_console();
+                return 0;
+        }
+
         if (log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
             log_target == LOG_TARGET_SYSLOG)
                 if ((r = log_open_syslog()) >= 0) {
@@ -210,10 +221,11 @@ static int write_to_console(
         snprintf(location, sizeof(location), "(%s:%u) ", file, line);
         char_array_0(location);
 
-        highlight = LOG_PRI(level) <= LOG_ERR;
+        highlight = LOG_PRI(level) <= LOG_ERR && show_color;
 
         zero(iovec);
-        IOVEC_SET_STRING(iovec[n++], location);
+        if (show_location)
+                IOVEC_SET_STRING(iovec[n++], location);
         if (highlight)
                 IOVEC_SET_STRING(iovec[n++], "\x1B[1;31m");
         IOVEC_SET_STRING(iovec[n++], buffer);
@@ -253,13 +265,13 @@ static int write_to_syslog(
         if (strftime(header_time, sizeof(header_time), "%h %e %T ", tm) <= 0)
                 return -EINVAL;
 
-        snprintf(header_pid, sizeof(header_pid), "[%llu]: ", (unsigned long long) getpid());
+        snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) getpid());
         char_array_0(header_pid);
 
         zero(iovec);
         IOVEC_SET_STRING(iovec[0], header_priority);
         IOVEC_SET_STRING(iovec[1], header_time);
-        IOVEC_SET_STRING(iovec[2], __progname);
+        IOVEC_SET_STRING(iovec[2], program_invocation_short_name);
         IOVEC_SET_STRING(iovec[3], header_pid);
         IOVEC_SET_STRING(iovec[4], buffer);
 
@@ -289,12 +301,12 @@ static int write_to_kmsg(
         snprintf(header_priority, sizeof(header_priority), "<%i>", LOG_PRI(level));
         char_array_0(header_priority);
 
-        snprintf(header_pid, sizeof(header_pid), "[%llu]: ", (unsigned long long) getpid());
+        snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) getpid());
         char_array_0(header_pid);
 
         zero(iovec);
         IOVEC_SET_STRING(iovec[0], header_priority);
-        IOVEC_SET_STRING(iovec[1], __progname);
+        IOVEC_SET_STRING(iovec[1], program_invocation_short_name);
         IOVEC_SET_STRING(iovec[2], header_pid);
         IOVEC_SET_STRING(iovec[3], buffer);
         IOVEC_SET_STRING(iovec[4], "\n");
@@ -310,31 +322,73 @@ static int log_dispatch(
         const char*file,
         int line,
         const char *func,
-        const char *buffer) {
+        char *buffer) {
 
-        int r;
+        int r = 0;
 
-        if (log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
-            log_target == LOG_TARGET_SYSLOG) {
+        if (log_target == LOG_TARGET_NULL)
+                return 0;
 
-                if ((r = write_to_syslog(level, file, line, func, buffer)) < 0) {
-                        log_close_syslog();
-                        log_open_kmsg();
-                } else if (r > 0)
-                        return r;
-        }
+        do {
+                char *e;
+                int k;
 
-        if (log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
-            log_target == LOG_TARGET_KMSG) {
+                buffer += strspn(buffer, NEWLINE);
 
-                if ((r = write_to_kmsg(level, file, line, func, buffer)) < 0) {
-                        log_close_kmsg();
-                        log_open_console();
-                } else if (r > 0)
-                        return r;
-        }
+                if (buffer[0] == 0)
+                        break;
+
+                if ((e = strpbrk(buffer, NEWLINE)))
+                        *(e++) = 0;
+
+                if (log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
+                    log_target == LOG_TARGET_SYSLOG) {
+
+                        if ((r = write_to_syslog(level, file, line, func, buffer)) < 0) {
+                                log_close_syslog();
+                                log_open_kmsg();
+                        } else if (r > 0)
+                                r++;
+                }
+
+                if (log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
+                    log_target == LOG_TARGET_KMSG) {
+
+                        if ((r = write_to_kmsg(level, file, line, func, buffer)) < 0) {
+                                log_close_kmsg();
+                                log_open_console();
+                        } else if (r > 0)
+                                r++;
+                }
+
+                if ((k = write_to_console(level, file, line, func, buffer)) < 0)
+                        return k;
+
+                buffer = e;
+        } while (buffer);
+
+        return r;
+}
+
+int log_dump_internal(
+        int level,
+        const char*file,
+        int line,
+        const char *func,
+        char *buffer) {
+
+        int saved_errno, r;
+
+        /* This modifies the buffer... */
+
+        if (_likely_(LOG_PRI(level) > log_max_level))
+                return 0;
+
+        saved_errno = errno;
+        r = log_dispatch(level, file, line, func, buffer);
+        errno = saved_errno;
 
-        return write_to_console(level, file, line, func, buffer);
+        return r;
 }
 
 int log_meta(
@@ -348,7 +402,7 @@ int log_meta(
         int saved_errno, r;
         va_list ap;
 
-        if (_likely(LOG_PRI(level) > log_max_level))
+        if (_likely_(LOG_PRI(level) > log_max_level))
                 return 0;
 
         saved_errno = errno;
@@ -419,6 +473,15 @@ void log_parse_environment(void) {
         if ((e = getenv("SYSTEMD_LOG_LEVEL")))
                 if (log_set_max_level_from_string(e) < 0)
                         log_warning("Failed to parse log level %s. Ignoring.", e);
+
+        if ((e = getenv("SYSTEMD_LOG_COLOR")))
+                if (log_show_color_from_string(e) < 0)
+                        log_warning("Failed to parse bool %s. Ignoring.", e);
+
+        if ((e = getenv("SYSTEMD_LOG_LOCATION"))) {
+                if (log_show_location_from_string(e) < 0)
+                        log_warning("Failed to parse bool %s. Ignoring.", e);
+        }
 }
 
 LogTarget log_get_target(void) {
@@ -429,11 +492,40 @@ int log_get_max_level(void) {
         return log_max_level;
 }
 
+void log_show_color(bool b) {
+        show_color = b;
+}
+
+void log_show_location(bool b) {
+        show_location = b;
+}
+
+int log_show_color_from_string(const char *e) {
+        int t;
+
+        if ((t = parse_boolean(e)) < 0)
+                return -EINVAL;
+
+        log_show_color(t);
+        return 0;
+}
+
+int log_show_location_from_string(const char *e) {
+        int t;
+
+        if ((t = parse_boolean(e)) < 0)
+                return -EINVAL;
+
+        log_show_location(t);
+        return 0;
+}
+
 static const char *const log_target_table[] = {
         [LOG_TARGET_CONSOLE] = "console",
         [LOG_TARGET_SYSLOG] = "syslog",
         [LOG_TARGET_KMSG] = "kmsg",
         [LOG_TARGET_SYSLOG_OR_KMSG] = "syslog-or-kmsg",
+        [LOG_TARGET_NULL] = "null"
 };
 
 DEFINE_STRING_TABLE_LOOKUP(log_target, LogTarget);