[pulseaudio-discuss] [PATCH 1/2] Log feature: Add a new log target to a file descriptor

Vincent Becker vincentx.becker at intel.com
Fri Mar 18 03:23:46 PDT 2011


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
---
 src/daemon/cmdline.c     |    5 +++--
 src/daemon/daemon-conf.c |   23 +++++++++++++++++++++++
 src/pulsecore/log.c      |   25 +++++++++++++++++++++++++
 src/pulsecore/log.h      |    5 +++++
 4 files changed, 56 insertions(+), 2 deletions(-)

diff --git a/src/daemon/cmdline.c b/src/daemon/cmdline.c
index f6cdcdc..caa5b2b 100644
--- a/src/daemon/cmdline.c
+++ b/src/daemon/cmdline.c
@@ -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,\n"
+           "                    file:PATH}          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;
diff --git a/src/daemon/daemon-conf.c b/src/daemon/daemon-conf.c
index e38e67a..0d42f73 100644
--- a/src/daemon/daemon-conf.c
+++ b/src/daemon/daemon-conf.c
@@ -28,6 +28,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
+#include <fcntl.h>
 
 #ifdef HAVE_SCHED_H
 #include <sched.h>
@@ -141,6 +142,8 @@ static const pa_daemon_conf default_conf = {
 #endif
 };
 
+static int log_fd = -1;
+
 pa_daemon_conf* pa_daemon_conf_new(void) {
     pa_daemon_conf *c;
 
@@ -166,6 +169,10 @@ pa_daemon_conf* pa_daemon_conf_new(void) {
 
 void pa_daemon_conf_free(pa_daemon_conf *c) {
     pa_assert(c);
+
+    if (log_fd >= 0)
+        pa_close(log_fd);
+
     pa_xfree(c->script_commands);
     pa_xfree(c->dl_search_path);
     pa_xfree(c->default_script_file);
@@ -211,6 +218,22 @@ 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];
+
+        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;
 
diff --git a/src/pulsecore/log.c b/src/pulsecore/log.c
index 2c0e267..1494906 100644
--- a/src/pulsecore/log.c
+++ b/src/pulsecore/log.c
@@ -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,12 @@ void pa_log_set_flags(pa_log_flags_t _flags, pa_log_merge_t merge) {
         flags = _flags;
 }
 
+void pa_log_set_fd(int fd) {
+    pa_assert(fd >= 0);
+
+    log_fd = fd;
+}
+
 void pa_log_set_show_backtrace(unsigned nlevels) {
     show_backtrace = nlevels;
 }
@@ -399,6 +406,24 @@ void pa_log_levelv_meta(
             }
 #endif
 
+            case PA_LOG_FD: {
+                if (log_fd != -1) {
+                    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_close(log_fd);
+                        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);
+                        log_fd = -1;
+                    }
+                }
+
+                break;
+            }
             case PA_LOG_NULL:
             default:
                 break;
diff --git a/src/pulsecore/log.h b/src/pulsecore/log.h
index 1fd38d4..ad04e7b 100644
--- a/src/pulsecore/log.h
+++ b/src/pulsecore/log.h
@@ -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);
 
-- 
1.7.2.3

---------------------------------------------------------------------
Intel Corporation SAS (French simplified joint stock company)
Registered headquarters: "Les Montalets"- 2, rue de Paris, 
92196 Meudon Cedex, France
Registration Number:  302 456 199 R.C.S. NANTERRE
Capital: 4,572,000 Euros

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.




More information about the pulseaudio-discuss mailing list