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 Signed-off-by: Vincent Becker <vincentx.becker at intel.com> --- src/daemon/cmdline.c | 5 +++-- src/daemon/daemon-conf.c | 34 ++++++++++++++++++++++++++++++++-- src/pulsecore/log.c | 24 ++++++++++++++++++++++++ src/pulsecore/log.h | 5 +++++ 4 files changed, 64 insertions(+), 4 deletions(-) diff --git a/src/daemon/cmdline.c b/src/daemon/cmdline.c index f6cdcdc..2c3eb67 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', '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..5696f00 100644 --- a/src/daemon/daemon-conf.c +++ b/src/daemon/daemon-conf.c @@ -28,6 +28,8 @@ #include <stdio.h> #include <string.h> #include <unistd.h> +#include <sys/stat.h> +#include <fcntl.h> #ifdef HAVE_SCHED_H #include <sched.h> @@ -141,6 +143,9 @@ 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 +171,9 @@ 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); @@ -185,8 +193,30 @@ int pa_daemon_conf_set_log_target(pa_daemon_conf *c, const char *string) { } else if (!strcmp(string, "stderr")) { c->auto_log_target = 0; c->log_target = PA_LOG_STDERR; - } else - return -1; + } else if (pa_startswith(string, "file:")) { + char *file_path; + const char *state = NULL; + unsigned i; + + /* After second pa_split call, file_path will contain the right part of file:<path> */ + for (i = 0; i < 2; i++) + file_path = pa_split(string, ":", &state); + + /* Check if the file is regular */ + if ((log_fd = open(file_path, O_RDWR|O_TRUNC|O_CREAT, 0777)) >= 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)); + pa_xfree(file_path); + return -1; + } + pa_xfree(file_path); + } + else + return -1; return 0; } diff --git a/src/pulsecore/log.c b/src/pulsecore/log.c index 2c0e267..a5e26c8 100644 --- a/src/pulsecore/log.c +++ b/src/pulsecore/log.c @@ -71,6 +71,8 @@ static unsigned show_backtrace = 0, show_backtrace_override = 0, skip_backtrace static pa_log_flags_t flags = 0, flags_override = 0; static pa_bool_t no_rate_limit = FALSE; +static int fdlog = -1; + #ifdef HAVE_SYSLOG_H static const int level_to_syslog[] = { [PA_LOG_ERROR] = LOG_ERR, @@ -128,6 +130,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); + + fdlog = fd; +} + void pa_log_set_show_backtrace(unsigned nlevels) { show_backtrace = nlevels; } @@ -399,6 +407,22 @@ void pa_log_levelv_meta( } #endif + case PA_LOG_FD: { + if (fdlog != -1) { + char metadata[256]; + + pa_snprintf(metadata, sizeof(metadata), "\n%c %s%s", level_to_char[level], timestamp, location); + + if ((write(fdlog, metadata, strlen(metadata)) < 0) || (write(fdlog, t, strlen(t)) < 0)) { + saved_errno = errno; + pa_close(fdlog); + fdlog = -1; + } + } + + break; + } + case PA_LOG_NULL: default: break; diff --git a/src/pulsecore/log.h b/src/pulsecore/log.h index 1fd38d4..bfe245c 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. of a char device */ PA_LOG_TARGET_MAX } pa_log_target_t; @@ -80,6 +81,10 @@ void pa_log_set_show_backtrace(unsigned nlevels); /* Skip the first backtrace frames */ void pa_log_set_skip_backtrace(unsigned nlevels); +/* Set the file descriptor of the logging device. + Daemon conf is in charge of opening this device */ +void pa_log_set_fd(int fd); + void pa_log_level_meta( pa_log_level_t level, const char*file, -- 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.