]> code.delx.au - pulseaudio/commitdiff
log: Add a new log target to a file descriptor
authorVincent Becker <vincentx.becker@intel.com>
Fri, 18 Mar 2011 10:23:46 +0000 (11:23 +0100)
committerColin Guthrie <cguthrie@mandriva.org>
Fri, 18 Mar 2011 12:32:51 +0000 (12:32 +0000)
This patch enables logging of text debug messages (pa_log feature) into a file or a device driver.
Example : pulseaudio --log-target=file:./mylog.txt

(Minor tweaks by Colin + Arun)

src/daemon/cmdline.c
src/daemon/daemon-conf.c
src/pulsecore/log.c
src/pulsecore/log.h

index f6cdcdc836458512dfd123fbf70269f66b723b69..4854affcabc2621b848d1fd0df4a20b17c68a2f1 100644 (file)
@@ -145,7 +145,8 @@ void pa_cmdline_help(const char *argv0) {
            "                                        this time passed\n"
            "      --log-level[=LEVEL]               Increase or set verbosity level\n"
            "  -v                                    Increase the verbosity level\n"
-           "      --log-target={auto,syslog,stderr} Specify the log target\n"
+           "      --log-target={auto,syslog,stderr,file:PATH}\n"
+           "                                        Specify the log target\n"
            "      --log-meta[=BOOL]                 Include code location in log messages\n"
            "      --log-time[=BOOL]                 Include timestamps in log messages\n"
            "      --log-backtrace=FRAMES            Include a backtrace in log messages\n"
@@ -318,7 +319,7 @@ int pa_cmdline_parse(pa_daemon_conf *conf, int argc, char *const argv [], int *d
 
             case ARG_LOG_TARGET:
                 if (pa_daemon_conf_set_log_target(conf, optarg) < 0) {
-                    pa_log(_("Invalid log target: use either 'syslog', 'stderr' or 'auto'."));
+                    pa_log(_("Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file name 'file:<path>'."));
                     goto fail;
                 }
                 break;
index e38e67ad48fdfa097638de2fcd8068a5222f0ae3..ce93dbc6ea5226ca43104ee90cbb5be1a0504bfd 100644 (file)
@@ -28,6 +28,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
+#include <fcntl.h>
 
 #ifdef HAVE_SCHED_H
 #include <sched.h>
@@ -166,6 +167,9 @@ pa_daemon_conf* pa_daemon_conf_new(void) {
 
 void pa_daemon_conf_free(pa_daemon_conf *c) {
     pa_assert(c);
+
+    pa_log_set_fd(-1);
+
     pa_xfree(c->script_commands);
     pa_xfree(c->dl_search_path);
     pa_xfree(c->default_script_file);
@@ -211,6 +215,23 @@ int pa_daemon_conf_set_log_level(pa_daemon_conf *c, const char *string) {
         c->log_level = PA_LOG_WARN;
     else if (pa_startswith(string, "err"))
         c->log_level = PA_LOG_ERROR;
+    else if (pa_startswith(string, "file:")) {
+        char file_path[512];
+        int log_fd;
+
+        pa_strlcpy(file_path, string + 5, sizeof(file_path));
+
+        /* Open target file with user rights */
+        if ((log_fd = open(file_path, O_RDWR|O_TRUNC|O_CREAT, S_IRWXU)) >= 0) {
+             c->auto_log_target = 0;
+             c->log_target = PA_LOG_FD;
+             pa_log_set_fd(log_fd);
+        }
+        else {
+            printf("Failed to open target file %s, error : %s\n", file_path, pa_cstrerror(errno));
+            return -1;
+        }
+    }
     else
         return -1;
 
index 2c0e267a37d12833e23e4574e7fc952c422145eb..b12cbf0c9c563bff80937c6bc0cef5fd06f63f96 100644 (file)
@@ -70,6 +70,7 @@ static pa_log_level_t maximum_level = PA_LOG_ERROR, maximum_level_override = PA_
 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 int log_fd = -1;
 
 #ifdef HAVE_SYSLOG_H
 static const int level_to_syslog[] = {
@@ -128,6 +129,15 @@ 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;
 }
@@ -399,6 +409,23 @@ void pa_log_levelv_meta(
             }
 #endif
 
+            case PA_LOG_FD: {
+                if (log_fd >= 0) {
+                    char metadata[256];
+
+                    pa_snprintf(metadata, sizeof(metadata), "\n%c %s %s", level_to_char[level], timestamp, location);
+
+                    if ((write(log_fd, metadata, strlen(metadata)) < 0) || (write(log_fd, t, strlen(t)) < 0)) {
+                        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(PA_LOG_STDERR);
+                    }
+                }
+
+                break;
+            }
             case PA_LOG_NULL:
             default:
                 break;
index 1fd38d44427dc156780097730d237e697935b145..ad04e7bd661fb034fdd30847fe10a200c175d9db 100644 (file)
@@ -36,6 +36,7 @@ typedef enum pa_log_target {
     PA_LOG_STDERR,  /* default */
     PA_LOG_SYSLOG,
     PA_LOG_NULL,    /* to /dev/null */
+    PA_LOG_FD,      /* to a file descriptor, e.g. a char device */
     PA_LOG_TARGET_MAX
 } pa_log_target_t;
 
@@ -74,6 +75,10 @@ void pa_log_set_level(pa_log_level_t l);
 /* Set flags */
 void pa_log_set_flags(pa_log_flags_t flags, pa_log_merge_t merge);
 
+/* Set the file descriptor of the logging device.
+   Daemon conf is in charge of opening this device */
+void pa_log_set_fd(int fd);
+
 /* Enable backtrace */
 void pa_log_set_show_backtrace(unsigned nlevels);