From: Stephan Bosch Date: Sun, 30 Jun 2019 09:41:58 +0000 (+0200) Subject: lib: lib-event - Add support for amending the event log message in a callback. X-Git-Tag: 2.3.9~399 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=51b5367db82de4055313bcbb9dddace1b76d3fb3;p=thirdparty%2Fdovecot%2Fcore.git lib: lib-event - Add support for amending the event log message in a callback. --- diff --git a/src/lib/event-log.c b/src/lib/event-log.c index b3f15bd16b..eb672ed1cb 100644 --- a/src/lib/event-log.c +++ b/src/lib/event-log.c @@ -95,18 +95,50 @@ void e_log(struct event *event, enum log_type level, } struct event_get_log_message_context { + const struct event_log_params *params; + string_t *log_prefix; + const char *message; bool replace_prefix; unsigned int type_pos; }; -static bool +static bool ATTR_FORMAT(3, 0) event_get_log_message(struct event *event, - struct event_get_log_message_context *glmctx) + struct event_get_log_message_context *glmctx, + const char *fmt, va_list args) { const char *prefix = event->log_prefix; bool ret = FALSE; + /* Call the message amendment callback for this event if there is one. + */ + if (event->log_message_callback != NULL) { + const char *in_message; + + /* construct the log message composed by children and arguments + */ + if (glmctx->message == NULL) { + str_vprintfa(glmctx->log_prefix, fmt, args); + in_message = str_c(glmctx->log_prefix); + } else if (str_len(glmctx->log_prefix) == 0) { + in_message = glmctx->message; + } else { + str_append(glmctx->log_prefix, glmctx->message); + in_message = str_c(glmctx->log_prefix); + } + + /* reformat the log message */ + glmctx->message = event->log_message_callback( + event->log_message_callback_context, + glmctx->params->log_type, in_message); + + /* continue with a cleared prefix buffer (as prefix is now part + of *message_r). */ + str_truncate(glmctx->log_prefix, 0); + ret = TRUE; + } + if (event->log_prefix_callback != NULL) { prefix = event->log_prefix_callback( event->log_prefix_callback_context); @@ -120,10 +152,8 @@ event_get_log_message(struct event *event, /* this event replaces all parent log prefixes */ glmctx->replace_prefix = TRUE; glmctx->type_pos = (prefix == NULL ? 0 : strlen(prefix)); - } else if (event->parent == NULL) { - /* append to default log prefix, don't replace it */ - } else { - if (event_get_log_message(event->parent, glmctx)) + } else if (event->parent != NULL) { + if (event_get_log_message(event->parent, glmctx, fmt, args)) ret = TRUE; } return ret; @@ -208,18 +238,25 @@ event_logv_params(struct event *event, const struct event_log_params *params, abort_after_event = TRUE; i_zero(&glmctx); + glmctx.params = params; glmctx.log_prefix = t_str_new(64); - if (!event_get_log_message(event, &glmctx)) { + if (!event_get_log_message(event, &glmctx, fmt, args)) { /* keep log prefix as it is */ event_vsend(event, &ctx, fmt, args); } else if (glmctx.replace_prefix) { /* event overrides the log prefix (even if it's "") */ ctx.log_prefix = str_c(glmctx.log_prefix); ctx.log_prefix_type_pos = glmctx.type_pos; - event_vsend(event, &ctx, fmt, args); + if (glmctx.message != NULL) + event_send(event, &ctx, "%s", glmctx.message); + else + event_vsend(event, &ctx, fmt, args); } else { /* append to log prefix, but don't fully replace it */ - str_vprintfa(glmctx.log_prefix, fmt, args); + if (glmctx.message != NULL) + str_append(glmctx.log_prefix, glmctx.message); + else + str_vprintfa(glmctx.log_prefix, fmt, args); event_send(event, &ctx, "%s", str_c(glmctx.log_prefix)); } if (abort_after_event) diff --git a/src/lib/lib-event-private.h b/src/lib/lib-event-private.h index 7b62e25421..7adc1de6f6 100644 --- a/src/lib/lib-event-private.h +++ b/src/lib/lib-event-private.h @@ -14,6 +14,8 @@ struct event { char *log_prefix; event_log_prefix_callback_t *log_prefix_callback; void *log_prefix_callback_context; + event_log_message_callback_t *log_message_callback; + void *log_message_callback_context; enum log_type min_log_level; bool log_prefix_from_system_pool:1; bool log_prefix_replace:1; diff --git a/src/lib/lib-event.c b/src/lib/lib-event.c index c88c1f7743..7ea2acf799 100644 --- a/src/lib/lib-event.c +++ b/src/lib/lib-event.c @@ -485,6 +485,17 @@ event_set_log_prefix_callback(struct event *event, return event; } +#undef event_set_log_message_callback +struct event * +event_set_log_message_callback(struct event *event, + event_log_message_callback_t *callback, + void *context) +{ + event->log_message_callback = callback; + event->log_message_callback_context = context; + return event; +} + struct event * event_set_name(struct event *event, const char *name) { diff --git a/src/lib/lib-event.h b/src/lib/lib-event.h index 690b0fd3a8..a1c6820f0f 100644 --- a/src/lib/lib-event.h +++ b/src/lib/lib-event.h @@ -77,7 +77,11 @@ struct event_passthrough { struct event *(*event)(void); }; -typedef const char *event_log_prefix_callback_t(void *context); +typedef const char * +event_log_prefix_callback_t(void *context); +typedef const char * +event_log_message_callback_t(void *context, enum log_type log_type, + const char *message); /* Returns TRUE if the event has all the categories that the "other" event has (and maybe more). */ bool event_has_all_categories(struct event *event, const struct event *other); @@ -169,7 +173,8 @@ struct event *event_get_global(void); struct event * event_set_append_log_prefix(struct event *event, const char *prefix); /* Replace the full log prefix string for this event. The parent events' log - prefixes won't be used. + prefixes won't be used. Also, any parent event's message amendment callback + is not used. Clears log_prefix callback. */ @@ -185,6 +190,17 @@ struct event *event_set_log_prefix_callback(struct event *event, event_set_log_prefix_callback(event, replace, (event_log_prefix_callback_t*)callback, \ context - CALLBACK_TYPECHECK(callback, const char *(*)(typeof(context)))) +/* Sets event message amendment callback */ +struct event *event_set_log_message_callback(struct event *event, + event_log_message_callback_t *callback, + void *context); +#define event_set_log_message_callback(event, callback, context) \ + event_set_log_message_callback(event, \ + (event_log_message_callback_t*)callback, \ + context - CALLBACK_TYPECHECK(callback, \ + const char *(*)(typeof(context), enum log_type, \ + const char *))) + /* Set the event's name. The name is specific to a single sending of an event, and it'll be automatically cleared once the event is sent. This should typically be used only in a parameter to e_debug(), etc. */