Loggers specify what log messages they want to receive during registration.
authorTobias Brunner <tobias@strongswan.org>
Mon, 23 Jan 2012 12:51:21 +0000 (13:51 +0100)
committerTobias Brunner <tobias@strongswan.org>
Wed, 2 May 2012 12:45:38 +0000 (14:45 +0200)
This also allows us to generate the log message only once for all
loggers that need it (avoids calls to custom printf specifier callbacks).

To update the log levels loggers can simply be registered again.

14 files changed:
src/charon/charon.c
src/libcharon/bus/bus.c
src/libcharon/bus/bus.h
src/libcharon/bus/listeners/file_logger.c
src/libcharon/bus/listeners/logger.h
src/libcharon/bus/listeners/sys_logger.c
src/libcharon/control/controller.c
src/libcharon/control/controller.h
src/libcharon/plugins/android/android_logger.c
src/libcharon/plugins/smp/smp.c
src/libcharon/plugins/sql/sql_logger.c
src/libcharon/plugins/stroke/stroke_control.c
src/libcharon/plugins/stroke/stroke_socket.c
src/libcharon/processing/jobs/initiate_mediation_job.c

index 5e55221..48fb262 100644 (file)
@@ -395,11 +395,9 @@ static void initialize_loggers(bool use_stderr, level_t levels[])
        {
                /* set up default stdout file_logger */
                file_logger = file_logger_create(stdout, NULL, FALSE);
-               charon->bus->add_logger(charon->bus, &file_logger->logger);
                charon->file_loggers->insert_last(charon->file_loggers, file_logger);
                /* set up default daemon sys_logger */
                sys_logger = sys_logger_create(LOG_DAEMON, FALSE);
-               charon->bus->add_logger(charon->bus, &sys_logger->logger);
                charon->sys_loggers->insert_last(charon->sys_loggers, sys_logger);
                for (group = 0; group < DBG_MAX; group++)
                {
@@ -409,12 +407,14 @@ static void initialize_loggers(bool use_stderr, level_t levels[])
                                file_logger->set_level(file_logger, group, levels[group]);
                        }
                }
+               charon->bus->add_logger(charon->bus, &file_logger->logger);
+               charon->bus->add_logger(charon->bus, &sys_logger->logger);
 
                /* set up default auth sys_logger */
                sys_logger = sys_logger_create(LOG_AUTHPRIV, FALSE);
-               charon->bus->add_logger(charon->bus, &sys_logger->logger);
-               charon->sys_loggers->insert_last(charon->sys_loggers, sys_logger);
                sys_logger->set_level(sys_logger, DBG_ANY, LEVEL_AUDIT);
+               charon->sys_loggers->insert_last(charon->sys_loggers, sys_logger);
+               charon->bus->add_logger(charon->bus, &sys_logger->logger);
        }
 }
 
index 4f1a4ce..c493291 100644 (file)
@@ -40,9 +40,17 @@ struct private_bus_t {
        linked_list_t *listeners;
 
        /**
-        * List of registered loggers.
+        * List of registered loggers for each log group as log_entry_t.
+        * Loggers are ordered by descending log level.
+        * The extra list stores all loggers so we can properly unregister them.
         */
-       linked_list_t *loggers;
+       linked_list_t *loggers[DBG_MAX + 1];
+
+       /**
+        * Maximum log level of any registered logger for each log group.
+        * This allows to check quickly if a log message has to be logged at all.
+        */
+       level_t max_level[DBG_MAX + 1];
 
        /**
         * Mutex for the list of listeners, recursively.
@@ -79,6 +87,25 @@ struct entry_t {
 
 };
 
+typedef struct log_entry_t log_entry_t;
+
+/**
+ * a logger entry
+ */
+struct log_entry_t {
+
+       /**
+        * registered logger interface
+        */
+       logger_t *logger;
+
+       /**
+        * registered log levels per group
+        */
+       level_t levels[DBG_MAX];
+
+};
+
 METHOD(bus_t, add_listener, void,
        private_bus_t *this, listener_t *listener)
 {
@@ -114,11 +141,98 @@ METHOD(bus_t, remove_listener, void,
        this->mutex->unlock(this->mutex);
 }
 
+/**
+ * Register a logger on the given log group according to the requested level
+ */
+static inline void register_logger(private_bus_t *this, debug_t group,
+                                                                  log_entry_t *entry)
+{
+       enumerator_t *enumerator;
+       linked_list_t *loggers;
+       log_entry_t *current;
+       level_t level;
+
+       loggers = this->loggers[group];
+       level = entry->levels[group];
+
+       enumerator = loggers->create_enumerator(loggers);
+       while (enumerator->enumerate(enumerator, (void**)&current))
+       {
+               if (current->levels[group] <= level)
+               {
+                       break;
+               }
+       }
+       loggers->insert_before(loggers, enumerator, entry);
+       enumerator->destroy(enumerator);
+
+       this->max_level[group] = max(this->max_level[group], level);
+}
+
+/**
+ * Unregister a logger from all log groups (destroys the log_entry_t)
+ */
+static inline void unregister_logger(private_bus_t *this, logger_t *logger)
+{
+       enumerator_t *enumerator;
+       linked_list_t *loggers;
+       log_entry_t *entry, *found = NULL;
+
+       loggers = this->loggers[DBG_MAX];
+       enumerator = loggers->create_enumerator(loggers);
+       while (enumerator->enumerate(enumerator, &entry))
+       {
+               if (entry->logger == logger)
+               {
+                       loggers->remove_at(loggers, enumerator);
+                       found = entry;
+                       break;
+               }
+       }
+       enumerator->destroy(enumerator);
+
+       if (found)
+       {
+               debug_t group;
+               for (group = 0; group < DBG_MAX; group++)
+               {
+                       if (found->levels[group] > LEVEL_SILENT)
+                       {
+                               loggers = this->loggers[group];
+                               loggers->remove(loggers, found, NULL);
+
+                               this->max_level[group] = LEVEL_SILENT;
+                               if (loggers->get_first(loggers, (void**)&entry) == SUCCESS)
+                               {
+                                       this->max_level[group] = entry->levels[group];
+                               }
+                       }
+               }
+               free(found);
+       }
+}
+
 METHOD(bus_t, add_logger, void,
        private_bus_t *this, logger_t *logger)
 {
+       log_entry_t *entry;
+       debug_t group;
+
+       INIT(entry,
+               .logger = logger,
+       );
+
        this->log_lock->write_lock(this->log_lock);
-       this->loggers->insert_last(this->loggers, logger);
+       unregister_logger(this, logger);
+       for (group = 0; group < DBG_MAX; group++)
+       {
+               entry->levels[group] = logger->get_level(logger, group);
+               if (entry->levels[group] > LEVEL_SILENT)
+               {
+                       register_logger(this, group, entry);
+               }
+       }
+       this->loggers[DBG_MAX]->insert_last(this->loggers[DBG_MAX], entry);
        this->log_lock->unlock(this->log_lock);
 }
 
@@ -126,7 +240,7 @@ METHOD(bus_t, remove_logger, void,
        private_bus_t *this, logger_t *logger)
 {
        this->log_lock->write_lock(this->log_lock);
-       this->loggers->remove(this->loggers, logger, NULL);
+       unregister_logger(this, logger);
        this->log_lock->unlock(this->log_lock);
 }
 
@@ -154,43 +268,41 @@ typedef struct {
        debug_t group;
        /** debug level */
        level_t level;
-       /** format string */
-       char *format;
-       /** argument list */
-       va_list args;
+       /** message */
+       char message[8192];
 } log_data_t;
 
 /**
  * logger->log() invocation as a invoke_function callback
  */
-static void log_cb(logger_t *logger, log_data_t *data)
+static void log_cb(log_entry_t *entry, log_data_t *data)
 {
-       va_list args;
-
-       va_copy(args, data->args);
-       logger->log(logger, data->group, data->level, data->thread, data->ike_sa,
-                               data->format, args);
-       va_end(args);
+       if (entry->levels[data->group] < data->level)
+       {
+               return;
+       }
+       entry->logger->log(entry->logger, data->group, data->level,
+                                          data->thread, data->ike_sa, data->message);
 }
 
 METHOD(bus_t, vlog, void,
        private_bus_t *this, debug_t group, level_t level,
        char* format, va_list args)
 {
-       log_data_t data;
-
-       data.ike_sa = this->thread_sa->get(this->thread_sa);
-       data.thread = thread_current_id();
-       data.group = group;
-       data.level = level;
-       data.format = format;
-       va_copy(data.args, args);
-
        this->log_lock->read_lock(this->log_lock);
-       this->loggers->invoke_function(this->loggers, (void*)log_cb, &data);
+       if (this->max_level[group] >= level)
+       {
+               linked_list_t *loggers = this->loggers[group];
+               log_data_t data;
+
+               data.ike_sa = this->thread_sa->get(this->thread_sa);
+               data.thread = thread_current_id();
+               data.group = group;
+               data.level = level;
+               vsnprintf(data.message, sizeof(data.message), format, args);
+               loggers->invoke_function(loggers, (linked_list_invoke_t)log_cb, &data);
+       }
        this->log_lock->unlock(this->log_lock);
-
-       va_end(data.args);
 }
 
 METHOD(bus_t, log_, void,
@@ -598,8 +710,14 @@ METHOD(bus_t, narrow, void,
 METHOD(bus_t, destroy, void,
        private_bus_t *this)
 {
+       debug_t group;
+       for (group = 0; group < DBG_MAX; group++)
+       {
+               this->loggers[group]->destroy(this->loggers[group]);
+       }
+       this->loggers[DBG_MAX]->destroy_function(this->loggers[DBG_MAX],
+                                                                                        (void*)free);
        this->listeners->destroy_function(this->listeners, (void*)free);
-       this->loggers->destroy(this->loggers);
        this->thread_sa->destroy(this->thread_sa);
        this->log_lock->destroy(this->log_lock);
        this->mutex->destroy(this->mutex);
@@ -612,6 +730,7 @@ METHOD(bus_t, destroy, void,
 bus_t *bus_create()
 {
        private_bus_t *this;
+       debug_t group;
 
        INIT(this,
                .public = {
@@ -638,12 +757,17 @@ bus_t *bus_create()
                        .destroy = _destroy,
                },
                .listeners = linked_list_create(),
-               .loggers = linked_list_create(),
                .mutex = mutex_create(MUTEX_TYPE_RECURSIVE),
                .log_lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
                .thread_sa = thread_value_create(NULL),
        );
 
+       for (group = 0; group <= DBG_MAX; group++)
+       {
+               this->loggers[group] = linked_list_create();
+               this->max_level[group] = LEVEL_SILENT;
+       }
+
        return &this->public;
 }
 
index d6e4a67..b9974ad 100644 (file)
@@ -150,6 +150,14 @@ struct bus_t {
         * by multiple threads.  Recursive calls are not prevented, so logger that
         * may cause recursive calls are responsible to avoid infinite loops.
         *
+        * During registration get_level() is called for all log groups and the
+        * logger is registered to receive log messages for groups for which
+        * the requested log level is > LEVEL_SILENT and whose level is lower
+        * or equal than the requested level.
+        *
+        * To update the registered log levels call add_logger again with the
+        * same logger and return the new levels from get_level().
+        *
         * @param logger        logger to register.
         */
        void (*add_logger) (bus_t *this, logger_t *logger);
index c8c8534..77af9e4 100644 (file)
@@ -62,65 +62,65 @@ struct private_file_logger_t {
 
 METHOD(logger_t, log_, void,
        private_file_logger_t *this, debug_t group, level_t level, int thread,
-       ike_sa_t* ike_sa, char *format, va_list args)
+       ike_sa_t* ike_sa, char *message)
 {
-       if (level <= this->levels[group])
-       {
-               char buffer[8192], timestr[128], namestr[128] = "";
-               char *current = buffer, *next;
-               struct tm tm;
-               time_t t;
+       char timestr[128], namestr[128] = "";
+       char *current = message, *next;
+       struct tm tm;
+       time_t t;
 
-               if (this->time_format)
-               {
-                       t = time(NULL);
-                       localtime_r(&t, &tm);
-                       strftime(timestr, sizeof(timestr), this->time_format, &tm);
-               }
-               if (this->ike_name && ike_sa)
+       if (this->time_format)
+       {
+               t = time(NULL);
+               localtime_r(&t, &tm);
+               strftime(timestr, sizeof(timestr), this->time_format, &tm);
+       }
+       if (this->ike_name && ike_sa)
+       {
+               if (ike_sa->get_peer_cfg(ike_sa))
                {
-                       if (ike_sa->get_peer_cfg(ike_sa))
-                       {
-                               snprintf(namestr, sizeof(namestr), " <%s|%d>",
-                                       ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa));
-                       }
-                       else
-                       {
-                               snprintf(namestr, sizeof(namestr), " <%d>",
-                                       ike_sa->get_unique_id(ike_sa));
-                       }
+                       snprintf(namestr, sizeof(namestr), " <%s|%d>",
+                               ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa));
                }
                else
                {
-                       namestr[0] = '\0';
+                       snprintf(namestr, sizeof(namestr), " <%d>",
+                               ike_sa->get_unique_id(ike_sa));
                }
+       }
+       else
+       {
+               namestr[0] = '\0';
+       }
 
-               /* write in memory buffer first */
-               vsnprintf(buffer, sizeof(buffer), format, args);
-
-               /* prepend a prefix in front of every line */
-               this->mutex->lock(this->mutex);
-               while (current)
+       /* prepend a prefix in front of every line */
+       this->mutex->lock(this->mutex);
+       while (current)
+       {
+               next = strchr(current, '\n');
+               if (next)
+               {
+                       *(next++) = '\0';
+               }
+               if (this->time_format)
                {
-                       next = strchr(current, '\n');
-                       if (next)
-                       {
-                               *(next++) = '\0';
-                       }
-                       if (this->time_format)
-                       {
-                               fprintf(this->out, "%s %.2d[%N]%s %s\n",
-                                               timestr, thread, debug_names, group, namestr, current);
-                       }
-                       else
-                       {
-                               fprintf(this->out, "%.2d[%N]%s %s\n",
-                                               thread, debug_names, group, namestr, current);
-                       }
-                       current = next;
+                       fprintf(this->out, "%s %.2d[%N]%s %s\n",
+                                       timestr, thread, debug_names, group, namestr, current);
                }
-               this->mutex->unlock(this->mutex);
+               else
+               {
+                       fprintf(this->out, "%.2d[%N]%s %s\n",
+                                       thread, debug_names, group, namestr, current);
+               }
+               current = next;
        }
+       this->mutex->unlock(this->mutex);
+}
+
+METHOD(logger_t, get_level, level_t,
+       private_file_logger_t *this, debug_t group)
+{
+       return this->levels[group];
 }
 
 METHOD(file_logger_t, set_level, void,
@@ -161,6 +161,7 @@ file_logger_t *file_logger_create(FILE *out, char *time_format, bool ike_name)
                .public = {
                        .logger = {
                                .log = _log_,
+                               .get_level = _get_level,
                        },
                        .set_level = _set_level,
                        .destroy = _destroy,
index 9918e29..0306536 100644 (file)
@@ -33,21 +33,31 @@ struct logger_t {
        /**
         * Log a debugging message.
         *
-        * @note Calls to bus_t.log() are handled seperately from calls to
-        * other functions. This callback may be called concurrently by
-        * multiple threads.  Also recurisve calls are not prevented, logger that
-        * may cause recursive calls are responsible to avoid infinite loops.
+        * @note Calls to bus_t.log() are handled separately from calls to
+        * other functions.  This callback may be called concurrently by
+        * multiple threads.  Also recursive calls are not prevented, loggers that
+        * may cause recursive log messages are responsible to avoid infinite loops.
         *
         * @param group         kind of the signal (up, down, rekeyed, ...)
         * @param level         verbosity level of the signal
         * @param thread        ID of the thread raised this signal
         * @param ike_sa        IKE_SA associated to the event
-        * @param format        printf() style format string
-        * @param args          vprintf() style argument list
+        * @param message       log message
         */
        void (*log)(logger_t *this, debug_t group, level_t level, int thread,
-                               ike_sa_t *ike_sa, char* format, va_list args);
+                               ike_sa_t *ike_sa, char* message);
 
+       /**
+        * Get the desired log level for a debug group.  This is called during
+        * registration.
+        *
+        * If the desired log levels have changed, re-register the logger with
+        * the bus.
+        *
+        * @param group         debug group
+        * @return                      max level to log (0..4) or -1 for none (see debug.h)
+        */
+       level_t (*get_level)(logger_t *this, debug_t group);
 };
 
 #endif /** LOGGER_H_ @}*/
index 440fda0..9962fe0 100644 (file)
@@ -57,47 +57,48 @@ struct private_sys_logger_t {
 
 METHOD(logger_t, log_, void,
        private_sys_logger_t *this, debug_t group, level_t level, int thread,
-       ike_sa_t* ike_sa, char *format, va_list args)
+       ike_sa_t* ike_sa, char *message)
 {
-       if (level <= this->levels[group])
-       {
-               char buffer[8192], groupstr[4], namestr[128] = "";
-               char *current = buffer, *next;
+       char groupstr[4], namestr[128] = "";
+       char *current = message, *next;
 
-               /* write in memory buffer first */
-               vsnprintf(buffer, sizeof(buffer), format, args);
-               /* cache group name and optional name string */
-               snprintf(groupstr, sizeof(groupstr), "%N", debug_names, group);
+       /* cache group name and optional name string */
+       snprintf(groupstr, sizeof(groupstr), "%N", debug_names, group);
 
-               if (this->ike_name && ike_sa)
+       if (this->ike_name && ike_sa)
+       {
+               if (ike_sa->get_peer_cfg(ike_sa))
                {
-                       if (ike_sa->get_peer_cfg(ike_sa))
-                       {
-                               snprintf(namestr, sizeof(namestr), " <%s|%d>",
-                                       ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa));
-                       }
-                       else
-                       {
-                               snprintf(namestr, sizeof(namestr), " <%d>",
-                                       ike_sa->get_unique_id(ike_sa));
-                       }
+                       snprintf(namestr, sizeof(namestr), " <%s|%d>",
+                               ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa));
                }
+               else
+               {
+                       snprintf(namestr, sizeof(namestr), " <%d>",
+                               ike_sa->get_unique_id(ike_sa));
+               }
+       }
 
-               /* do a syslog for every line */
-               this->mutex->lock(this->mutex);
-               while (current)
+       /* do a syslog for every line */
+       this->mutex->lock(this->mutex);
+       while (current)
+       {
+               next = strchr(current, '\n');
+               if (next)
                {
-                       next = strchr(current, '\n');
-                       if (next)
-                       {
-                               *(next++) = '\0';
-                       }
-                       syslog(this->facility|LOG_INFO, "%.2d[%s]%s %s\n",
-                                  thread, groupstr, namestr, current);
-                       current = next;
+                       *(next++) = '\0';
                }
-               this->mutex->unlock(this->mutex);
+               syslog(this->facility|LOG_INFO, "%.2d[%s]%s %s\n",
+                          thread, groupstr, namestr, current);
+               current = next;
        }
+       this->mutex->unlock(this->mutex);
+}
+
+METHOD(logger_t, get_level, level_t,
+       private_sys_logger_t *this, debug_t group)
+{
+       return this->levels[group];
 }
 
 METHOD(sys_logger_t, set_level, void,
@@ -135,6 +136,7 @@ sys_logger_t *sys_logger_create(int facility, bool ike_name)
                .public = {
                        .logger = {
                                .log = _log_,
+                               .get_level = _get_level,
                        },
                        .set_level = _set_level,
                        .destroy = _destroy,
index 7ba4747..c23bf04 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Tobias Brunner
+ * Copyright (C) 2011-2012 Tobias Brunner
  * Copyright (C) 2007-2011 Martin Willi
  * Copyright (C) 2011 revosec AG
  * Hochschule fuer Technik Rapperswil
@@ -199,11 +199,11 @@ static bool wait_for_listener(interface_listener_t *listener, job_t *job,
 
 METHOD(logger_t, listener_log, void,
        interface_logger_t *this, debug_t group, level_t level, int thread,
-       ike_sa_t *ike_sa, char* format, va_list args)
+       ike_sa_t *ike_sa, char* message)
 {
        if (this->listener->ike_sa == ike_sa)
        {
-               if (!this->callback(this->param, group, level, ike_sa, format, args))
+               if (!this->callback(this->param, group, level, ike_sa, message))
                {
                        this->listener->status = NEED_MORE;
                        listener_done(this->listener);
@@ -211,6 +211,14 @@ METHOD(logger_t, listener_log, void,
        }
 }
 
+METHOD(logger_t, listener_get_level, level_t,
+       interface_logger_t *this, debug_t group)
+{
+       /* in order to allow callback listeners to decide what they want to log
+        * we request any log message, but only if we actually want logging */
+       return this->callback == controller_cb_empty ? LEVEL_SILENT : LEVEL_PRIVATE;
+}
+
 METHOD(job_t, get_priority_medium, job_priority_t,
        job_t *this)
 {
@@ -350,6 +358,7 @@ METHOD(controller_t, initiate, status_t,
                        .logger = {
                                .public = {
                                        .log = _listener_log,
+                                       .get_level = _listener_get_level,
                                },
                                .callback = callback,
                                .param = param,
@@ -416,6 +425,7 @@ METHOD(controller_t, terminate_ike, status_t,
                        .logger = {
                                .public = {
                                        .log = _listener_log,
+                                       .get_level = _listener_get_level,
                                },
                                .callback = callback,
                                .param = param,
@@ -494,6 +504,7 @@ METHOD(controller_t, terminate_child, status_t,
                        .logger = {
                                .public = {
                                        .log = _listener_log,
+                                       .get_level = _listener_get_level,
                                },
                                .callback = callback,
                                .param = param,
@@ -560,7 +571,7 @@ METHOD(controller_t, terminate_child, status_t,
  * See header
  */
 bool controller_cb_empty(void *param, debug_t group, level_t level,
-                                                ike_sa_t *ike_sa, char *format, va_list args)
+                                                ike_sa_t *ike_sa, char *message)
 {
        return TRUE;
 }
index e7e9222..26614af 100644 (file)
 #include <bus/bus.h>
 
 /**
- * callback to log things triggered by controller.
+ * Callback to log things triggered by controller.
  *
- * @param param                        echoed parameter supplied when function invoked
+ * @param param                        parameter supplied when controller method was called
  * @param group                        debugging group
- * @param level                        verbosity level if log
+ * @param level                        verbosity level
  * @param ike_sa               associated IKE_SA, if any
- * @param format               printf like format string
- * @param args                 list of arguments to use for format
- * @return                             FALSE to return from invoked function
+ * @param message              log message
+ * @return                             FALSE to return from called controller method
  */
 typedef bool (*controller_cb_t)(void* param, debug_t group, level_t level,
-                                                               ike_sa_t* ike_sa, char* format, va_list args);
+                                                               ike_sa_t* ike_sa, char* message);
 
 /**
- * Empty callback function for controller_t functions.
+ * Empty callback function for controller_t methods.
  *
  * If you want to do a synchronous call, but don't need a callback, pass
- * this function to the controllers methods.
+ * this function to the controller methods.
  */
 bool controller_cb_empty(void *param, debug_t group, level_t level,
-                                                ike_sa_t *ike_sa, char *format, va_list args);
+                                                ike_sa_t *ike_sa, char *message);
 
 typedef struct controller_t controller_t;
 
index 845d307..d551f27 100644 (file)
@@ -47,34 +47,36 @@ struct private_android_logger_t {
 
 
 METHOD(logger_t, log_, void,
-          private_android_logger_t *this, debug_t group, level_t level,
-          int thread, ike_sa_t* ike_sa, char *format, va_list args)
+       private_android_logger_t *this, debug_t group, level_t level,
+       int thread, ike_sa_t* ike_sa, char *message)
 {
-       if (level <= this->level)
-       {
-               int prio = level > 1 ? ANDROID_LOG_DEBUG : ANDROID_LOG_INFO;
-               char sgroup[16], buffer[8192];
-               char *current = buffer, *next;
-               snprintf(sgroup, sizeof(sgroup), "%N", debug_names, group);
-               vsnprintf(buffer, sizeof(buffer), format, args);
-               this->mutex->lock(this->mutex);
-               while (current)
-               {       /* log each line separately */
-                       next = strchr(current, '\n');
-                       if (next)
-                       {
-                               *(next++) = '\0';
-                       }
-                       __android_log_print(prio, "charon", "%.2d[%s] %s\n",
-                                                               thread, sgroup, current);
-                       current = next;
+       int prio = level > 1 ? ANDROID_LOG_DEBUG : ANDROID_LOG_INFO;
+       char sgroup[16];
+       char *current = message, *next;
+       snprintf(sgroup, sizeof(sgroup), "%N", debug_names, group);
+       this->mutex->lock(this->mutex);
+       while (current)
+       {       /* log each line separately */
+               next = strchr(current, '\n');
+               if (next)
+               {
+                       *(next++) = '\0';
                }
-               this->mutex->unlock(this->mutex);
+               __android_log_print(prio, "charon", "%.2d[%s] %s\n",
+                                                       thread, sgroup, current);
+               current = next;
        }
+       this->mutex->unlock(this->mutex);
+}
+
+METHOD(logger_t, get_level, level_t,
+       private_android_logger_t *this, debug_t group)
+{
+       return this->level;
 }
 
 METHOD(android_logger_t, destroy, void,
-          private_android_logger_t *this)
+       private_android_logger_t *this)
 {
        this->mutex->destroy(this->mutex);
        free(this);
@@ -91,6 +93,7 @@ android_logger_t *android_logger_create()
                .public = {
                        .logger = {
                                .log = _log_,
+                               .get_level = _get_level,
                        },
                        .destroy = _destroy,
                },
index 1b2adc9..67e1e30 100644 (file)
@@ -349,7 +349,7 @@ static void request_query_config(xmlTextReaderPtr reader, xmlTextWriterPtr write
  * callback which logs to a XML writer
  */
 static bool xml_callback(xmlTextWriterPtr writer, debug_t group, level_t level,
-                                                ike_sa_t* ike_sa, char* format, va_list args)
+                                                ike_sa_t* ike_sa, char* message)
 {
        if (level <= 1)
        {
@@ -358,7 +358,7 @@ static bool xml_callback(xmlTextWriterPtr writer, debug_t group, level_t level,
                xmlTextWriterWriteFormatAttribute(writer, "level", "%d", level);
                xmlTextWriterWriteFormatAttribute(writer, "source", "%N", debug_names, group);
                xmlTextWriterWriteFormatAttribute(writer, "thread", "%u", thread_current_id());
-               xmlTextWriterWriteVFormatString(writer, format, args);
+               xmlTextWriterWriteString(writer, message);
                xmlTextWriterEndElement(writer);
                /* </item> */
        }
index e693bac..e7267b8 100644 (file)
@@ -50,7 +50,7 @@ struct private_sql_logger_t {
 
 METHOD(logger_t, log_, void,
        private_sql_logger_t *this, debug_t group, level_t level, int thread,
-       ike_sa_t* ike_sa, char *format, va_list args)
+       ike_sa_t* ike_sa, char *message)
 {
        if (this->recursive->get(this->recursive))
        {
@@ -58,9 +58,8 @@ METHOD(logger_t, log_, void,
        }
        this->recursive->set(this->recursive, this->recursive);
 
-       if (ike_sa && level <= this->level)
+       if (ike_sa)
        {
-               char buffer[8192];
                chunk_t local_spi, remote_spi;
                host_t *local_host, *remote_host;
                identification_t *local_id, *remote_id;
@@ -86,8 +85,6 @@ METHOD(logger_t, log_, void,
                local_host = ike_sa->get_my_host(ike_sa);
                remote_host = ike_sa->get_other_host(ike_sa);
 
-               vsnprintf(buffer, sizeof(buffer), format, args);
-
                this->db->execute(this->db, NULL, "REPLACE INTO ike_sas ("
                                                  "local_spi, remote_spi, id, initiator, "
                                                  "local_id_type, local_id_data, "
@@ -107,11 +104,18 @@ METHOD(logger_t, log_, void,
                this->db->execute(this->db, NULL, "INSERT INTO logs ("
                                                  "local_spi, signal, level, msg) VALUES (?, ?, ?, ?)",
                                                  DB_BLOB, local_spi, DB_INT, group, DB_INT, level,
-                                                 DB_TEXT, buffer);
+                                                 DB_TEXT, message);
        }
+
        this->recursive->set(this->recursive, NULL);
 }
 
+METHOD(logger_t, get_level, level_t,
+       private_sql_logger_t *this, debug_t group)
+{
+       return this->level;
+}
+
 METHOD(sql_logger_t, destroy, void,
        private_sql_logger_t *this)
 {
@@ -129,6 +133,7 @@ sql_logger_t *sql_logger_create(database_t *db)
                .public = {
                        .logger = {
                                .log = _log_,
+                               .get_level = _get_level,
                        },
                        .destroy = _destroy,
                },
index a58d904..a083a11 100644 (file)
@@ -58,11 +58,11 @@ struct stroke_log_info_t {
  * logging to the stroke interface
  */
 static bool stroke_log(stroke_log_info_t *info, debug_t group, level_t level,
-                                          ike_sa_t *ike_sa, char *format, va_list args)
+                                          ike_sa_t *ike_sa, char *message)
 {
        if (level <= info->level)
        {
-               if (vfprintf(info->out, format, args) < 0 ||
+               if (fprintf(info->out, message) < 0 ||
                        fprintf(info->out, "\n") < 0 ||
                        fflush(info->out) != 0)
                {
index 7ef15db..2d061a4 100644 (file)
@@ -517,12 +517,14 @@ static void stroke_loglevel(private_stroke_socket_t *this,
        while (enumerator->enumerate(enumerator, &sys_logger))
        {
                sys_logger->set_level(sys_logger, group, msg->loglevel.level);
+               charon->bus->add_logger(charon->bus, &sys_logger->logger);
        }
        enumerator->destroy(enumerator);
        enumerator = charon->file_loggers->create_enumerator(charon->file_loggers);
        while (enumerator->enumerate(enumerator, &file_logger))
        {
                file_logger->set_level(file_logger, group, msg->loglevel.level);
+               charon->bus->add_logger(charon->bus, &file_logger->logger);
        }
        enumerator->destroy(enumerator);
 }
index e52f3c6..610998d 100644 (file)
@@ -54,7 +54,7 @@ METHOD(job_t, destroy, void,
  */
 static bool initiate_callback(private_initiate_mediation_job_t *this,
                        debug_t group, level_t level, ike_sa_t *ike_sa,
-                       char *format, va_list args)
+                       char *message)
 {
        if (ike_sa && !this->mediation_sa_id)
        {