log: support syslog()

Allow logging to syslog if log_file is configured to "syslog".
This commit is contained in:
Max Kellermann 2008-12-28 19:48:53 +01:00
parent c6cb611065
commit c01aa53e6a
5 changed files with 124 additions and 6 deletions

1
NEWS
View File

@ -6,6 +6,7 @@ ver 0.15 - (200?/??/??)
* Add RVA2 tag support
* the option "error_file" was removed, all messages are logged into
"log_file"
* support logging to syslog
ver 0.14 (2008/12/25)
* audio outputs:

View File

@ -54,6 +54,21 @@ if test -z "$prefix" || test "x$prefix" = xNONE; then
fi
dnl
dnl libc features
dnl
AC_CHECK_FUNCS(syslog)
if test $ac_cv_func_syslog = no; then
# syslog is not in the default libraries. See if it's in some other.
for lib in bsd socket inet; do
AC_CHECK_LIB($lib, syslog,
[AC_DEFINE(HAVE_SYSLOG)
LIBS="$LIBS -l$lib"; break])
done
fi
dnl
dnl build options
dnl

View File

@ -51,6 +51,7 @@ This specifies where the db file will be stored.
.TP
.B log_file <file>
This specifies where the log file should be located.
The special value "syslog" makes MPD use the local syslog daemon.
.SH OPTIONAL PARAMETERS
.TP
.B pid_file <file>

View File

@ -25,6 +25,10 @@ db_file "~/.mpd/database"
# These logs are great for troubleshooting, depending on your log_level
# settings.
#
# The special value "syslog" makes MPD use the local syslog daemon.
# On most systems, log messages will appear in /var/log/daemon.log
# then.
#
log_file "~/.mpd/log"
###############################################################################

109
src/log.c
View File

@ -18,6 +18,8 @@
#include "log.h"
#include "conf.h"
#include "utils.h"
#include "config.h"
#include <assert.h>
#include <sys/types.h>
@ -33,6 +35,10 @@
#include <pthread.h>
#include <glib.h>
#ifdef HAVE_SYSLOG
#include <syslog.h>
#endif
#define LOG_LEVEL_SECURE G_LOG_LEVEL_INFO
#define LOG_DATE_BUF_SIZE 16
@ -119,6 +125,68 @@ log_init_file(const char *path, unsigned line)
g_log_set_default_handler(file_log_func, NULL);
}
#ifdef HAVE_SYSLOG
static int
glib_to_syslog_level(GLogLevelFlags log_level)
{
switch (log_level & G_LOG_LEVEL_MASK) {
case G_LOG_LEVEL_ERROR:
case G_LOG_LEVEL_CRITICAL:
return LOG_ERR;
case G_LOG_LEVEL_WARNING:
return LOG_WARNING;
case G_LOG_LEVEL_MESSAGE:
return LOG_NOTICE;
case G_LOG_LEVEL_INFO:
return LOG_INFO;
case G_LOG_LEVEL_DEBUG:
return LOG_DEBUG;
default:
return LOG_NOTICE;
}
}
static void
syslog_log_func(const gchar *log_domain,
GLogLevelFlags log_level, const gchar *message,
G_GNUC_UNUSED gpointer user_data)
{
if (stdout_mode) {
/* fall back to the file log function during
startup */
file_log_func(log_domain, log_level,
message, user_data);
return;
}
if (log_level > log_threshold)
return;
if (log_domain == NULL)
log_domain = "";
syslog(glib_to_syslog_level(log_level), "%s%s%s",
log_domain, *log_domain == 0 ? "" : ": ",
message);
}
static void
log_init_syslog(void)
{
assert(out_filename == NULL);
openlog(PACKAGE, 0, LOG_DAEMON);
g_log_set_default_handler(syslog_log_func, NULL);
}
#endif
static inline GLogLevelFlags
parse_log_level(const char *value, unsigned line)
{
@ -147,8 +215,31 @@ void log_init(bool verbose, bool use_stdout)
if (use_stdout) {
log_init_stdout();
} else {
param = parseConfigFilePath(CONF_LOG_FILE, 1);
log_init_file(param->value, param->line);
param = getConfigParam(CONF_LOG_FILE);
if (param == NULL) {
#ifdef HAVE_SYSLOG
/* no configuration: default to syslog (if
available) */
log_init_syslog();
#else
FATAL("config parameter \"%s\" not found\n",
CONF_LOG_FILE);
#endif
#ifdef HAVE_SYSLOG
} else if (strcmp(param->value, "syslog") == 0) {
log_init_syslog();
#endif
} else {
char *path = parsePath(param->value);
g_free(param->value);
if (path == NULL)
FATAL("error parsing \"%s\" at line %i\n",
CONF_LOG_FILE, param->line);
param->value = path;
log_init_file(param->value, param->line);
}
}
}
@ -156,7 +247,8 @@ void setup_log_output(bool use_stdout)
{
fflush(NULL);
if (!use_stdout) {
redirect_logs();
if (out_filename != NULL)
redirect_logs();
stdout_mode = false;
log_charset = NULL;
}
@ -192,7 +284,7 @@ G_GNUC_PRINTF(1, 2) G_GNUC_NORETURN void FATAL(const char *fmt, ...)
int cycle_log_files(void)
{
if (stdout_mode)
if (stdout_mode || out_filename == NULL)
return 0;
assert(out_filename);
@ -214,7 +306,12 @@ void close_log_files(void)
{
if (stdout_mode)
return;
assert(out_fd >= 0);
close(out_fd);
if (out_filename == NULL)
closelog();
else {
assert(out_fd >= 0);
close(out_fd);
}
}