]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-master: Add log_debug setting
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Wed, 22 Nov 2017 14:41:51 +0000 (15:41 +0100)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Wed, 13 Dec 2017 11:22:17 +0000 (13:22 +0200)
lib-master understands only the global log_debug setting, which is passed
to it via environment from master process, or alternatively via doveconf
when executing standalone programs. Any per-user log_debug settings need
to be handled explicitly elsewhere.

src/lib-master/master-interface.h
src/lib-master/master-service-settings.c
src/lib-master/master-service-settings.h
src/lib-master/master-service.c
src/master/service-process.c

index 5b1f01222eb2c89928e3e8be214ac0989611bf1d..821aa02b5a3f28207cb2aa7910aec0f7cc4c241b 100644 (file)
@@ -75,6 +75,10 @@ enum master_login_state {
    environments that should be preserved. */
 #define DOVECOT_PRESERVE_ENVS_ENV "DOVECOT_PRESERVE_ENVS"
 
+/* getenv(DOVECOT_LOG_DEBUG_ENV) returns the global log_debug setting. This can
+   be used to initialize debug logging immediately at startup. */
+#define DOVECOT_LOG_DEBUG_ENV "LOG_DEBUG"
+
 /* Write pipe to anvil. */
 #define MASTER_ANVIL_FD 3
 /* Anvil reads new log fds from this fd */
index 36d351520800205c24b475b81d9bc617aa7ddb47..51ed220861ab407d8f98e0762a6bedc2f83e6d68 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "lib.h"
 #include "array.h"
+#include "event-filter.h"
 #include "path-util.h"
 #include "istream.h"
 #include "write-full.h"
@@ -41,6 +42,7 @@ static const struct setting_define master_service_setting_defines[] = {
        DEF(SET_STR, info_log_path),
        DEF(SET_STR, debug_log_path),
        DEF(SET_STR, log_timestamp),
+       DEF(SET_STR, log_debug),
        DEF(SET_STR, syslog_facility),
        DEF(SET_STR, import_environment),
        DEF(SET_SIZE, config_cache_size),
@@ -74,6 +76,7 @@ static const struct master_service_settings master_service_default_settings = {
        .info_log_path = "",
        .debug_log_path = "",
        .log_timestamp = DEFAULT_FAILURE_STAMP_FORMAT,
+       .log_debug = "",
        .syslog_facility = "mail",
        .import_environment = "TZ CORE_OUTOFMEM CORE_ERROR" ENV_SYSTEMD ENV_GDB,
        .config_cache_size = 1024*1024,
@@ -98,6 +101,24 @@ const struct setting_parser_info master_service_setting_parser_info = {
 };
 
 /* <settings checks> */
+int master_service_log_debug_parse(struct event_filter *filter, const char *str,
+                                  const char **error_r)
+{
+       const char *categories[2] = { NULL, NULL };
+       struct event_filter_query query = {
+               .categories = categories
+       };
+
+       /* FIXME: we should support more complicated filters */
+       const char *const *args = t_strsplit_spaces(str, " ");
+       for (unsigned int i = 0; args[i] != NULL; i++) {
+               categories[0] = args[i];
+               event_filter_add(filter, &query);
+       }
+       *error_r = NULL;
+       return 0;
+}
+
 static bool
 master_service_settings_check(void *_set, pool_t pool ATTR_UNUSED,
                              const char **error_r)
@@ -114,6 +135,17 @@ master_service_settings_check(void *_set, pool_t pool ATTR_UNUSED,
                                           set->syslog_facility);
                return FALSE;
        }
+       struct event_filter *filter = event_filter_create();
+       const char *error;
+       if (master_service_log_debug_parse(filter, set->log_debug, &error) < 0) {
+               *error_r = t_strdup_printf("Invalid log_debug: %s", error);
+               event_filter_unref(&filter);
+               return FALSE;
+       }
+#ifndef CONFIG_BINARY
+       event_set_global_debug_log_filter(filter);
+#endif
+       event_filter_unref(&filter);
        return TRUE;
 }
 /* </settings checks> */
index 67ae9bcade1471cc15ab151579cdb441bd558ca3..4cd618213873d0c3e3af93f020289d131a447e73 100644 (file)
@@ -14,6 +14,7 @@ struct master_service_settings {
        const char *info_log_path;
        const char *debug_log_path;
        const char *log_timestamp;
+       const char *log_debug;
        const char *syslog_facility;
        const char *import_environment;
        uoff_t config_cache_size;
@@ -94,4 +95,8 @@ int master_service_set(struct master_service *service, const char *line);
 bool master_service_set_has_config_override(struct master_service *service,
                                            const char *key);
 
+/* Parse log_debug setting into an event filter. */
+int master_service_log_debug_parse(struct event_filter *filter, const char *str,
+                                  const char **error_r);
+
 #endif
index c2d689020696f27ed3fe7dd405b79c07645aa384..cf26023bbec6eabfd1b9b72c386bc6a5a0c102f1 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "lib.h"
 #include "lib-signals.h"
+#include "event-filter.h"
 #include "ioloop.h"
 #include "path-util.h"
 #include "array.h"
@@ -272,6 +273,19 @@ master_service_init(const char *name, enum master_service_flags flags,
        else
                i_set_failure_prefix("%s: ", name);
 
+       /* Initialize debug logging */
+       value = getenv(DOVECOT_LOG_DEBUG_ENV);
+       if (value != NULL) {
+               struct event_filter *filter = event_filter_create();
+               const char *error;
+               if (master_service_log_debug_parse(filter, value, &error) < 0) {
+                       i_error("Invalid "DOVECOT_LOG_DEBUG_ENV" - ignoring: %s",
+                               error);
+               }
+               event_set_global_debug_filter(filter);
+               event_filter_unref(&filter);
+       }
+
        if ((flags & MASTER_SERVICE_FLAG_STANDALONE) == 0) {
                /* initialize master_status structure */
                value = getenv(MASTER_UID_ENV);
index 5dcac81238ae71ad42d2c677bf19052b60a2052f..50eb1b12e29a4118aea8dc876b2b2ebdde637816 100644 (file)
@@ -262,6 +262,8 @@ service_process_setup_environment(struct service *service, unsigned int uid,
        if (service->type == SERVICE_TYPE_ANVIL &&
            service_anvil_global->restarted)
                env_put("ANVIL_RESTARTED=1");
+       env_put(t_strconcat(DOVECOT_LOG_DEBUG_ENV"=",
+                           service->list->service_set->log_debug, NULL));
 }
 
 static void service_process_status_timeout(struct service_process *process)