Fetch prefix using a callback.
bool *replace_prefix, unsigned int *type_pos)
{
bool ret = FALSE;
+ const char *prefix = event->log_prefix;
+
+ if (event->log_prefix_callback != NULL)
+ prefix = event->log_prefix_callback(event->log_prefix_callback_context);
if (event->log_prefix_replace) {
/* this event replaces all parent log prefixes */
*replace_prefix = TRUE;
- *type_pos = event->log_prefix == NULL ? 0 :
- strlen(event->log_prefix);
+ *type_pos = prefix == NULL ? 0 :
+ strlen(prefix);
} else if (event->parent == NULL) {
/* append to default log prefix, don't replace it */
} else {
replace_prefix, type_pos))
ret = TRUE;
}
- if (event->log_prefix != NULL) {
- str_append(log_prefix, event->log_prefix);
+ if (prefix != NULL) {
+ str_append(log_prefix, prefix);
ret = TRUE;
}
return ret;
uint64_t id;
char *log_prefix;
+ event_log_prefix_callback_t *log_prefix_callback;
+ void *log_prefix_callback_context;
bool log_prefix_from_system_pool:1;
bool log_prefix_replace:1;
bool passthrough:1;
static struct event *
event_set_log_prefix(struct event *event, const char *prefix, bool append)
{
+ event->log_prefix_callback = NULL;
+ event->log_prefix_callback_context = NULL;
if (event->log_prefix == NULL) {
/* allocate the first log prefix from the pool */
event->log_prefix = p_strdup(event->pool, prefix);
return event_set_log_prefix(event, prefix, FALSE);
}
+#undef event_set_log_prefix_callback
+struct event *
+event_set_log_prefix_callback(struct event *event,
+ bool replace,
+ event_log_prefix_callback_t *callback,
+ void *context)
+{
+ if (event->log_prefix_from_system_pool)
+ i_free(event->log_prefix);
+ else
+ event->log_prefix = NULL;
+ event->log_prefix_replace = replace;
+ event->log_prefix_callback = callback;
+ event->log_prefix_callback_context = context;
+ return event;
+}
+
struct event *
event_set_name(struct event *event, const char *name)
{
struct event *(*event)(void);
};
+typedef const char *event_log_prefix_callback_t(void *context);
+
/* 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);
/* Returns TRUE if the event has all the fields that the "other" event has (and maybe more).
/* Set the appended log prefix string for this event. All the parent events'
log prefixes will be concatenated together when logging. The log type
text (e.g. "Info: ") will be inserted before appended log prefixes (but
- after replaced log prefix). */
+ after replaced log prefix).
+
+ Clears log_prefix callback.
+ */
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.
+
+ Clears log_prefix callback.
+*/
struct event *event_replace_log_prefix(struct event *event, const char *prefix);
+
+/* Sets event prefix callback, sets log_prefix empty */
+struct event *event_set_log_prefix_callback(struct event *event,
+ bool replace,
+ event_log_prefix_callback_t *callback,
+ void *context);
+#define event_set_log_prefix_callback(event, replace, callback, context) \
+ event_set_log_prefix_callback(event, replace, (event_log_prefix_callback_t*)callback, \
+ context + CALLBACK_TYPECHECK(callback, const char *(*)(typeof(context))))
+
/* 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. */
TYPE_END,
TYPE_APPEND,
TYPE_REPLACE,
+ TYPE_CALLBACK_APPEND,
+ TYPE_CALLBACK_REPLACE,
TYPE_SKIP,
};
} T_END;
}
+static const char *
+test_event_log_prefix_cb(char *prefix)
+{
+ return t_strdup_printf("callback(%s)", prefix);
+}
+
static void test_event_log_prefix(void)
{
struct test_log tests[] = {
},
.result = "replaced4;Info: appended5-TEXT",
},
+ {
+ .prefixes = (const struct test_log_prefix []) {
+ { TYPE_CALLBACK_APPEND, "appended1-" },
+ { .type = TYPE_END }
+ },
+ .global_log_prefix = "global3.",
+ .result = "global3.Info: callback(appended1-)TEXT",
+ },
+ {
+ .prefixes = (const struct test_log_prefix []) {
+ { TYPE_APPEND, "appended1," },
+ { TYPE_REPLACE, "replaced1." },
+ { TYPE_CALLBACK_REPLACE, "replaced2-" },
+ { .type = TYPE_END }
+ },
+ .result = "callback(replaced2-)Info: TEXT",
+ },
+ {
+ .prefixes = (const struct test_log_prefix []) {
+ { TYPE_CALLBACK_REPLACE, "replaced1." },
+ { TYPE_APPEND, "appended1," },
+ { .type = TYPE_END }
+ },
+ .result = "callback(replaced1.)Info: appended1,TEXT",
+ },
+ {
+ .prefixes = (const struct test_log_prefix []) {
+ { TYPE_CALLBACK_REPLACE, "replaced1." },
+ { TYPE_REPLACE, "replaced2-" },
+ { .type = TYPE_END }
+ },
+ .result = "replaced2-Info: TEXT",
+ },
};
const struct event_log_params params = {
.log_type = LOG_TYPE_INFO,
case TYPE_REPLACE:
event_replace_log_prefix(event, test->prefixes[j].str);
break;
+ case TYPE_CALLBACK_APPEND:
+ event_set_log_prefix_callback(event, FALSE,
+ test_event_log_prefix_cb,
+ (char*)test->prefixes[j].str);
+ break;
+ case TYPE_CALLBACK_REPLACE:
+ event_set_log_prefix_callback(event, TRUE,
+ test_event_log_prefix_cb,
+ (char*)test->prefixes[j].str);
+ break;
case TYPE_SKIP:
break;
}