diff --git a/core/AmConfig.cpp b/core/AmConfig.cpp index 806708f5..5d7a3bfe 100644 --- a/core/AmConfig.cpp +++ b/core/AmConfig.cpp @@ -156,6 +156,11 @@ int AmConfig::readConfiguration() // take values from global configuration file // they will be overwritten by command line args + + if (cfg.hasParameter("syslog_facility")) { + set_log_facility(cfg.getParameter("syslog_facility").c_str()); + } + // plugin_config_path ModConfigPath = cfg.getParameter("plugin_config_path",ModConfigPath); diff --git a/core/etc/sems.conf.sample b/core/etc/sems.conf.sample index d56371bc..8a4a4625 100644 --- a/core/etc/sems.conf.sample +++ b/core/etc/sems.conf.sample @@ -37,6 +37,18 @@ stderr=no # (same as -D) loglevel=2 +# optional parameter: syslog_facility={DAEMON|USER|LOCAL[0-7]} +# +# - sets the log facility that is used for syslog. Using this, +# the log can for example be filtered into a special file +# by the syslog daemon. +# +# Default: DAEMON +# +# Example: +# syslog_facility=LOCAL0 + + # optional parameter: application # # This config value controls which application is to be diff --git a/core/log.cpp b/core/log.cpp index 088e36e4..02f978a4 100644 --- a/core/log.cpp +++ b/core/log.cpp @@ -37,6 +37,10 @@ int log_level=L_INFO; int log_stderr=0; + +/* log facility (see syslog(3)) */ +int log_facility=LOG_DAEMON; + vector log_hooks; @@ -53,10 +57,42 @@ inline const char* level2txt(int level) void init_log() { - openlog(LOG_NAME, LOG_PID|LOG_CONS,L_FAC); + openlog(LOG_NAME, LOG_PID|LOG_CONS,log_facility); setlogmask( -1 ); } +void set_log_facility(const char* facility) { + int new_facility = -1; + if (!strcmp(facility, "DAEMON")){ + new_facility = LOG_DAEMON; + } else if (!strcmp(facility, "USER")) { + new_facility = LOG_USER; + } else if (strlen(facility)==6 && + !strncmp(facility, "LOCAL", 5) && + facility[5]-'0' < 8) { + switch (facility[5]) { + case '0': new_facility = LOG_LOCAL0; break; + case '1': new_facility = LOG_LOCAL1; break; + case '2': new_facility = LOG_LOCAL2; break; + case '3': new_facility = LOG_LOCAL3; break; + case '4': new_facility = LOG_LOCAL4; break; + case '5': new_facility = LOG_LOCAL5; break; + case '6': new_facility = LOG_LOCAL6; break; + case '7': new_facility = LOG_LOCAL7; break; + } + } else { + ERROR("unknown syslog facility '%s'\n", + facility); + return; + } + + if (new_facility != log_facility) { + log_facility = new_facility; + closelog(); + init_log(); + } +} + void dprint(int level, const char* fct, char* file, int line, char* fmt, ...) { va_list ap; diff --git a/core/log.h b/core/log.h index 348c920a..c02e0176 100644 --- a/core/log.h +++ b/core/log.h @@ -39,8 +39,6 @@ extern "C" { #define L_INFO 2 #define L_DBG 3 - /* log facility (see syslog(3)) */ -#define L_FAC LOG_DAEMON /* priority at which we log */ #define DPRINT_PRIO LOG_DEBUG @@ -49,7 +47,10 @@ extern "C" { extern int log_level; extern int log_stderr; + extern int log_facility; + void init_log(); + void set_log_facility(const char* facility); void dprint (int level, const char* fct, char* file, int line, char* fmt, ...); void log_print (int level, char* fmt, ...); @@ -74,16 +75,16 @@ extern "C" { else {\ switch(level){\ case L_ERR:\ - syslog(LOG_ERR | L_FAC, "Error: (%s)(%s)(%i): " fmt, __FILE__, __FUNCTION__, __LINE__, ##args);\ + syslog(LOG_ERR, "Error: (%s)(%s)(%i): " fmt, __FILE__, __FUNCTION__, __LINE__, ##args);\ break;\ case L_WARN:\ - syslog(LOG_WARNING | L_FAC, "Warning: (%s)(%s)(%i): " fmt, __FILE__, __FUNCTION__, __LINE__, ##args);\ + syslog(LOG_WARNING, "Warning: (%s)(%s)(%i): " fmt, __FILE__, __FUNCTION__, __LINE__, ##args);\ break;\ case L_INFO:\ - syslog(LOG_INFO | L_FAC, "Info: (%s)(%s)(%i): " fmt, __FILE__, __FUNCTION__, __LINE__, ##args);\ + syslog(LOG_INFO, "Info: (%s)(%s)(%i): " fmt, __FILE__, __FUNCTION__, __LINE__, ##args);\ break;\ case L_DBG:\ - syslog(LOG_DEBUG | L_FAC, "Debug: (%s)(%s)(%i): " fmt, __FILE__, __FUNCTION__, __LINE__, ##args);\ + syslog(LOG_DEBUG, "Debug: (%s)(%s)(%i): " fmt, __FILE__, __FUNCTION__, __LINE__, ##args);\ break;\ }\ }\