diff --git a/conf/options/charon-logging.opt b/conf/options/charon-logging.opt index 31c46ad35..05f30553d 100644 --- a/conf/options/charon-logging.opt +++ b/conf/options/charon-logging.opt @@ -70,3 +70,14 @@ charon.syslog..ike_name = no charon.syslog..log_level = no Add the log level of each message after the subsystem (e.g. [IKE2]). + +charon.syslog..map_level = -1 + Map strongSwan specific loglevels to syslog loglevels. + + The default setting of -1 passes all messages to syslog using a log + level of LOG_INFO. A non-negative value maps the strongSwan specific + loglevels (0..4) to the syslog level starting at the specified number. + For example, a value of 5 (LOG_NOTICE) maps strongSwan loglevel 0 to + LOG_NOTICE, level 1 to LOG_INFO, and levels 2, 3 and 4 to LOG_DEBUG. + This allows (additional) filtering of log messages on the syslog + server. diff --git a/src/libcharon/bus/listeners/sys_logger.c b/src/libcharon/bus/listeners/sys_logger.c index 017fc4b9b..21476a2e5 100644 --- a/src/libcharon/bus/listeners/sys_logger.c +++ b/src/libcharon/bus/listeners/sys_logger.c @@ -55,6 +55,11 @@ struct private_sys_logger_t { */ bool log_level; + /** + * Map strongSwan loglevels to syslog levels, -1 to disable + */ + int map_level; + /** * Mutex to ensure multi-line log messages are not torn apart */ @@ -72,9 +77,18 @@ METHOD(logger_t, log_, void, { char groupstr[5], namestr[128] = ""; const char *current = message, *next; + int priority = this->facility; /* cache group name and optional name string */ this->lock->read_lock(this->lock); + if (this->map_level < 0) + { + priority |= LOG_INFO; + } + else + { + priority |= min(LOG_DEBUG, this->map_level + level); + } if (this->log_level) { snprintf(groupstr, sizeof(groupstr), "%N%d", debug_names, group, @@ -107,11 +121,11 @@ METHOD(logger_t, log_, void, next = strchr(current, '\n'); if (next == NULL) { - syslog(this->facility | LOG_INFO, "%.2d[%s]%s %s\n", + syslog(priority, "%.2d[%s]%s %s\n", thread, groupstr, namestr, current); break; } - syslog(this->facility | LOG_INFO, "%.2d[%s]%s %.*s\n", + syslog(priority, "%.2d[%s]%s %.*s\n", thread, groupstr, namestr, (int)(next - current), current); current = next + 1; } @@ -148,11 +162,12 @@ METHOD(sys_logger_t, set_level, void, } METHOD(sys_logger_t, set_options, void, - private_sys_logger_t *this, bool ike_name, bool log_level) + private_sys_logger_t *this, bool ike_name, bool log_level, int map_level) { this->lock->write_lock(this->lock); this->ike_name = ike_name; this->log_level = log_level; + this->map_level = map_level; this->lock->unlock(this->lock); } @@ -182,12 +197,13 @@ sys_logger_t *sys_logger_create(int facility) .destroy = _destroy, }, .facility = facility, + .map_level = -1, .mutex = mutex_create(MUTEX_TYPE_DEFAULT), .lock = rwlock_create(RWLOCK_TYPE_DEFAULT), ); set_level(this, DBG_ANY, LEVEL_SILENT); - setlogmask(LOG_UPTO(LOG_INFO)); + setlogmask(LOG_UPTO(LOG_DEBUG)); return &this->public; } diff --git a/src/libcharon/bus/listeners/sys_logger.h b/src/libcharon/bus/listeners/sys_logger.h index 027af9d2f..7cab9b50a 100644 --- a/src/libcharon/bus/listeners/sys_logger.h +++ b/src/libcharon/bus/listeners/sys_logger.h @@ -49,8 +49,10 @@ struct sys_logger_t { * * @param ike_name TRUE to prefix the name of the IKE_SA * @param log_level TRUE to include the log level in the message + * @param map_level map log level to syslog level, -1 to disable */ - void (*set_options) (sys_logger_t *this, bool ike_name, bool log_level); + void (*set_options) (sys_logger_t *this, bool ike_name, bool log_level, + int map_level); /** * Destroys a sys_logger_t object. diff --git a/src/libcharon/daemon.c b/src/libcharon/daemon.c index ef66d8bf9..e2ac7032f 100644 --- a/src/libcharon/daemon.c +++ b/src/libcharon/daemon.c @@ -451,6 +451,7 @@ static void load_sys_logger(private_daemon_t *this, char *facility, debug_t group; level_t def; bool ike_name, log_level; + int map_level; if (get_syslog_facility(facility) == -1) { @@ -467,8 +468,10 @@ static void load_sys_logger(private_daemon_t *this, char *facility, FALSE, lib->ns, facility); log_level = lib->settings->get_bool(lib->settings, "%s.syslog.%s.log_level", FALSE, lib->ns, facility); + map_level = lib->settings->get_int(lib->settings, "%s.syslog.%s.map_level", + -1, lib->ns, facility); - sys_logger->set_options(sys_logger, ike_name, log_level); + sys_logger->set_options(sys_logger, ike_name, log_level, map_level); def = lib->settings->get_int(lib->settings, "%s.syslog.%s.default", 1, lib->ns, facility);