]> code.delx.au - pulseaudio/blobdiff - src/pulsecore/log.c
remap: Change remapping function argument type from void to int16_t / float as approp...
[pulseaudio] / src / pulsecore / log.c
index 8066ca5a1fff58b652f192a304399948e40dd6dd..cf96dcef1a6721118bcd6793c3cc76be6bfbf41a 100644 (file)
@@ -30,6 +30,7 @@
 #include <string.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <sys/stat.h>
 
 #ifdef HAVE_EXECINFO_H
 #include <execinfo.h>
 #include <syslog.h>
 #endif
 
+#ifdef HAVE_JOURNAL
+#include <systemd/sd-journal.h>
+#endif
+
 #include <pulse/gccmacro.h>
 #include <pulse/rtclock.h>
 #include <pulse/utf8.h>
 static char *ident = NULL; /* in local charset format */
 static pa_log_target target = { PA_LOG_STDERR, NULL };
 static pa_log_target_type_t target_override;
-static pa_bool_t target_override_set = FALSE;
+static bool target_override_set = false;
 static pa_log_level_t maximum_level = PA_LOG_ERROR, maximum_level_override = PA_LOG_ERROR;
 static unsigned show_backtrace = 0, show_backtrace_override = 0, skip_backtrace = 0;
 static pa_log_flags_t flags = 0, flags_override = 0;
-static pa_bool_t no_rate_limit = FALSE;
+static bool no_rate_limit = false;
 static int log_fd = -1;
+static int write_type = 0;
 
 #ifdef HAVE_SYSLOG_H
 static const int level_to_syslog[] = {
@@ -88,6 +94,18 @@ static const int level_to_syslog[] = {
 };
 #endif
 
+/* These are actually equivalent to the syslog ones
+ * but we don't want to depend on syslog.h */
+#ifdef HAVE_JOURNAL
+static const int level_to_journal[] = {
+    [PA_LOG_ERROR]  = 3,
+    [PA_LOG_WARN]   = 4,
+    [PA_LOG_NOTICE] = 5,
+    [PA_LOG_INFO]   = 6,
+    [PA_LOG_DEBUG]  = 7
+};
+#endif
+
 static const char level_to_char[] = {
     [PA_LOG_ERROR] = 'E',
     [PA_LOG_WARN] = 'W',
@@ -127,6 +145,9 @@ int pa_log_set_target(pa_log_target *t) {
     switch (t->type) {
         case PA_LOG_STDERR:
         case PA_LOG_SYSLOG:
+#ifdef HAVE_JOURNAL
+        case PA_LOG_JOURNAL:
+#endif
         case PA_LOG_NULL:
             break;
         case PA_LOG_FILE:
@@ -190,15 +211,6 @@ void pa_log_set_flags(pa_log_flags_t _flags, pa_log_merge_t merge) {
         flags = _flags;
 }
 
-void pa_log_set_fd(int fd) {
-    if (fd >= 0)
-        log_fd = fd;
-    else if (log_fd >= 0) {
-        pa_close(log_fd);
-        log_fd = -1;
-    }
-}
-
 void pa_log_set_show_backtrace(unsigned nlevels) {
     show_backtrace = nlevels;
 }
@@ -280,7 +292,7 @@ static void init_defaults(void) {
 
         if (getenv(ENV_LOG_SYSLOG)) {
             target_override = PA_LOG_SYSLOG;
-            target_override_set = TRUE;
+            target_override_set = true;
         }
 
         if ((e = getenv(ENV_LOG_LEVEL))) {
@@ -320,11 +332,25 @@ static void init_defaults(void) {
         }
 
         if (getenv(ENV_LOG_NO_RATELIMIT))
-            no_rate_limit = TRUE;
+            no_rate_limit = true;
 
     } PA_ONCE_END;
 }
 
+#ifdef HAVE_SYSLOG_H
+static void log_syslog(pa_log_level_t level, char *t, char *timestamp, char *location, char *bt) {
+    char *local_t;
+
+    openlog(ident, LOG_PID, LOG_USER);
+
+    if ((local_t = pa_utf8_to_locale(t)))
+        t = local_t;
+
+    syslog(level_to_syslog[level], "%s%s%s%s", timestamp, location, t, pa_strempty(bt));
+    pa_xfree(local_t);
+}
+#endif
+
 void pa_log_levelv_meta(
         pa_log_level_t level,
         const char*file,
@@ -363,9 +389,11 @@ void pa_log_levelv_meta(
     pa_vsnprintf(text, sizeof(text), format, ap);
 
     if ((_flags & PA_LOG_PRINT_META) && file && line > 0 && func)
-        pa_snprintf(location, sizeof(location), "[%s][%s:%i %s()] ", pa_thread_get_name(pa_thread_self()), file, line, func);
+        pa_snprintf(location, sizeof(location), "[%s][%s:%i %s()] ",
+                    pa_strnull(pa_thread_get_name(pa_thread_self())), file, line, func);
     else if ((_flags & (PA_LOG_PRINT_META|PA_LOG_PRINT_FILE)) && file)
-        pa_snprintf(location, sizeof(location), "[%s] %s: ", pa_thread_get_name(pa_thread_self()), pa_path_get_filename(file));
+        pa_snprintf(location, sizeof(location), "[%s] %s: ",
+                    pa_strnull(pa_thread_get_name(pa_thread_self())), pa_path_get_filename(file));
     else
         location[0] = 0;
 
@@ -455,38 +483,66 @@ void pa_log_levelv_meta(
             }
 
 #ifdef HAVE_SYSLOG_H
-            case PA_LOG_SYSLOG: {
-                char *local_t;
-
-                openlog(ident, LOG_PID, LOG_USER);
+            case PA_LOG_SYSLOG:
+                log_syslog(level, t, timestamp, location, bt);
+                break;
+#endif
 
-                if ((local_t = pa_utf8_to_locale(t)))
-                    t = local_t;
+#ifdef HAVE_JOURNAL
+            case PA_LOG_JOURNAL:
+                if (sd_journal_send("MESSAGE=%s", t,
+                                "PRIORITY=%i", level_to_journal[level],
+                                "CODE_FILE=%s", file,
+                                "CODE_FUNC=%s", func,
+                                "CODE_LINE=%d", line,
+                                NULL) < 0) {
+#ifdef HAVE_SYSLOG_H
+                    pa_log_target new_target = { .type = PA_LOG_SYSLOG, .file = NULL };
 
-                syslog(level_to_syslog[level], "%s%s%s%s", timestamp, location, t, pa_strempty(bt));
-                pa_xfree(local_t);
+                    syslog(level_to_syslog[PA_LOG_ERROR], "%s%s%s", timestamp, __FILE__,
+                           "Error writing logs to the journal. Redirect log messages to syslog.");
+                    log_syslog(level, t, timestamp, location, bt);
+#else
+                    pa_log_target new_target = { .type = PA_LOG_STDERR, .file = NULL };
 
+                    saved_errno = errno;
+                    fprintf(stderr, "%s\n", "Error writing logs to the journal. Redirect log messages to console.");
+                    fprintf(stderr, "%s %s\n", metadata, t);
+#endif
+                    pa_log_set_target(&new_target);
+                }
                 break;
-            }
 #endif
 
             case PA_LOG_FILE:
             case PA_LOG_NEWFILE: {
+                char *local_t;
+
+                if ((local_t = pa_utf8_to_locale(t)))
+                    t = local_t;
+
                 if (log_fd >= 0) {
                     char metadata[256];
 
-                    pa_snprintf(metadata, sizeof(metadata), "\n%c %s %s", level_to_char[level], timestamp, location);
+                    if (_flags & PA_LOG_PRINT_LEVEL)
+                        pa_snprintf(metadata, sizeof(metadata), "%s%c: %s", timestamp, level_to_char[level], location);
+                    else
+                        pa_snprintf(metadata, sizeof(metadata), "%s%s", timestamp, location);
 
-                    if ((write(log_fd, metadata, strlen(metadata)) < 0) || (write(log_fd, t, strlen(t)) < 0)) {
+                    if ((pa_write(log_fd, metadata, strlen(metadata), &write_type) < 0)
+                            || (pa_write(log_fd, t, strlen(t), &write_type) < 0)
+                            || (bt && pa_write(log_fd, bt, strlen(bt), &write_type) < 0)
+                            || (pa_write(log_fd, "\n", 1, &write_type) < 0)) {
                         pa_log_target new_target = { .type = PA_LOG_STDERR, .file = NULL };
                         saved_errno = errno;
-                        pa_log_set_fd(-1);
                         fprintf(stderr, "%s\n", "Error writing logs to a file descriptor. Redirect log messages to console.");
                         fprintf(stderr, "%s %s\n", metadata, t);
                         pa_log_set_target(&new_target);
                     }
                 }
 
+                pa_xfree(local_t);
+
                 break;
             }
             case PA_LOG_NULL:
@@ -524,14 +580,14 @@ void pa_log_level(pa_log_level_t level, const char *format, ...) {
     va_end(ap);
 }
 
-pa_bool_t pa_log_ratelimit(pa_log_level_t level) {
+bool pa_log_ratelimit(pa_log_level_t level) {
     /* Not more than 10 messages every 5s */
     static PA_DEFINE_RATELIMIT(ratelimit, 5 * PA_USEC_PER_SEC, 10);
 
     init_defaults();
 
     if (no_rate_limit)
-        return TRUE;
+        return true;
 
     return pa_ratelimit_test(&ratelimit, level);
 }
@@ -563,6 +619,10 @@ pa_log_target *pa_log_parse_target(const char *string) {
         t = pa_log_target_new(PA_LOG_STDERR, NULL);
     else if (pa_streq(string, "syslog"))
         t = pa_log_target_new(PA_LOG_SYSLOG, NULL);
+#ifdef HAVE_JOURNAL
+    else if (pa_streq(string, "journal"))
+        t = pa_log_target_new(PA_LOG_JOURNAL, NULL);
+#endif
     else if (pa_streq(string, "null"))
         t = pa_log_target_new(PA_LOG_NULL, NULL);
     else if (pa_startswith(string, "file:"))
@@ -587,6 +647,11 @@ char *pa_log_target_to_string(const pa_log_target *t) {
         case PA_LOG_SYSLOG:
             string = pa_xstrdup("syslog");
             break;
+#ifdef HAVE_JOURNAL
+        case PA_LOG_JOURNAL:
+            string = pa_xstrdup("journal");
+            break;
+#endif
         case PA_LOG_NULL:
             string = pa_xstrdup("null");
             break;