diff --git a/include/villas/log.h b/include/villas/log.h index 5234f71bd..5300f9d3d 100644 --- a/include/villas/log.h +++ b/include/villas/log.h @@ -31,6 +31,7 @@ extern "C" { #include #include +#include "advio.h" #include "common.h" #include "log_config.h" @@ -99,6 +100,8 @@ struct log { long facilities; /**< Debug facilities used by the debug() macro. */ const char *path; /**< Path of the log file. */ char *prefix; /**< Prefix each line with this string. */ + int syslog; /**< Whether or not to log to syslogd. */ + FILE *file; /**< Send all log output to this file / stdout / stderr. */ }; diff --git a/lib/log.c b/lib/log.c index b08fa2f11..2ca7cfe82 100644 --- a/lib/log.c +++ b/lib/log.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "config.h" #include "log.h" @@ -128,6 +129,7 @@ int log_init(struct log *l, int level, long facilitites) global_log = l; l->level = level; + l->syslog = 0; l->facilities = facilitites; l->file = stderr; l->path = NULL; @@ -162,14 +164,22 @@ int log_init(struct log *l, int level, long facilitites) int log_start(struct log *l) { - l->file = l->path ? fopen(l->path, "a+") : stderr; - if (!l->file) { - l->file = stderr; - error("Failed to open log file '%s'", l->path); + if (l->path) { + l->file = fopen(l->path, "a+");; + if (!l->file) { + l->file = stderr; + error("Failed to open log file '%s'", l->path); + } } + else + l->file = stderr; l->state = STATE_STARTED; + if (l->syslog) { + openlog(NULL, LOG_PID, LOG_DAEMON); + } + debug(LOG_LOG | 5, "Log sub-system started: level=%d, faciltities=%#lx, path=%s", l->level, l->facilities, l->path); return 0; @@ -177,9 +187,15 @@ int log_start(struct log *l) int log_stop(struct log *l) { - if (l->state == STATE_STARTED) { - if (l->file != stderr && l->file != stdout) - fclose(l->file); + if (l->state != STATE_STARTED) + return 0; + + if (l->file != stderr && l->file != stdout) { + fclose(l->file); + } + + if (l->syslog) { + closelog(); } l->state = STATE_STOPPED; diff --git a/lib/log_config.c b/lib/log_config.c index f8eaf21c0..ce587830e 100644 --- a/lib/log_config.c +++ b/lib/log_config.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "config.h" #include "log.h" @@ -38,10 +39,11 @@ int log_parse(struct log *l, json_t *cfg) json_error_t err; - ret = json_unpack_ex(cfg, &err, 0, "{ s?: i, s?: s, s?: s }", + ret = json_unpack_ex(cfg, &err, 0, "{ s?: i, s?: s, s?: s, s?: b }", "level", &l->level, "file", &path, - "facilities", &facilities + "facilities", &facilities, + "syslog", &l->syslog ); if (ret) jerror(&err, "Failed to parse logging configuration"); @@ -71,6 +73,9 @@ void jerror(json_error_t *err, const char *fmt, ...) log_print(l, LOG_LVL_ERROR, "%s:", buf); { INDENT log_print(l, LOG_LVL_ERROR, "%s in %s:%d:%d", err->text, err->source, err->line, err->column); + + if (l->syslog) + syslog(LOG_ERR, "%s in %s:%d:%d", err->text, err->source, err->line, err->column); } free(buf); diff --git a/lib/log_helper.c b/lib/log_helper.c index cc9f3cd5a..df0f1c2d3 100644 --- a/lib/log_helper.c +++ b/lib/log_helper.c @@ -22,6 +22,7 @@ #include #include +#include #include "utils.h" #include "log.h" @@ -37,7 +38,12 @@ void debug(long class, const char *fmt, ...) if (((fac == 0) || (fac & l->facilities)) && (lvl <= l->level)) { va_start(ap, fmt); + log_vprint(l, LOG_LVL_DEBUG, fmt, ap); + + if (l->syslog) + syslog(LOG_DEBUG, fmt, ap); + va_end(ap); } } @@ -49,7 +55,12 @@ void info(const char *fmt, ...) struct log *l = global_log; va_start(ap, fmt); + log_vprint(l, LOG_LVL_INFO, fmt, ap); + + if (l->syslog) + syslog(LOG_INFO, fmt, ap); + va_end(ap); } @@ -60,7 +71,12 @@ void warn(const char *fmt, ...) struct log *l = global_log; va_start(ap, fmt); + log_vprint(l, LOG_LVL_WARN, fmt, ap); + + if (l->syslog) + syslog(LOG_WARNING, fmt, ap); + va_end(ap); } @@ -71,7 +87,12 @@ void stats(const char *fmt, ...) struct log *l = global_log; va_start(ap, fmt); + log_vprint(l, LOG_LVL_STATS, fmt, ap); + + if (l->syslog) + syslog(LOG_INFO, fmt, ap); + va_end(ap); } @@ -82,7 +103,12 @@ void error(const char *fmt, ...) struct log *l = global_log; va_start(ap, fmt); + log_vprint(l, LOG_LVL_ERROR, fmt, ap); + + if (l->syslog) + syslog(LOG_ERR, fmt, ap); + va_end(ap); killme(SIGABRT); @@ -102,6 +128,9 @@ void serror(const char *fmt, ...) log_print(l, LOG_LVL_ERROR, "%s: %m (%u)", buf, errno); + if (l->syslog) + syslog(LOG_ERR, "%s: %m (%u)", buf, errno); + free(buf); killme(SIGABRT);