Add the ability to direct logs etc. to a file or pipe.

This commit is contained in:
Mike Brady
2020-05-28 12:19:59 +01:00
parent 6406c296f5
commit c0e5d0473e
4 changed files with 72 additions and 3 deletions
+63
View File
@@ -41,6 +41,7 @@
#include <time.h>
#include <unistd.h>
#include <fcntl.h>
#include <libgen.h>
#ifdef COMPILE_FOR_OSX
#include <CoreServices/CoreServices.h>
@@ -139,8 +140,70 @@ void do_sps_log_to_stdout(__attribute__((unused)) int prio, const char *t, ...)
fprintf(stdout, "%s\n", s);
}
int create_log_file(const char* path) {
int fd = -1;
if (path != NULL) {
char *dirc = strdup(path);
if (dirc) {
char *dname = dirname(dirc);
// create the directory, if necessary
int result = 0;
if (dname) {
char *pdir = realpath(dname, NULL); // will return a NULL if the directory doesn't exist
if (pdir == NULL) {
mode_t oldumask = umask(000);
result = mkpath(dname, 0777);
umask(oldumask);
} else {
free(pdir);
}
if ((result == 0) || (result == -EEXIST)) {
// now open the file
fd = open(path, O_WRONLY | O_NONBLOCK | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if ((fd == -1) && (errno == EEXIST))
fd = open(path, O_WRONLY | O_APPEND | O_NONBLOCK);
if (fd >= 0) {
// now we switch to blocking mode
int flags = fcntl(fd, F_GETFL);
if ((flags == -1)) {
// strerror_r(errno, (char *)errorstring, sizeof(errorstring));
// debug(1, "create_log_file -- error %d (\"%s\") getting flags of pipe: \"%s\".", errno,
// (char *)errorstring, pathname);
} else {
flags = fcntl(fd, F_SETFL,flags & ~O_NONBLOCK);
// if (flags == -1) {
// strerror_r(errno, (char *)errorstring, sizeof(errorstring));
// debug(1, "create_log_file -- error %d (\"%s\") unsetting NONBLOCK of pipe: \"%s\".", errno,
// (char *)errorstring, pathname);
}
}
}
}
free(dirc);
}
}
return fd;
}
void do_sps_log_to_fd(__attribute__((unused)) int prio, const char *t, ...) {
char s[1024];
va_list args;
va_start(args, t);
vsnprintf(s, sizeof(s), t, args);
va_end(args);
if (config.log_fd == -1)
config.log_fd = create_log_file(config.log_file_path);
if (config.log_fd >= 0) {
dprintf(config.log_fd, "%s\n", s);
} else if (errno != ENXIO) { // maybe there is a pipe there but not hooked up
fprintf(stderr, "%s\n", s);
}
}
void log_to_stderr() { sps_log = do_sps_log_to_stderr; }
void log_to_stdout() { sps_log = do_sps_log_to_stdout; }
void log_to_file() { sps_log = do_sps_log_to_fd; }
void log_to_syslog() {
#ifdef CONFIG_LIBDAEMON
sps_log = daemon_log;
+4
View File
@@ -182,6 +182,8 @@ typedef struct {
char *pidfile;
#endif
int log_fd; // file descriptor of the file or pipe to log stuff to.
char *log_file_path; // path to file or pipe to log to, if any
int logOutputLevel; // log output level
int debugger_show_elapsed_time; // in the debug message, display the time since startup
int debugger_show_relative_time; // in the debug message, display the time since the last one
@@ -298,6 +300,8 @@ void memory_barrier();
void log_to_stderr(); // call this to direct logging to stderr;
void log_to_stdout(); // call this to direct logging to stdout;
void log_to_syslog(); // call this to direct logging to the system log;
void log_to_file(); // call this to direct logging to a file or (pre-existing) pipe;
// true if Shairport Sync is supposed to be sending output to the output device, false otherwise
+1 -1
View File
@@ -245,7 +245,7 @@ mqtt =
diagnostics =
{
// disable_resend_requests = "no"; // set this to yes to stop Shairport Sync from requesting the retransmission of missing packets. Default is "no".
// log_output_to = "syslog"; // set this to "syslog" (default), "STDERR" or "STDOUT" to specify were all logs, statistics and diagnostic messages are written to.
// log_output_to = "syslog"; // set this to "syslog" (default), "stderr" or "stdout" or a file or pipe path to specify were all logs, statistics and diagnostic messages are written to. If there's anything wrong with the file spec, output will be to "stderr".
// statistics = "no"; // set to "yes" to print statistics in the log
// log_verbosity = 0; // "0" means no debug verbosity, "3" is most verbose.
// log_show_file_and_line = "yes"; // set this to yes if you want the file and line number of the message source in the log file
+4 -2
View File
@@ -671,8 +671,9 @@ int parse_options(int argc, char **argv) {
} else if (strcasecmp(str, "stderr") == 0) {
log_to_stderr();
} else {
log_to_syslog();
die("Invalid diagnostics log_output_to setting \"%s\". It should be \"syslog\", \"STDERR\" or \"STDOUT\". It is set to syslog.");
config.log_file_path = (char *)str;
config.log_fd = -1;
log_to_file();
}
}
/* Get the ignore_volume_control setting. */
@@ -1423,6 +1424,7 @@ int main(int argc, char **argv) {
#ifdef CONFIG_LIBDAEMON
pid = getpid();
#endif
config.log_fd = -1;
conns = NULL; // no connections active
memset((void *)&main_thread_id, 0, sizeof(main_thread_id));
memset(&config, 0, sizeof(config)); // also clears all strings, BTW