]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Rework] More logger refactoring
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 10 Feb 2020 19:28:41 +0000 (19:28 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 10 Feb 2020 21:12:13 +0000 (21:12 +0000)
src/libutil/logger.c
src/libutil/logger.h
src/libutil/logger_console.c
src/libutil/logger_file.c
src/libutil/logger_private.h
src/libutil/logger_syslog.c
src/lua/lua_config.c
src/rspamd.c

index f2ab3f611f9cc3924e3e23733f4bac66208270a7..af71665fda971931f9bb86addcce8d2237723cff 100644 (file)
@@ -24,6 +24,7 @@
 
 
 static rspamd_logger_t *default_logger = NULL;
+static rspamd_logger_t *emergency_logger = NULL;
 static struct rspamd_log_modules *log_modules = NULL;
 
 guint rspamd_task_log_id = (guint)-1;
@@ -32,268 +33,190 @@ RSPAMD_CONSTRUCTOR(rspamd_task_log_init)
        rspamd_task_log_id = rspamd_logger_add_debug_module("task");
 }
 
-
-/* Logging utility functions */
-gint
-rspamd_log_open_priv (rspamd_logger_t *rspamd_log, uid_t uid, gid_t gid)
+rspamd_logger_t *
+rspamd_log_default_logger (void)
 {
-       gint nfd;
+       return default_logger;
+}
 
-       if (!rspamd_log->opened) {
+rspamd_logger_t *
+rspamd_log_emergency_logger (void)
+{
+       return emergency_logger;
+}
 
-               switch (rspamd_log->log_type) {
-               case RSPAMD_LOG_CONSOLE:
-                       /* Dup stderr fd to simplify processing */
-                       nfd = dup (STDERR_FILENO);
+void
+rspamd_log_set_log_level (rspamd_logger_t *logger, gint level)
+{
+       g_assert (logger != NULL);
 
-                       if (nfd == -1) {
-                               return -1;
-                       }
-                       if (rspamd_log->fd != -1) {
-                               /*
-                                * Postponed closing (e.g. when we switch from
-                                * LOG_FILE to LOG_CONSOLE)
-                                */
-                               close (rspamd_log->fd);
-                       }
+       logger->log_level = level;
+}
 
-                       rspamd_log->fd = nfd;
+void
+rspamd_log_set_log_flags (rspamd_logger_t *logger, gint flags)
+{
+       g_assert (logger != NULL);
 
-                       if (isatty (STDERR_FILENO)) {
-                               rspamd_log->flags |= RSPAMD_LOG_FLAG_TTY;
-                       }
-                       break;
-               case RSPAMD_LOG_SYSLOG:
-#ifdef HAVE_SYSLOG_H
-                       openlog ("rspamd", LOG_NDELAY | LOG_PID,
-                                       rspamd_log->log_facility);
-                       rspamd_log->no_lock = TRUE;
-                       if (rspamd_log->fd != -1) {
-                               /*
-                                * Postponed closing (e.g. when we switch from
-                                * LOG_FILE to LOG_SYSLOG)
-                                */
-                               close (rspamd_log->fd);
-                       }
-#else
-                       return -1;
-#endif
-                       break;
-               case RSPAMD_LOG_FILE:
-                       nfd = rspamd_try_open_log_fd (rspamd_log, uid, gid);
+       logger->flags = flags;
+}
 
-                       if (nfd == -1) {
-                               return -1;
-                       }
+void
+rspamd_log_close (rspamd_logger_t *logger)
+{
+       g_assert (logger != NULL);
 
-                       if (rspamd_log->fd != -1) {
-                               /*
-                                * Postponed closing (e.g. when we switch from
-                                * LOG_CONSOLE to LOG_FILE)
-                                */
-                               close (rspamd_log->fd);
-                       }
+       if (logger->debug_ip) {
+               rspamd_map_helper_destroy_radix (logger->debug_ip);
+       }
 
-                       rspamd_log->fd = nfd;
-                       rspamd_log->no_lock = TRUE;
-                       break;
-               default:
-                       return -1;
-               }
+       if (logger->pk) {
+               rspamd_pubkey_unref (logger->pk);
+       }
 
-               rspamd_log->opened = TRUE;
-               rspamd_log->enabled = TRUE;
+       if (logger->keypair) {
+               rspamd_keypair_unref (logger->keypair);
        }
 
-       return 0;
-}
+       logger->ops.dtor (logger, logger->ops.specific);
 
+       /* TODO: Do we really need that ? */
+       if (logger == default_logger) {
+               default_logger = NULL;
+       }
 
-void
-rspamd_log_close_priv (rspamd_logger_t *rspamd_log, gboolean termination, uid_t uid, gid_t gid)
-{
+       if (logger == emergency_logger) {
+               emergency_logger = NULL;
+       }
 
-       rspamd_log_flush (rspamd_log);
-       rspamd_log_reset_repeated (rspamd_log);
+       if (!logger->pool) {
+               g_free (logger);
+       }
+}
 
-       if (rspamd_log->opened) {
-               switch (rspamd_log->type) {
-               case RSPAMD_LOG_SYSLOG:
-#ifdef HAVE_SYSLOG_H
-                       closelog ();
-#endif
-                       break;
-               case RSPAMD_LOG_FILE:
-                       if (rspamd_log->fd != -1) {
-#if _POSIX_SYNCHRONIZED_IO > 0
-                               if (fdatasync (rspamd_log->fd) == -1) {
-                                       msg_err ("error syncing log file: %s", strerror (errno));
-                               }
-#else
-                               if (fsync (rspamd_log->fd) == -1) {
-                                       msg_err ("error syncing log file: %s", strerror (errno));
-                               }
-#endif
-                               close (rspamd_log->fd);
-                               rspamd_log->fd = -1;
-                       }
-                       break;
-               case RSPAMD_LOG_CONSOLE:
-                       /*
-                        * Console logging is special: it is usually a last resort when
-                        * we have errors or something like that.
-                        *
-                        * Hence, we need to postpone it's closing to the moment
-                        * when we open (in a reliable matter!) a new logging
-                        * facility.
-                        */
-                       break;
-               }
+bool
+rspamd_log_reopen (rspamd_logger_t *rspamd_log,  struct rspamd_config *cfg,
+                                  uid_t uid, gid_t gid)
+{
+       void *nspec;
+       GError *err = NULL;
 
-               rspamd_log->enabled = FALSE;
-               rspamd_log->opened = FALSE;
-       }
+       g_assert (rspamd_log != NULL);
 
-       if (termination) {
-               g_free (rspamd_log->log_file);
-               rspamd_log->log_file = NULL;
-               g_free (rspamd_log);
-       }
+       nspec = rspamd_log->ops.reload (rspamd_log, cfg, rspamd_log->ops.specific,
+                       uid, gid, &err);
 }
 
-gint
-rspamd_log_reopen_priv (rspamd_logger_t *rspamd_log, uid_t uid, gid_t gid)
+static void
+rspamd_emergency_logger_dtor (gpointer d)
 {
-       if (rspamd_log->type == RSPAMD_LOG_FILE) {
-               rspamd_log_flush (rspamd_log);
-               rspamd_log_reset_repeated (rspamd_log);
+       rspamd_logger_t *logger = (rspamd_logger_t *)d;
 
-               gint newfd = rspamd_try_open_log_fd (rspamd_log, uid, gid);
+       rspamd_log_close (logger);
+}
 
-               if (newfd != -1) {
-                       rspamd_log_close_priv (rspamd_log, FALSE, uid, gid);
-                       rspamd_log->fd = newfd;
+rspamd_logger_t *
+rspamd_log_init (rspamd_mempool_t *pool)
+{
+       rspamd_logger_t *logger;
+       GError *err = NULL;
 
-                       rspamd_log->opened = TRUE;
-                       rspamd_log->enabled = TRUE;
-               }
+       g_assert (default_logger == NULL);
+       g_assert (emergency_logger == NULL);
 
-               /* Do nothing, use old settings */
+       if (pool) {
+               logger = rspamd_mempool_alloc0 (pool, sizeof (rspamd_logger_t));
+               logger->mtx = rspamd_mempool_get_mutex (pool);
        }
        else {
-               /* Straightforward */
-               rspamd_log_close_priv (rspamd_log, FALSE, uid, gid);
-
-               if (rspamd_log_open_priv (rspamd_log, uid, gid) == 0) {
-                       return 0;
-               }
+               logger = g_malloc0 (sizeof (rspamd_logger_t));
        }
 
-       return -1;
-}
 
-/**
- * Open log file or initialize other structures
- */
-gint
-rspamd_log_open (rspamd_logger_t *logger)
-{
-       return rspamd_log_open_priv (logger, -1, -1);
-}
+       logger->pool = pool;
+       logger->process_type = "main";
 
-/**
- * Close log file or destroy other structures
- */
-void
-rspamd_log_close (rspamd_logger_t *logger, gboolean termination)
-{
-       rspamd_log_close_priv (logger, termination, -1, -1);
-}
+       const struct rspamd_logger_funcs *funcs = &console_log_funcs;
+       memcpy (&logger->ops, funcs, sizeof (*funcs));
 
-/**
- * Close and open log again
- */
-gint
-rspamd_log_reopen (rspamd_logger_t *logger)
-{
-       return rspamd_log_reopen_priv (logger, -1, -1);
+       logger->ops.specific = logger->ops.init (logger, NULL, -1, -1, &err);
+
+       if (logger->ops.specific == NULL) {
+               rspamd_fprintf (stderr, "fatal error: cannot init console logging: %e\n",
+                               err);
+               g_error_free (err);
+
+               exit (EXIT_FAILURE);
+       }
+
+       default_logger = logger;
+       emergency_logger = logger;
+
+       rspamd_mempool_add_destructor (pool, rspamd_emergency_logger_dtor,
+                       emergency_logger);
+
+       return logger;
 }
 
-/*
- * Setup logger
- */
-void
-rspamd_set_logger (struct rspamd_config *cfg,
-               GQuark ptype,
-               rspamd_logger_t **plogger,
-               rspamd_mempool_t *pool)
+rspamd_logger_t *
+rspamd_log_open_specific (rspamd_mempool_t *pool,
+                                                 struct rspamd_config *cfg,
+                                                 const gchar *ptype,
+                                                 uid_t uid, gid_t gid)
 {
        rspamd_logger_t *logger;
+       GError *err = NULL;
 
-       if (plogger == NULL || *plogger == NULL) {
-               logger = g_malloc0 (sizeof (rspamd_logger_t));
-               logger->fd = -1;
-
-               if (cfg->log_error_elts > 0 && pool) {
-                       logger->errlog = rspamd_mempool_alloc0_shared (pool,
-                                       sizeof (*logger->errlog));
-                       logger->errlog->pool = pool;
-                       logger->errlog->max_elts = cfg->log_error_elts;
-                       logger->errlog->elt_len = cfg->log_error_elt_maxlen;
-                       logger->errlog->elts = rspamd_mempool_alloc0_shared (pool,
-                                       sizeof (struct rspamd_logger_error_elt) * cfg->log_error_elts +
-                                       cfg->log_error_elt_maxlen * cfg->log_error_elts);
-               }
-
-               if (pool) {
-                       logger->mtx = rspamd_mempool_get_mutex (pool);
-               }
+       g_assert (default_logger == NULL);
+       g_assert (emergency_logger == NULL);
 
-               if (plogger) {
-                       *plogger = logger;
-               }
+       if (pool) {
+               logger = rspamd_mempool_alloc0 (pool, sizeof (rspamd_logger_t));
+               logger->mtx = rspamd_mempool_get_mutex (pool);
        }
        else {
-               logger = *plogger;
+               logger = g_malloc0 (sizeof (rspamd_logger_t));
        }
 
-       logger->type = cfg->log_type;
-       logger->pid = getpid ();
-       logger->process_type = ptype;
+       logger->pool = pool;
 
-       switch (cfg->log_type) {
-               case RSPAMD_LOG_CONSOLE:
-                       logger->log_func = file_log_function;
-                       break;
-               case RSPAMD_LOG_SYSLOG:
-                       logger->log_func = syslog_log_function;
-                       break;
-               case RSPAMD_LOG_FILE:
-                       logger->log_func = file_log_function;
-                       break;
+       if (cfg->log_error_elts > 0 && pool) {
+               logger->errlog = rspamd_mempool_alloc0_shared (pool,
+                               sizeof (*logger->errlog));
+               logger->errlog->pool = pool;
+               logger->errlog->max_elts = cfg->log_error_elts;
+               logger->errlog->elt_len = cfg->log_error_elt_maxlen;
+               logger->errlog->elts = rspamd_mempool_alloc0_shared (pool,
+                               sizeof (struct rspamd_logger_error_elt) * cfg->log_error_elts +
+                               cfg->log_error_elt_maxlen * cfg->log_error_elts);
        }
 
-       logger->log_type = cfg->log_type;
+       const struct rspamd_logger_funcs *funcs = NULL;
 
-       if (!(logger->flags & RSPAMD_LOG_FLAG_ENFORCED)) {
-               logger->log_level = cfg->log_level;
+       switch (cfg->log_type) {
+       case RSPAMD_LOG_CONSOLE:
+               funcs = &console_log_funcs;
+               break;
+       case RSPAMD_LOG_SYSLOG:
+               funcs = &syslog_log_funcs;
+               break;
+       case RSPAMD_LOG_FILE:
+               funcs = &file_log_funcs;
+               break;
        }
 
-       logger->log_buffered = cfg->log_buffered;
-       logger->log_silent_workers = cfg->log_silent_workers;
-       logger->log_buf_size = cfg->log_buf_size;
+       g_assert (funcs != NULL);
+       memcpy (&logger->ops, funcs, sizeof (*funcs));
 
-       if (logger->log_file) {
-               g_free (logger->log_file);
-               logger->log_file = NULL;
-       }
-       if (cfg->log_file) {
-               logger->log_file = g_strdup (cfg->log_file);
+       logger->pid = getpid ();
+       logger->process_type = ptype;
+
+       if (!(logger->flags & RSPAMD_LOG_FLAG_ENFORCED)) {
+               logger->log_level = cfg->log_level;
        }
 
        logger->flags = cfg->log_flags;
 
-
        /* Set up conditional logging */
        if (cfg->debug_ip_map != NULL) {
                /* Try to add it as map first of all */
@@ -309,20 +232,6 @@ rspamd_set_logger (struct rspamd_config *cfg,
                                NULL,
                                NULL);
        }
-       else if (logger->debug_ip) {
-               rspamd_map_helper_destroy_radix (logger->debug_ip);
-               logger->debug_ip = NULL;
-       }
-
-       if (logger->pk) {
-               rspamd_pubkey_unref (logger->pk);
-       }
-       logger->pk = NULL;
-
-       if (logger->keypair) {
-               rspamd_keypair_unref (logger->keypair);
-       }
-       logger->keypair = NULL;
 
        if (cfg->log_encryption_key) {
                logger->pk = rspamd_pubkey_ref (cfg->log_encryption_key);
@@ -334,14 +243,29 @@ rspamd_set_logger (struct rspamd_config *cfg,
        default_logger = logger;
 }
 
+
 /**
  * Used after fork() for updating structure params
  */
 void
-rspamd_log_update_pid (GQuark ptype, rspamd_logger_t *rspamd_log)
+rspamd_log_on_fork (GQuark ptype, struct rspamd_config *cfg,
+                                       rspamd_logger_t *logger)
 {
-       rspamd_log->pid = getpid ();
-       rspamd_log->process_type = g_quark_to_string (ptype);
+       logger->pid = getpid ();
+       logger->process_type = g_quark_to_string (ptype);
+
+       if (logger->ops.on_fork) {
+               GError *err = NULL;
+
+               bool ret = logger->ops.on_fork (logger, cfg, logger->ops.specific, &err);
+
+               if (!ret && emergency_logger) {
+                       rspamd_common_log_function (emergency_logger, G_LOG_LEVEL_CRITICAL,
+                                       "logger", NULL, G_STRFUNC,
+                                       "cannot update logging on fork: %e", err);
+                       g_error_free (err);
+               }
+       }
 }
 
 static inline gboolean
@@ -455,13 +379,14 @@ rspamd_log_write_ringbuffer (rspamd_logger_t *rspamd_log,
        g_atomic_int_set (&elt->completed, 1);
 }
 
-void
+bool
 rspamd_common_logv (rspamd_logger_t *rspamd_log, gint level_flags,
                const gchar *module, const gchar *id, const gchar *function,
                const gchar *fmt, va_list args)
 {
        gchar logbuf[RSPAMD_LOGBUF_SIZE], *end;
        gint level = level_flags & (RSPAMD_LOG_LEVEL_MASK & G_LOG_LEVEL_MASK), mod_id;
+       bool ret = false;
 
        if (G_UNLIKELY (rspamd_log == NULL)) {
                rspamd_log = default_logger;
@@ -491,23 +416,23 @@ rspamd_common_logv (rspamd_logger_t *rspamd_log, gint level_flags,
 
                                encrypted = rspamd_log_encrypt_message (logbuf, end, &enc_len,
                                                rspamd_log);
-                               rspamd_log->log_func (module, id,
+                               ret = rspamd_log->ops.log (module, id,
                                                function,
                                                level_flags,
                                                encrypted,
                                                enc_len,
                                                rspamd_log,
-                                               rspamd_log->log_arg);
+                                               rspamd_log->ops.specific);
                                g_free (encrypted);
                        }
                        else {
-                               rspamd_log->log_func (module, id,
+                               ret = rspamd_log->ops.log (module, id,
                                                function,
                                                level_flags,
                                                logbuf,
                                                end - logbuf,
                                                rspamd_log,
-                                               rspamd_log->log_arg);
+                                               rspamd_log->ops.specific);
                        }
 
                        switch (level) {
@@ -530,12 +455,14 @@ rspamd_common_logv (rspamd_logger_t *rspamd_log, gint level_flags,
                        }
                }
        }
+
+       return ret;
 }
 
 /**
  * This log functions select real logger and write message if level is less or equal to configured log level
  */
-void
+bool
 rspamd_common_log_function (rspamd_logger_t *rspamd_log,
                gint level_flags,
                const gchar *module, const gchar *id,
@@ -546,19 +473,21 @@ rspamd_common_log_function (rspamd_logger_t *rspamd_log,
        va_list vp;
 
        va_start (vp, fmt);
-       rspamd_common_logv (rspamd_log, level_flags, module, id, function, fmt, vp);
+       bool ret = rspamd_common_logv (rspamd_log, level_flags, module, id, function, fmt, vp);
        va_end (vp);
+
+       return ret;
 }
 
-void
+bool
 rspamd_default_logv (gint level_flags, const gchar *module, const gchar *id,
                const gchar *function,
                const gchar *fmt, va_list args)
 {
-       rspamd_common_logv (NULL, level_flags, module, id, function, fmt, args);
+       return rspamd_common_logv (NULL, level_flags, module, id, function, fmt, args);
 }
 
-void
+bool
 rspamd_default_log_function (gint level_flags,
                const gchar *module, const gchar *id,
                const gchar *function, const gchar *fmt, ...)
@@ -567,64 +496,20 @@ rspamd_default_log_function (gint level_flags,
        va_list vp;
 
        va_start (vp, fmt);
-       rspamd_default_logv (level_flags, module, id, function, fmt, vp);
+       bool ret = rspamd_default_logv (level_flags, module, id, function, fmt, vp);
        va_end (vp);
-}
-
-
-/**
- * Syslog interface for logging
- */
-static void
-syslog_log_function (const gchar *module, const gchar *id,
-               const gchar *function,
-               gint level_flags,
-               const gchar *message,
-               gsize mlen,
-               rspamd_logger_t *rspamd_log,
-               gpointer arg)
-{
-#ifdef HAVE_SYSLOG_H
-       struct {
-               GLogLevelFlags glib_level;
-               gint syslog_level;
-       } levels_match[] = {
-                       {G_LOG_LEVEL_DEBUG, LOG_DEBUG},
-                       {G_LOG_LEVEL_INFO, LOG_INFO},
-                       {G_LOG_LEVEL_WARNING, LOG_WARNING},
-                       {G_LOG_LEVEL_CRITICAL, LOG_ERR}
-       };
-       unsigned i;
-       gint syslog_level;
-
-       if (!(level_flags & RSPAMD_LOG_FORCED) && !rspamd_log->enabled) {
-               return;
-       }
-       /* Detect level */
-       syslog_level = LOG_DEBUG;
 
-       for (i = 0; i < G_N_ELEMENTS (levels_match); i ++) {
-               if (level_flags & levels_match[i].glib_level) {
-                       syslog_level = levels_match[i].syslog_level;
-                       break;
-               }
-       }
-
-       syslog (syslog_level, "<%.*s>; %s; %s: %*.s",
-                       LOG_ID, id != NULL ? id : "",
-                       module != NULL ? module : "",
-                       function != NULL ? function : "",
-                       (gint)mlen, message);
-#endif
+       return ret;
 }
 
+
 /**
  * Main file interface for logging
  */
 /**
  * Write log line depending on ip
  */
-void
+bool
 rspamd_conditional_debug (rspamd_logger_t *rspamd_log,
                rspamd_inet_addr_t *addr, const gchar *module, const gchar *id,
                const gchar *function, const gchar *fmt, ...)
@@ -645,7 +530,7 @@ rspamd_conditional_debug (rspamd_logger_t *rspamd_log,
                if (rspamd_log->debug_ip && addr != NULL) {
                        if (rspamd_match_radix_map_addr (rspamd_log->debug_ip,
                                        addr) == NULL) {
-                               return;
+                               return false;
                        }
                }
 
@@ -653,17 +538,19 @@ rspamd_conditional_debug (rspamd_logger_t *rspamd_log,
                end = rspamd_vsnprintf (logbuf, sizeof (logbuf), fmt, vp);
                *end = '\0';
                va_end (vp);
-               rspamd_log->log_func (module, id,
+               return rspamd_log->ops.log (module, id,
                                function,
                                G_LOG_LEVEL_DEBUG | RSPAMD_LOG_FORCED,
                                logbuf,
                                end - logbuf,
                                rspamd_log,
-                               rspamd_log->log_arg);
+                               rspamd_log->ops.specific);
        }
+
+       return false;
 }
 
-void
+bool
 rspamd_conditional_debug_fast (rspamd_logger_t *rspamd_log,
                rspamd_inet_addr_t *addr,
                guint mod_id, const gchar *module, const gchar *id,
@@ -682,7 +569,7 @@ rspamd_conditional_debug_fast (rspamd_logger_t *rspamd_log,
                if (rspamd_log->debug_ip && addr != NULL) {
                        if (rspamd_match_radix_map_addr (rspamd_log->debug_ip, addr)
                                        == NULL) {
-                               return;
+                               return false;
                        }
                }
 
@@ -690,17 +577,19 @@ rspamd_conditional_debug_fast (rspamd_logger_t *rspamd_log,
                end = rspamd_vsnprintf (logbuf, sizeof (logbuf), fmt, vp);
                *end = '\0';
                va_end (vp);
-               rspamd_log->log_func (module, id,
+               return rspamd_log->ops.log (module, id,
                                function,
                                G_LOG_LEVEL_DEBUG | RSPAMD_LOG_FORCED,
                                logbuf,
                                end - logbuf,
                                rspamd_log,
-                               rspamd_log->log_arg);
+                               rspamd_log->ops.specific);
        }
+
+       return false;
 }
 
-void
+bool
 rspamd_conditional_debug_fast_num_id (rspamd_logger_t *rspamd_log,
                                                           rspamd_inet_addr_t *addr,
                                                           guint mod_id, const gchar *module, guint64 id,
@@ -719,7 +608,7 @@ rspamd_conditional_debug_fast_num_id (rspamd_logger_t *rspamd_log,
                if (rspamd_log->debug_ip && addr != NULL) {
                        if (rspamd_match_radix_map_addr (rspamd_log->debug_ip, addr)
                                == NULL) {
-                               return;
+                               return false;
                        }
                }
 
@@ -728,14 +617,16 @@ rspamd_conditional_debug_fast_num_id (rspamd_logger_t *rspamd_log,
                end = rspamd_vsnprintf (logbuf, sizeof (logbuf), fmt, vp);
                *end = '\0';
                va_end (vp);
-               rspamd_log->log_func (module, idbuf,
+               return rspamd_log->ops.log (module, idbuf,
                                function,
                                G_LOG_LEVEL_DEBUG | RSPAMD_LOG_FORCED,
                                logbuf,
                                end - logbuf,
                                rspamd_log,
-                               rspamd_log->log_arg);
+                               rspamd_log->ops.specific);
        }
+
+       return false;
 }
 
 /**
@@ -751,13 +642,13 @@ rspamd_glib_log_function (const gchar *log_domain,
 
        if (rspamd_log->enabled &&
                        rspamd_logger_need_log (rspamd_log, log_level, -1)) {
-               rspamd_log->log_func ("glib", NULL,
+               rspamd_log->ops.log ("glib", NULL,
                                NULL,
                                log_level,
                                message,
                                strlen (message),
                                rspamd_log,
-                               rspamd_log->log_arg);
+                               rspamd_log->ops.specific);
        }
 }
 
@@ -951,26 +842,8 @@ rspamd_logger_configure_modules (GHashTable *mods_enabled)
        }
 }
 
-rspamd_logger_t*
-rspamd_logger_get_singleton (void)
-{
-       return default_logger;
-}
-
 struct rspamd_logger_funcs*
 rspamd_logger_set_log_function (rspamd_logger_t *logger,
-                                                               struct rspamd_logger_funcs *nfuncs);
+                                                               struct rspamd_logger_funcs *nfuncs)
 {
-       if (logger == NULL) {
-               logger = default_logger;
-       }
-
-       g_assert (logger != NULL);
-
-       rspamd_log_func_t old_func = logger->log_func;
-
-       logger->log_func = nfunc;
-       logger->log_arg = narg;
-
-       return old_func;
 }
\ No newline at end of file
index e98905f764984273f07f4573dfc0c929b82f480c..f8ecbf1ee6a056239a1deea53cea3e9ba31f0ed8 100644 (file)
@@ -33,6 +33,10 @@ typedef void * (*rspamd_log_init_func) (rspamd_logger_t *logger,
                                                                                struct rspamd_config *cfg,
                                                                                uid_t uid, gid_t gid,
                                                                                GError **err);
+typedef bool (*rspamd_log_on_fork_func) (rspamd_logger_t *logger,
+                                                                                struct rspamd_config *cfg,
+                                                                                gpointer arg,
+                                                                                GError **err);
 typedef void* (*rspamd_log_reload_func) (rspamd_logger_t *logger,
                                                                                struct rspamd_config *cfg,
                                                                                gpointer arg,
@@ -46,59 +50,74 @@ struct rspamd_logger_funcs {
        rspamd_log_reload_func reload;
        rspamd_log_dtor_func dtor;
        rspamd_log_func_t log;
+       rspamd_log_on_fork_func on_fork;
        gpointer specific;
 };
 
 #define RSPAMD_LOGBUF_SIZE 8192
 
 /**
- * Init logger
+ * Opens a new (initial) logger with console type
+ * This logger is also used as an emergency logger
+ * @return new rspamd logger object
  */
-void rspamd_set_logger (struct rspamd_config *cfg,
-                                               GQuark ptype,
-                                               rspamd_logger_t **plogger,
-                                               rspamd_mempool_t *pool);
+rspamd_logger_t * rspamd_log_open_emergency (rspamd_mempool_t *pool);
 
 /**
- * Open log file or initialize other structures
+ * Open specific (configured logging)
+ * @param pool
+ * @param config
+ * @param uid
+ * @param gid
+ * @return
  */
-bool rspamd_log_open (rspamd_logger_t *logger);
+rspamd_logger_t * rspamd_log_open_specific (rspamd_mempool_t *pool,
+                                                                                       struct rspamd_config *config,
+                                                                                       const gchar *ptype,
+                                                                                       uid_t uid, gid_t gid);
 
 /**
- * Close log file or destroy other structures
+ * Set log level (from GLogLevelFlags)
+ * @param logger
+ * @param level
  */
-bool rspamd_log_close (rspamd_logger_t *logger, gboolean termination);
-
+void rspamd_log_set_log_level (rspamd_logger_t *logger, gint level);
 /**
- * Close and open log again
+ * Set log flags (from enum rspamd_log_flags)
+ * @param logger
+ * @param flags
  */
-bool rspamd_log_reopen (rspamd_logger_t *logger);
+void rspamd_log_set_log_flags (rspamd_logger_t *logger, gint flags);
 
 /**
- * Open log file or initialize other structures for privileged processes
+ * Close log file or destroy other structures
  */
-bool rspamd_log_open_priv (rspamd_logger_t *logger, uid_t uid, gid_t gid);
+void rspamd_log_close (rspamd_logger_t *logger);
+
 
-/**
- * Close log file or destroy other structures for privileged processes
- */
-void rspamd_log_close_priv (rspamd_logger_t *logger, gboolean termination, uid_t uid, gid_t gid);
+
+rspamd_logger_t * rspamd_log_default_logger (void);
+rspamd_logger_t * rspamd_log_emergency_logger (void);
 
 /**
  * Close and open log again for privileged processes
  */
-bool rspamd_log_reopen_priv (rspamd_logger_t *logger, uid_t uid, gid_t gid);
+bool rspamd_log_reopen (rspamd_logger_t *logger, struct rspamd_config *cfg,
+                                               uid_t uid, gid_t gid);
 
 /**
  * Set log pid
  */
-void rspamd_log_update_pid (GQuark ptype, rspamd_logger_t *logger);
+void rspamd_log_on_fork (GQuark ptype, struct rspamd_config *cfg,
+                                                rspamd_logger_t *logger);
 
 /**
  * Log function that is compatible for glib messages
  */
 void rspamd_glib_log_function (const gchar *log_domain,
-                                                          GLogLevelFlags log_level, const gchar *message, gpointer arg);
+                                                          GLogLevelFlags log_level,
+                                                          const gchar *message,
+                                                          gpointer arg);
 
 /**
  * Log function for printing glib assertions
@@ -207,12 +226,6 @@ const guint64 *rspamd_log_counters (rspamd_logger_t *logger);
  */
 ucl_object_t *rspamd_log_errorbuf_export (const rspamd_logger_t *logger);
 
-/**
- * Returns the current logger object
- * @return
- */
-rspamd_logger_t *rspamd_logger_get_singleton (void);
-
 /**
  * Sets new logger functions and initialise logging if needed
  * @param logger
index c410bdd795ecd040a21638585ce998e3db979eab..fae12ea1186def8130a8e75bfb0f4d4a1dd97d42 100644 (file)
@@ -63,7 +63,7 @@ rspamd_log_console_init (rspamd_logger_t *logger, struct rspamd_config *cfg,
 
        priv = g_malloc0 (sizeof (*priv));
        priv->log_color = (logger->flags & RSPAMD_LOG_FLAG_COLOR);
-       priv->log_rspamadm (logger->flags & RSPAMD_LOG_FLAG_RSPAMADM);
+       priv->log_rspamadm (logger->flags & RSPAMD_LOG_FLAG_RSPAMADM);
 
        if (priv->log_rspamadm) {
                priv->fd = dup (STDOUT_FILENO);
@@ -78,7 +78,7 @@ rspamd_log_console_init (rspamd_logger_t *logger, struct rspamd_config *cfg,
                g_set_error (err, CONSOLE_LOG_QUARK, errno,
                                "open_log: cannot dup console fd: %s, %s\n",
                                strerror (errno));
-               rspamd_log_console_dtor (priv);
+               rspamd_log_console_dtor (logger, priv);
 
                return NULL;
        }
index b4bb6208b6ddcb86b6f92f0f051baaf2fbe2cb48..9a242ac619b807ff097a0838c4812fad9abd1ce2 100644 (file)
@@ -261,44 +261,42 @@ rspamd_log_reset_repeated (rspamd_logger_t *rspamd_log,
        gchar tmpbuf[256];
        gssize r;
 
-       if (rspamd_log->opened) {
-               if (priv->repeats > REPEATS_MIN) {
-                       r = rspamd_snprintf (tmpbuf,
-                                       sizeof (tmpbuf),
-                                       "Last message repeated %ud times",
-                                       priv->repeats - REPEATS_MIN);
-                       priv->repeats = 0;
-
-                       if (priv->saved_message) {
-                               rspamd_log_file_log (priv->saved_module,
-                                               priv->saved_id,
-                                               priv->saved_function,
-                                               priv->saved_loglevel | RSPAMD_LOG_FORCED,
-                                               priv->saved_message,
-                                               priv->saved_mlen,
-                                               rspamd_log,
-                                               priv);
-
-                               g_free (priv->saved_message);
-                               g_free (priv->saved_function);
-                               g_free (priv->saved_module);
-                               g_free (priv->saved_id);
-                               priv->saved_message = NULL;
-                               priv->saved_function = NULL;
-                               priv->saved_module = NULL;
-                               priv->saved_id = NULL;
-                       }
-
-                       /* It is safe to use temporary buffer here as it is not static */
-                       rspamd_log_file_log (NULL, NULL,
-                                       G_STRFUNC,
+       if (priv->repeats > REPEATS_MIN) {
+               r = rspamd_snprintf (tmpbuf,
+                               sizeof (tmpbuf),
+                               "Last message repeated %ud times",
+                               priv->repeats - REPEATS_MIN);
+               priv->repeats = 0;
+
+               if (priv->saved_message) {
+                       rspamd_log_file_log (priv->saved_module,
+                                       priv->saved_id,
+                                       priv->saved_function,
                                        priv->saved_loglevel | RSPAMD_LOG_FORCED,
-                                       tmpbuf,
-                                       r,
+                                       priv->saved_message,
+                                       priv->saved_mlen,
                                        rspamd_log,
                                        priv);
-                       rspamd_log_flush (rspamd_log, priv);
+
+                       g_free (priv->saved_message);
+                       g_free (priv->saved_function);
+                       g_free (priv->saved_module);
+                       g_free (priv->saved_id);
+                       priv->saved_message = NULL;
+                       priv->saved_function = NULL;
+                       priv->saved_module = NULL;
+                       priv->saved_id = NULL;
                }
+
+               /* It is safe to use temporary buffer here as it is not static */
+               rspamd_log_file_log (NULL, NULL,
+                               G_STRFUNC,
+                               priv->saved_loglevel | RSPAMD_LOG_FORCED,
+                               tmpbuf,
+                               r,
+                               rspamd_log,
+                               priv);
+               rspamd_log_flush (rspamd_log, priv);
        }
 }
 
@@ -340,7 +338,7 @@ rspamd_log_file_init (rspamd_logger_t *logger, struct rspamd_config *cfg,
 {
        struct rspamd_file_logger_priv *priv;
 
-       if (!cfg->cfg_name) {
+       if (!cfg || !cfg->cfg_name) {
                g_set_error (err, FILE_LOG_QUARK, EINVAL,
                                "no log file specified");
                return NULL;
@@ -585,3 +583,15 @@ rspamd_log_file_reload (rspamd_logger_t *logger, struct rspamd_config *cfg,
 
        return npriv;
 }
+
+bool
+rspamd_log_file_on_fork (rspamd_logger_t *logger, struct rspamd_config *cfg,
+                                                         gpointer arg, GError **err)
+{
+       struct rspamd_file_logger_priv *priv = (struct rspamd_file_logger_priv *)arg;
+
+       rspamd_log_reset_repeated (logger, priv);
+       rspamd_log_flush (logger, priv);
+
+       return true;
+}
\ No newline at end of file
index 84ec3b026d3a0628f315e59bdb8bab39db397267..f4b6fe8d6f079787a0aa7ab941de004fa734d8d3 100644 (file)
@@ -70,12 +70,12 @@ struct rspamd_logger_s {
        gboolean enabled;
        gboolean is_debug;
        gboolean no_lock;
-       gboolean opened;
 
        pid_t pid;
        const gchar *process_type;
        struct rspamd_radix_map_helper *debug_ip;
        rspamd_mempool_mutex_t *mtx;
+       rspamd_mempool_t *pool;
        guint64 log_cnt[4];
 };
 
@@ -98,12 +98,15 @@ bool rspamd_log_file_log (const gchar *module, const gchar *id,
                                                  gsize mlen,
                                                  rspamd_logger_t *rspamd_log,
                                                  gpointer arg);
+bool rspamd_log_file_on_fork (rspamd_logger_t *logger, struct rspamd_config *cfg,
+                                                          gpointer arg, GError **err);
 
 const static struct rspamd_logger_funcs file_log_funcs = {
                .init = rspamd_log_file_init,
                .dtor = rspamd_log_file_dtor,
                .reload = rspamd_log_file_reload,
                .log = rspamd_log_file_log,
+               .on_fork = rspamd_log_file_on_fork,
 };
 
 /*
@@ -127,6 +130,7 @@ const static struct rspamd_logger_funcs syslog_log_funcs = {
                .dtor = rspamd_log_syslog_dtor,
                .reload = rspamd_log_syslog_reload,
                .log = rspamd_log_syslog_log,
+               .on_fork = NULL,
 };
 
 /*
@@ -150,6 +154,7 @@ const static struct rspamd_logger_funcs console_log_funcs = {
                .dtor = rspamd_log_console_dtor,
                .reload = rspamd_log_console_reload,
                .log = rspamd_log_console_log,
+               .on_fork = NULL,
 };
 
 #endif
index 15afabdb9ffb9fc547ec64eb767331e061fc08a8..5a295b288df553c19be9f7a9eeb43bd289b700c2 100644 (file)
@@ -34,6 +34,12 @@ rspamd_log_syslog_init (rspamd_logger_t *logger, struct rspamd_config *cfg,
 {
        struct rspamd_syslog_logger_priv *priv;
 
+       if (!cfg) {
+               g_set_error (err, SYSLOG_LOG_QUARK, EINVAL,
+                               "no log config specified");
+               return NULL;
+       }
+
        priv = g_malloc0 (sizeof (*priv));
 
        priv->log_facility = cfg->log_facility;
index 24487f1b565709f4261889e6479c45cb4150da60..7f993e777d27c896cceb6dc1a678c5c7aa67aee3 100644 (file)
@@ -4299,7 +4299,7 @@ lua_config_init_subsystem (lua_State *L)
                                struct ev_loop *ev_base = lua_check_ev_base (L, 3);
 
                                if (ev_base) {
-                                       cfg->dns_resolver = rspamd_dns_resolver_init (rspamd_logger_get_singleton (),
+                                       cfg->dns_resolver = rspamd_dns_resolver_init (rspamd_log_default_logger (),
                                                        ev_base,
                                                        cfg);
                                }
index 4c355788b25a3174c424b4acc28eb94bc6434cd2..108b2299694dec72a56119db637d4436707aa7c2 100644 (file)
@@ -1237,7 +1237,7 @@ main (gint argc, gchar **argv, gchar **env)
        type = g_quark_from_static_string ("main");
 
        /* First set logger to console logger */
-       rspamd_main->cfg->log_type = RSPAMD_LOG_CONSOLE;
+       rspamd_main->logger = rspamd_log_init (rspamd_main->server_pool);
        rspamd_set_logger (rspamd_main->cfg, type,
                        &rspamd_main->logger, rspamd_main->server_pool);
        (void) rspamd_log_open (rspamd_main->logger);
@@ -1338,9 +1338,6 @@ main (gint argc, gchar **argv, gchar **env)
        /* Set title */
        setproctitle ("main process");
 
-       /* Flush log */
-       rspamd_log_flush (rspamd_main->logger);
-
        /* Open control socket if needed */
        control_fd = -1;
        if (rspamd_main->cfg->control_socket_path) {