]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
sys-logger: Optionally support mapping strongSwan loglevels to syslog levels
authorMartin Willi <martin@strongswan.org>
Thu, 20 Jan 2022 13:48:48 +0000 (14:48 +0100)
committerTobias Brunner <tobias@strongswan.org>
Mon, 24 Jan 2022 16:33:02 +0000 (17:33 +0100)
strongSwan logs all syslog messages using LOG_INFO for historical reasons,
regardless of the strongSwan loglevel used producing the log message.

In some setups with advanced logging infrastructure, it may be feasible
to be more verbose when logging in strongSwan, but then filter messages
on the syslog server. While this may be possible by custom syslog filtering
rules matching the log level included with the log_level setting, this is
not super convenient.

So add a new map_level setting, which can map strongSwan loglevels to
syslog loglevels. By default this is disabled, keeping the existing
behavior. If enabled, it maps strongSwan loglevels to syslog loglevels
at a given syslog loglevel offset.

Closes strongswan/strongswan#859

conf/options/charon-logging.opt
src/libcharon/bus/listeners/sys_logger.c
src/libcharon/bus/listeners/sys_logger.h
src/libcharon/daemon.c

index 31c46ad35890c37819b17f277dd7d7d30c9c04f0..05f30553d5494f1e19b7ba171f07c8b5fb580c23 100644 (file)
@@ -70,3 +70,14 @@ charon.syslog.<facility>.ike_name = no
 
 charon.syslog.<facility>.log_level = no
        Add the log level of each message after the subsystem (e.g. [IKE2]).
+
+charon.syslog.<facility>.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.
index 017fc4b9b014a1df99d23f54e655e0d545a9ff7d..21476a2e55fea2aa171aa91a078de017a706091f 100644 (file)
@@ -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;
 }
index 027af9d2fe87c559411fa75d469057ab76111fa7..7cab9b50ae3060a7b0f7698c3653eea9b670758f 100644 (file)
@@ -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.
index ef66d8bf97e13bf82c613a1741917f2f2b70606b..e2ac7032f78dd6d16586224debeb671b66cfe37e 100644 (file)
@@ -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);