From: Timo Sirainen Date: Wed, 22 Nov 2017 14:41:51 +0000 (+0100) Subject: lib-master: Add log_debug setting X-Git-Tag: 2.3.0.rc1~97 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1fd856f1177990003ec3829267b9e490c095d836;p=thirdparty%2Fdovecot%2Fcore.git lib-master: Add log_debug setting 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. --- diff --git a/src/lib-master/master-interface.h b/src/lib-master/master-interface.h index 5b1f01222e..821aa02b5a 100644 --- a/src/lib-master/master-interface.h +++ b/src/lib-master/master-interface.h @@ -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 */ diff --git a/src/lib-master/master-service-settings.c b/src/lib-master/master-service-settings.c index 36d3515208..51ed220861 100644 --- a/src/lib-master/master-service-settings.c +++ b/src/lib-master/master-service-settings.c @@ -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 = { }; /* */ +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; } /* */ diff --git a/src/lib-master/master-service-settings.h b/src/lib-master/master-service-settings.h index 67ae9bcade..4cd6182138 100644 --- a/src/lib-master/master-service-settings.h +++ b/src/lib-master/master-service-settings.h @@ -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 diff --git a/src/lib-master/master-service.c b/src/lib-master/master-service.c index c2d6890206..cf26023bbe 100644 --- a/src/lib-master/master-service.c +++ b/src/lib-master/master-service.c @@ -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); diff --git a/src/master/service-process.c b/src/master/service-process.c index 5dcac81238..50eb1b12e2 100644 --- a/src/master/service-process.c +++ b/src/master/service-process.c @@ -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)