Mercurial > dovecot > core-2.2
changeset 12275:4933c3095ee2
Cleaned up log callbacks and made them more extensible.
fatal_failure_callback_t type is now gone, there's only failure_callback_t
left that has a struct pointer as parameter. More parameters can be easily
added to the struct in future.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Fri, 15 Oct 2010 15:46:43 +0100 |
parents | b0e4edc4d79a |
children | e68366e88099 |
files | src/doveadm/doveadm-log.c src/lib-test/test-common.c src/lib/failures.c src/lib/failures.h src/log/log-connection.c src/master/main.c |
diffstat | 6 files changed, 119 insertions(+), 69 deletions(-) [+] |
line wrap: on
line diff
--- a/src/doveadm/doveadm-log.c Fri Oct 15 15:13:59 2010 +0100 +++ b/src/doveadm/doveadm-log.c Fri Oct 15 15:46:43 2010 +0100 @@ -21,17 +21,20 @@ static void cmd_log_test(int argc ATTR_UNUSED, char *argv[] ATTR_UNUSED) { + struct failure_context ctx; unsigned int i; master_service->flags |= MASTER_SERVICE_FLAG_DONT_LOG_TO_STDERR; master_service_init_log(master_service, "doveadm: "); + memset(&ctx, 0, sizeof(ctx)); for (i = 0; i < LAST_LOG_TYPE; i++) { const char *prefix = failure_log_type_prefixes[i]; /* add timestamp so that syslog won't just write "repeated message" text */ - i_log_type(i, TEST_LOG_MSG_PREFIX"%s log (%u)", + ctx.type = i; + i_log_type(&ctx, TEST_LOG_MSG_PREFIX"%s log (%u)", t_str_lcase(t_strcut(prefix, ':')), (unsigned int)ioloop_time); }
--- a/src/lib-test/test-common.c Fri Oct 15 15:13:59 2010 +0100 +++ b/src/lib-test/test-common.c Fri Oct 15 15:46:43 2010 +0100 @@ -186,11 +186,13 @@ } static void -test_error_handler(enum log_type type, const char *format, va_list args) +test_error_handler(const struct failure_context *ctx, + const char *format, va_list args) { - default_error_handler(type, format, args); + default_error_handler(ctx, format, args); #ifdef DEBUG - if (type == LOG_TYPE_WARNING && strstr(format, "Growing") != NULL) { + if (ctx->type == LOG_TYPE_WARNING && + strstr(format, "Growing") != NULL) { /* ignore "Growing memory pool" and "Growing data stack" warnings */ return;
--- a/src/lib/failures.c Fri Oct 15 15:13:59 2010 +0100 +++ b/src/lib/failures.c Fri Oct 15 15:46:43 2010 +0100 @@ -27,20 +27,26 @@ }; /* Initialize working defaults */ -static fatal_failure_callback_t *fatal_handler ATTR_NORETURN = +static failure_callback_t *fatal_handler ATTR_NORETURN = default_fatal_handler; static failure_callback_t *error_handler = default_error_handler; static failure_callback_t *info_handler = default_error_handler; static failure_callback_t *debug_handler = default_error_handler; static void (*failure_exit_callback)(int *) = NULL; +static struct failure_context failure_ctx_debug = { .type = LOG_TYPE_DEBUG }; +static struct failure_context failure_ctx_info = { .type = LOG_TYPE_INFO }; +static struct failure_context failure_ctx_warning = { .type = LOG_TYPE_WARNING }; +static struct failure_context failure_ctx_error = { .type = LOG_TYPE_ERROR }; + static int log_fd = STDERR_FILENO, log_info_fd = STDERR_FILENO, log_debug_fd = STDERR_FILENO; static char *log_prefix = NULL, *log_stamp_format = NULL; static bool failure_ignore_errors = FALSE; static void ATTR_FORMAT(2, 0) -i_internal_error_handler(enum log_type type, const char *fmt, va_list args); +i_internal_error_handler(const struct failure_context *ctx, + const char *format, va_list args); /* kludgy .. we want to trust log_stamp_format with -Wformat-nonliteral */ static const char *get_log_stamp_format(const char *unused) @@ -180,21 +186,25 @@ failure_exit(status); } -void default_fatal_handler(enum log_type type, int status, +void default_fatal_handler(const struct failure_context *ctx, const char *format, va_list args) { - if (default_handler(failure_log_type_prefixes[type], log_fd, format, - args) < 0 && status == FATAL_DEFAULT) + int status = ctx->exit_status; + + if (default_handler(failure_log_type_prefixes[ctx->type], + log_fd, format, args) < 0 && + status == FATAL_DEFAULT) status = FATAL_LOGWRITE; - default_fatal_finish(type, status); + default_fatal_finish(ctx->type, status); } -void default_error_handler(enum log_type type, const char *format, va_list args) +void default_error_handler(const struct failure_context *ctx, + const char *format, va_list args) { int fd; - switch (type) { + switch (ctx->type) { case LOG_TYPE_DEBUG: fd = log_debug_fd; break; @@ -205,7 +215,7 @@ fd = log_fd; } - if (default_handler(failure_log_type_prefixes[type], + if (default_handler(failure_log_type_prefixes[ctx->type], fd, format, args) < 0) { if (fd == log_fd) failure_exit(FATAL_LOGWRITE); @@ -216,21 +226,21 @@ } } -void i_log_type(enum log_type type, const char *format, ...) +void i_log_type(const struct failure_context *ctx, const char *format, ...) { va_list args; va_start(args, format); - switch (type) { + switch (ctx->type) { case LOG_TYPE_DEBUG: - debug_handler(type, format, args); + debug_handler(ctx, format, args); break; case LOG_TYPE_INFO: - info_handler(type, format, args); + info_handler(ctx, format, args); break; default: - error_handler(type, format, args); + error_handler(ctx, format, args); } va_end(args); @@ -238,28 +248,42 @@ void i_panic(const char *format, ...) { + struct failure_context ctx; va_list args; + memset(&ctx, 0, sizeof(ctx)); + ctx.type = LOG_TYPE_PANIC; + va_start(args, format); - fatal_handler(LOG_TYPE_PANIC, 0, format, args); + fatal_handler(&ctx, format, args); va_end(args); } void i_fatal(const char *format, ...) { + struct failure_context ctx; va_list args; + memset(&ctx, 0, sizeof(ctx)); + ctx.type = LOG_TYPE_FATAL; + ctx.exit_status = FATAL_DEFAULT; + va_start(args, format); - fatal_handler(LOG_TYPE_FATAL, FATAL_DEFAULT, format, args); + fatal_handler(&ctx, format, args); va_end(args); } void i_fatal_status(int status, const char *format, ...) { + struct failure_context ctx; va_list args; + memset(&ctx, 0, sizeof(ctx)); + ctx.type = LOG_TYPE_FATAL; + ctx.exit_status = status; + va_start(args, format); - fatal_handler(LOG_TYPE_FATAL, status, format, args); + fatal_handler(&ctx, format, args); va_end(args); } @@ -269,7 +293,7 @@ va_list args; va_start(args, format); - error_handler(LOG_TYPE_ERROR, format, args); + error_handler(&failure_ctx_error, format, args); va_end(args); errno = old_errno; @@ -281,7 +305,7 @@ va_list args; va_start(args, format); - error_handler(LOG_TYPE_WARNING, format, args); + error_handler(&failure_ctx_warning, format, args); va_end(args); errno = old_errno; @@ -293,7 +317,7 @@ va_list args; va_start(args, format); - info_handler(LOG_TYPE_INFO, format, args); + info_handler(&failure_ctx_info, format, args); va_end(args); errno = old_errno; @@ -305,13 +329,13 @@ va_list args; va_start(args, format); - debug_handler(LOG_TYPE_DEBUG, format, args); + debug_handler(&failure_ctx_debug, format, args); va_end(args); errno = old_errno; } -void i_set_fatal_handler(fatal_failure_callback_t *callback ATTR_NORETURN) +void i_set_fatal_handler(failure_callback_t *callback ATTR_NORETURN) { if (callback == NULL) callback = default_fatal_handler; @@ -339,7 +363,7 @@ debug_handler = callback; } -void i_get_failure_handlers(fatal_failure_callback_t **fatal_callback_r, +void i_get_failure_handlers(failure_callback_t **fatal_callback_r, failure_callback_t **error_callback_r, failure_callback_t **info_callback_r, failure_callback_t **debug_callback_r) @@ -372,21 +396,24 @@ return 0; } -void i_syslog_fatal_handler(enum log_type type, int status, - const char *fmt, va_list args) +void i_syslog_fatal_handler(const struct failure_context *ctx, + const char *format, va_list args) { - if (syslog_handler(LOG_CRIT, type, fmt, args) < 0 && + int status = ctx->exit_status; + + if (syslog_handler(LOG_CRIT, ctx->type, format, args) < 0 && status == FATAL_DEFAULT) status = FATAL_LOGERROR; - default_fatal_finish(type, status); + default_fatal_finish(ctx->type, status); } -void i_syslog_error_handler(enum log_type type, const char *fmt, va_list args) +void i_syslog_error_handler(const struct failure_context *ctx, + const char *format, va_list args) { int level = LOG_ERR; - switch (type) { + switch (ctx->type) { case LOG_TYPE_DEBUG: level = LOG_DEBUG; break; @@ -408,7 +435,7 @@ i_unreached(); } - if (syslog_handler(level, type, fmt, args) < 0) + if (syslog_handler(level, ctx->type, format, args) < 0) failure_exit(FATAL_LOGERROR); } @@ -511,7 +538,8 @@ str_truncate(str, prefix_len); str_append_n(str, str_c(full_str) + pos, max_text_len); str_append_c(str, '\n'); - if (log_fd_write(2, str_data(str), str_len(str)) < 0) + if (log_fd_write(STDERR_FILENO, + str_data(str), str_len(str)) < 0) return -1; pos += max_text_len; } @@ -519,7 +547,8 @@ } static int ATTR_FORMAT(2, 0) -internal_handler(enum log_type log_type, const char *format, va_list args) +internal_handler(const struct failure_context *ctx, + const char *format, va_list args) { static int recursed = 0; int ret; @@ -536,13 +565,14 @@ unsigned int prefix_len; str = t_str_new(128); - str_printfa(str, "\001%c%s ", log_type + 1, my_pid); + str_printfa(str, "\001%c%s ", ctx->type + 1, my_pid); prefix_len = str_len(str); str_vprintfa(str, format, args); if (str_len(str)+1 <= PIPE_BUF) { str_append_c(str, '\n'); - ret = log_fd_write(2, str_data(str), str_len(str)); + ret = log_fd_write(STDERR_FILENO, + str_data(str), str_len(str)); } else { ret = internal_send_split(str, prefix_len); } @@ -596,21 +626,24 @@ failure->text = line + 1; } -static void ATTR_NORETURN ATTR_FORMAT(3, 0) -i_internal_fatal_handler(enum log_type type, int status, - const char *fmt, va_list args) +static void ATTR_NORETURN ATTR_FORMAT(2, 0) +i_internal_fatal_handler(const struct failure_context *ctx, + const char *format, va_list args) { - if (internal_handler(type, fmt, args) < 0 && + int status = ctx->exit_status; + + if (internal_handler(ctx, format, args) < 0 && status == FATAL_DEFAULT) status = FATAL_LOGERROR; - default_fatal_finish(type, status); + default_fatal_finish(ctx->type, status); } static void -i_internal_error_handler(enum log_type type, const char *fmt, va_list args) +i_internal_error_handler(const struct failure_context *ctx, + const char *format, va_list args) { - if (internal_handler(type, fmt, args) < 0) + if (internal_handler(ctx, format, args) < 0) failure_exit(FATAL_LOGERROR); }
--- a/src/lib/failures.h Fri Oct 15 15:13:59 2010 +0100 +++ b/src/lib/failures.h Fri Oct 15 15:46:43 2010 +0100 @@ -32,15 +32,20 @@ const char *text; }; +struct failure_context { + enum log_type type; + int exit_status; /* for LOG_TYPE_FATAL */ +}; + #define DEFAULT_FAILURE_STAMP_FORMAT "%b %d %H:%M:%S " -typedef void failure_callback_t(enum log_type type, const char *, va_list); -typedef void fatal_failure_callback_t(enum log_type type, int status, - const char *, va_list); +typedef void failure_callback_t(const struct failure_context *ctx, + const char *format, va_list args); extern const char *failure_log_type_prefixes[]; -void i_log_type(enum log_type type, const char *format, ...) ATTR_FORMAT(2, 3); +void i_log_type(const struct failure_context *ctx, const char *format, ...) + ATTR_FORMAT(2, 3); void i_panic(const char *format, ...) ATTR_FORMAT(1, 2) ATTR_NORETURN ATTR_COLD; void i_fatal(const char *format, ...) ATTR_FORMAT(1, 2) ATTR_NORETURN ATTR_COLD; @@ -54,31 +59,33 @@ /* Change failure handlers. */ #ifndef __cplusplus -void i_set_fatal_handler(fatal_failure_callback_t *callback ATTR_NORETURN); +void i_set_fatal_handler(failure_callback_t *callback ATTR_NORETURN); #else /* Older g++ doesn't like attributes in parameters */ -void i_set_fatal_handler(fatal_failure_callback_t *callback); +void i_set_fatal_handler(failure_callback_t *callback); #endif void i_set_error_handler(failure_callback_t *callback); void i_set_info_handler(failure_callback_t *callback); void i_set_debug_handler(failure_callback_t *callback); -void i_get_failure_handlers(fatal_failure_callback_t **fatal_callback_r, +void i_get_failure_handlers(failure_callback_t **fatal_callback_r, failure_callback_t **error_callback_r, failure_callback_t **info_callback_r, failure_callback_t **debug_callback_r); /* Send failures to file. */ -void default_fatal_handler(enum log_type type, int status, +void default_fatal_handler(const struct failure_context *ctx, const char *format, va_list args) - ATTR_NORETURN ATTR_FORMAT(3, 0); -void default_error_handler(enum log_type type, const char *format, va_list args) + ATTR_NORETURN ATTR_FORMAT(2, 0); +void default_error_handler(const struct failure_context *ctx, + const char *format, va_list args) ATTR_FORMAT(2, 0); /* Send failures to syslog() */ -void i_syslog_fatal_handler(enum log_type type, int status, - const char *fmt, va_list args) - ATTR_NORETURN ATTR_FORMAT(3, 0); -void i_syslog_error_handler(enum log_type type, const char *fmt, va_list args) +void i_syslog_fatal_handler(const struct failure_context *ctx, + const char *format, va_list args) + ATTR_NORETURN ATTR_FORMAT(2, 0); +void i_syslog_error_handler(const struct failure_context *ctx, + const char *format, va_list args) ATTR_FORMAT(2, 0); /* Open syslog and set failure/info/debug handlers to use it. */
--- a/src/log/log-connection.c Fri Oct 15 15:13:59 2010 +0100 +++ b/src/log/log-connection.c Fri Oct 15 15:46:43 2010 +0100 @@ -125,6 +125,7 @@ static void log_it(struct log_connection *log, const char *line) { struct failure_line failure; + struct failure_context failure_ctx; struct log_client *client = NULL; const char *prefix; @@ -150,10 +151,13 @@ } i_assert(failure.log_type < LOG_TYPE_COUNT); + memset(&failure_ctx, 0, sizeof(failure_ctx)); + failure_ctx.type = failure.log_type; + prefix = client != NULL && client->prefix != NULL ? client->prefix : log->default_prefix; i_set_failure_prefix(prefix); - i_log_type(failure.log_type, "%s", failure.text); + i_log_type(&failure_ctx, "%s", failure.text); i_set_failure_prefix("log: "); }
--- a/src/master/main.c Fri Oct 15 15:13:59 2010 +0100 +++ b/src/master/main.c Fri Oct 15 15:46:43 2010 +0100 @@ -46,7 +46,7 @@ struct service_list *services; static char *pidfile_path; -static fatal_failure_callback_t *orig_fatal_callback; +static failure_callback_t *orig_fatal_callback; static failure_callback_t *orig_error_callback; static const char *child_process_env[3]; /* @UNSAFE */ @@ -125,7 +125,7 @@ } static void ATTR_NORETURN ATTR_FORMAT(3, 0) -master_fatal_callback(enum log_type type, int status, +master_fatal_callback(const struct failure_context *ctx, const char *format, va_list args) { const char *path, *str; @@ -147,32 +147,33 @@ } } - orig_fatal_callback(type, status, format, args); + orig_fatal_callback(ctx, format, args); abort(); /* just to silence the noreturn attribute warnings */ } static void ATTR_NORETURN -startup_fatal_handler(enum log_type type, int status, +startup_fatal_handler(const struct failure_context *ctx, const char *fmt, va_list args) { va_list args2; VA_COPY(args2, args); - fprintf(stderr, "%s%s\n", failure_log_type_prefixes[type], + fprintf(stderr, "%s%s\n", failure_log_type_prefixes[ctx->type], t_strdup_vprintf(fmt, args2)); - orig_fatal_callback(type, status, fmt, args); + orig_fatal_callback(ctx, fmt, args); abort(); } static void -startup_error_handler(enum log_type type, const char *fmt, va_list args) +startup_error_handler(const struct failure_context *ctx, + const char *fmt, va_list args) { va_list args2; VA_COPY(args2, args); - fprintf(stderr, "%s%s\n", failure_log_type_prefixes[type], + fprintf(stderr, "%s%s\n", failure_log_type_prefixes[ctx->type], t_strdup_vprintf(fmt, args2)); - orig_error_callback(type, fmt, args); + orig_error_callback(ctx, fmt, args); } static void fatal_log_check(const struct master_settings *set)