diff --git a/daemon/call.c b/daemon/call.c index de580e4ce..76866f077 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -1094,7 +1094,9 @@ retry: for (i = 0; i < 100; i++) close(i); - openlog("rtpengine/child", LOG_PID | LOG_NDELAY, LOG_DAEMON); + if (!_log_stderr) { + openlog("rtpengine/child", LOG_PID | LOG_NDELAY, LOG_DAEMON); + } ilog(LOG_INFO, "Initiating XMLRPC call for tag "STR_FORMAT"", STR_FMT(tag)); alarm(5); diff --git a/daemon/log.c b/daemon/log.c index e3c2691cd..396fd65f9 100644 --- a/daemon/log.c +++ b/daemon/log.c @@ -19,7 +19,65 @@ volatile gint log_level = LOG_DEBUG; #define MAX_LOG_LINE_LENGTH 500 #endif +write_log_t write_log = (write_log_t) syslog; + +const _fac_code_t _facilitynames[] = + { + { "auth", LOG_AUTH }, + { "authpriv", LOG_AUTHPRIV }, + { "cron", LOG_CRON }, + { "daemon", LOG_DAEMON }, + { "ftp", LOG_FTP }, + { "kern", LOG_KERN }, + { "lpr", LOG_LPR }, + { "mail", LOG_MAIL }, + { "news", LOG_NEWS }, + { "syslog", LOG_SYSLOG }, + { "user", LOG_USER }, + { "uucp", LOG_UUCP }, + { "local0", LOG_LOCAL0 }, + { "local1", LOG_LOCAL1 }, + { "local2", LOG_LOCAL2 }, + { "local3", LOG_LOCAL3 }, + { "local4", LOG_LOCAL4 }, + { "local5", LOG_LOCAL5 }, + { "local6", LOG_LOCAL6 }, + { "local7", LOG_LOCAL7 }, + { NULL, -1 } + }; + +const char const* prio_str[] = { + "EMERG", + "ALERT", + "CRIT", + "ERR", + "WARNING", + "NOTICE", + "INFO", + "DEBUG" + }; + +gboolean _log_stderr = 0; +int _log_facility = LOG_DAEMON; + +void log_to_stderr(int facility_priority, char *format, ...) { + char *msg; + int ret; + va_list ap; + + va_start(ap, format); + ret = vasprintf(&msg, format, ap); + va_end(ap); + + if (ret < 0) { + fprintf(stderr,"ERR: Failed to print log message - message dropped\n"); + return; + } + + fprintf(stderr, "%s: %s\n", prio_str[facility_priority & LOG_PRIMASK], msg); + free(msg); +} void ilog(int prio, const char *fmt, ...) { char prefix[256]; @@ -60,20 +118,20 @@ void ilog(int prio, const char *fmt, ...) { va_end(ap); if (ret < 0) { - syslog(LOG_ERROR, "Failed to print syslog message - message dropped"); + write_log(LOG_ERROR, "Failed to print syslog message - message dropped"); return; } piece = msg; while (ret > MAX_LOG_LINE_LENGTH) { - syslog(xprio, "%s%s%.*s ...", prefix, infix, MAX_LOG_LINE_LENGTH, piece); + write_log(xprio, "%s%s%.*s ...", prefix, infix, MAX_LOG_LINE_LENGTH, piece); ret -= MAX_LOG_LINE_LENGTH; piece += MAX_LOG_LINE_LENGTH; infix = "... "; } - syslog(xprio, "%s%s%s", prefix, infix, piece); + write_log(xprio, "%s%s%s", prefix, infix, piece); free(msg); } diff --git a/daemon/log.h b/daemon/log.h index fa6db2e1d..79c142e29 100644 --- a/daemon/log.h +++ b/daemon/log.h @@ -20,8 +20,21 @@ struct log_info { } e; }; +extern gboolean _log_stderr; +extern int _log_facility; +typedef struct _fac_code { + char *c_name; + int c_val; +} _fac_code_t; + +extern const _fac_code_t _facilitynames[]; + +typedef void (* write_log_t) (int facility_priority, char *format, ...) __attribute__ ((format (printf, 2, 3))); +extern write_log_t write_log; + +void log_to_stderr(int facility_priority, char *format, ...) __attribute__ ((format (printf, 2, 3))); extern struct log_info __thread log_info; extern volatile gint log_level; diff --git a/daemon/main.c b/daemon/main.c index b1120b0ad..6ae831362 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -232,6 +232,26 @@ fail: return -1; } +static int parse_log_facility(char *name, int *dst) { + int i; + for (i = 0 ; _facilitynames[i].c_name; i++) { + if (strcmp(_facilitynames[i].c_name, name) == 0) { + *dst = _facilitynames[i].c_val; + return 1; + } + } + return 0; +} + +static void print_available_log_facilities () { + int i; + + fprintf(stderr, "available facilities:"); + for (i = 0 ; _facilitynames[i].c_name; i++) { + fprintf(stderr, " %s", _facilitynames[i].c_name); + } + fprintf(stderr, "\n"); +} static void options(int *argc, char ***argv) { @@ -243,6 +263,7 @@ static void options(int *argc, char ***argv) { char *listenudps = NULL; char *listenngs = NULL; char *redisps = NULL; + char *log_facility_s = NULL; int version = 0; GOptionEntry e[] = { @@ -267,6 +288,8 @@ static void options(int *argc, char ***argv) { { "redis-db", 'R', 0, G_OPTION_ARG_INT, &redis_db, "Which Redis DB to use", "INT" }, { "b2b-url", 'b', 0, G_OPTION_ARG_STRING, &b2b_url, "XMLRPC URL of B2B UA" , "STRING" }, { "log-level", 'L', 0, G_OPTION_ARG_INT, (void *)&log_level, "Mask log priorities above this level", "INT" }, + { "log-facility", 0, 0, G_OPTION_ARG_STRING, &log_facility_s, "Syslog facility to use for logging", "daemon|local0|...|local7"}, + { "log-stderr", 'E', 0, G_OPTION_ARG_NONE, &_log_stderr, "Log on stderr instead of syslog", NULL }, { "xmlrpc-format", 'x', 0, G_OPTION_ARG_INT, &xmlrpc_fmt, "XMLRPC timeout request format to use. 0: SEMS DI, 1: call-id only", "INT" }, { NULL, } }; @@ -341,6 +364,17 @@ static void options(int *argc, char ***argv) { if ((log_level < LOG_EMERG) || (log_level > LOG_DEBUG)) die("Invalid log level (--log_level)\n"); setlogmask(LOG_UPTO(log_level)); + + if (log_facility_s) { + if (!parse_log_facility(log_facility_s, &_log_facility)) { + print_available_log_facilities(); + die ("Invalid log facility '%s' (--log-facility)\n", log_facility_s); + } + } + + if (_log_stderr) { + write_log = log_to_stderr; + } } @@ -378,7 +412,8 @@ static void init_everything() { #if !GLIB_CHECK_VERSION(2,32,0) g_thread_init(NULL); #endif - openlog("rtpengine", LOG_PID | LOG_NDELAY, LOG_DAEMON); + if (!_log_stderr) + openlog("rtpengine", LOG_PID | LOG_NDELAY, _log_facility); signals(); resources(); sdp_init(); @@ -556,8 +591,8 @@ static void poller_loop(void *d) { int main(int argc, char **argv) { struct main_context ctx; - init_everything(); options(&argc, &argv); + init_everything(); create_everything(&ctx); ilog(LOG_INFO, "Startup complete, version %s", RTPENGINE_VERSION); diff --git a/debian/ngcp-rtpengine-daemon.default b/debian/ngcp-rtpengine-daemon.default index ed554e141..72a36ce9b 100644 --- a/debian/ngcp-rtpengine-daemon.default +++ b/debian/ngcp-rtpengine-daemon.default @@ -19,3 +19,4 @@ TABLE=0 # REDIS_DB=1 # B2B_URL=http://127.0.0.1:8090/ # LOG_LEVEL=6 +# LOG_FACILITY=daemon diff --git a/debian/ngcp-rtpengine-daemon.init b/debian/ngcp-rtpengine-daemon.init index 13f8b78ca..423fc0e34 100755 --- a/debian/ngcp-rtpengine-daemon.init +++ b/debian/ngcp-rtpengine-daemon.init @@ -63,6 +63,7 @@ OPTIONS="" [ -z "$NO_FALLBACK" -o \( "$NO_FALLBACK" != "1" -a "$NO_FALLBACK" != "yes" \) ] || OPTIONS="$OPTIONS --no-fallback" OPTIONS="$OPTIONS --table=$TABLE" [ -z "$LOG_LEVEL" ] || OPTIONS="$OPTIONS --log-level=$LOG_LEVEL" +[ -z "$LOG_FACILITY" ] || OPTIONS="$OPTIONS --log-facility=$LOG_FACILITY" if test "$FORK" = "no" ; then OPTIONS="$OPTIONS --foreground" fi diff --git a/el/rtpengine.init b/el/rtpengine.init index ef6418b7d..4b6f3e756 100644 --- a/el/rtpengine.init +++ b/el/rtpengine.init @@ -136,6 +136,11 @@ build_opts() { then OPTS+=" --log-level=$LOG_LEVEL" fi + + if [[ -n "$LOG_FACILITY" ]] + then + OPTS+=" --log-facility=$LOG_FACILITY" + fi } start() { diff --git a/el/rtpengine.sysconfig b/el/rtpengine.sysconfig index 00c500e5b..eee9846cf 100644 --- a/el/rtpengine.sysconfig +++ b/el/rtpengine.sysconfig @@ -33,6 +33,8 @@ LISTEN_UDP=127.0.0.1:2222 # IP address and port combination for UDP # traffic. Default: 40000 # #LOG_LEVEL=6 # Log level to use +#LOG_FACILITY=daemon # Syslog facility to use + # The following items are for use with NGCP #REDIS=127.0.0.1:6379 #REDIS_DB=0