struct event_category *category;
};
+enum event_filter_log_type {
+ EVENT_FILTER_LOG_TYPE_DEBUG = BIT(0),
+ EVENT_FILTER_LOG_TYPE_INFO = BIT(1),
+ EVENT_FILTER_LOG_TYPE_WARNING = BIT(2),
+ EVENT_FILTER_LOG_TYPE_ERROR = BIT(3),
+ EVENT_FILTER_LOG_TYPE_FATAL = BIT(4),
+ EVENT_FILTER_LOG_TYPE_PANIC = BIT(5),
+
+ EVENT_FILTER_LOG_TYPE_ALL = 0xff,
+};
+static const char *event_filter_log_type_names[] = {
+ "debug", "info", "warning", "error", "fatal", "panic",
+};
+static enum event_filter_log_type event_filter_log_types[] = {
+ EVENT_FILTER_LOG_TYPE_DEBUG,
+ EVENT_FILTER_LOG_TYPE_INFO,
+ EVENT_FILTER_LOG_TYPE_WARNING,
+ EVENT_FILTER_LOG_TYPE_ERROR,
+ EVENT_FILTER_LOG_TYPE_FATAL,
+ EVENT_FILTER_LOG_TYPE_PANIC,
+};
+
struct event_filter_query_internal {
unsigned int categories_count;
unsigned int fields_count;
bool has_unregistered_categories;
struct event_filter_category *categories;
const struct event_field *fields;
+ enum event_filter_log_type log_type_mask;
const char *name;
const char *source_filename;
pool_unref(&filter->pool);
}
+static bool
+event_filter_category_to_log_type(const char *name,
+ enum event_filter_log_type *log_type_r)
+{
+ unsigned int i;
+
+ for (i = 0; i < N_ELEMENTS(event_filter_log_type_names); i++) {
+ if (strcmp(name, event_filter_log_type_names[i]) == 0) {
+ *log_type_r = 1 << i;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
static void
event_filter_add_categories(struct event_filter *filter,
struct event_filter_query_internal *int_query,
{
unsigned int categories_count = str_array_length(categories);
struct event_filter_category *cat;
- unsigned int i;
+ enum event_filter_log_type log_type;
+ unsigned int i, j;
if (categories_count == 0)
return;
/* copy strings */
cat = p_new(filter->pool, struct event_filter_category,
categories_count);
- for (i = 0; i < categories_count; i++) {
- cat[i].name = p_strdup(filter->pool, categories[i]);
- cat[i].category = event_category_find_registered(categories[i]);
- if (cat[i].category == NULL)
+ for (i = j = 0; i < categories_count; i++) {
+ if (event_filter_category_to_log_type(categories[i], &log_type)) {
+ int_query->log_type_mask |= log_type;
+ continue;
+ }
+ cat[j].name = p_strdup(filter->pool, categories[i]);
+ cat[j].category = event_category_find_registered(categories[i]);
+ if (cat[j].category == NULL)
int_query->has_unregistered_categories = TRUE;
+ j++;
}
- int_query->categories_count = categories_count;
+ int_query->categories_count = j;
int_query->categories = cat;
}
event_filter_add_categories(filter, int_query, query->categories);
if (query->fields != NULL)
event_filter_add_fields(filter, int_query, query->fields);
+
+ if (int_query->log_type_mask == 0) {
+ /* no explicit log types given. default to all. */
+ int_query->log_type_mask = EVENT_FILTER_LOG_TYPE_ALL;
+ }
}
void event_filter_merge(struct event_filter *dest,
query.source_filename = int_query->source_filename;
query.source_linenum = int_query->source_linenum;
- if (int_query->categories_count > 0) {
+ if (int_query->categories_count > 0 ||
+ int_query->log_type_mask != EVENT_FILTER_LOG_TYPE_ALL) {
ARRAY_TYPE(const_string) categories;
t_array_init(&categories, int_query->categories_count);
array_append(&categories,
&int_query->categories[i].name, 1);
}
+ for (i = 0; i < N_ELEMENTS(event_filter_log_type_names); i++) {
+ if ((int_query->log_type_mask & (1 << i)) == 0)
+ continue;
+ array_append(&categories,
+ &event_filter_log_type_names[i], 1);
+ }
array_append_zero(&categories);
query.categories = array_idx(&categories, 0);
}
str_append_tabescaped(dest, query->categories[i].name);
str_append_c(dest, '\t');
}
+ if (query->log_type_mask != EVENT_FILTER_LOG_TYPE_ALL) {
+ for (i = 0; i < N_ELEMENTS(event_filter_log_type_names); i++) {
+ if ((query->log_type_mask & (1 << i)) == 0)
+ continue;
+ str_append_c(dest, EVENT_FILTER_CODE_CATEGORY);
+ str_append_tabescaped(dest, event_filter_log_type_names[i]);
+ str_append_c(dest, '\t');
+ }
+ }
+
for (i = 0; i < query->fields_count; i++) {
str_append_c(dest, EVENT_FILTER_CODE_FIELD);
str_append_tabescaped(dest, query->fields[i].key);
static bool
event_filter_query_match(const struct event_filter_query_internal *query,
struct event *event, const char *source_filename,
- unsigned int source_linenum)
+ unsigned int source_linenum,
+ const struct failure_context *ctx)
{
+ i_assert(ctx->type < N_ELEMENTS(event_filter_log_types));
+ if ((query->log_type_mask & event_filter_log_types[ctx->type]) == 0)
+ return FALSE;
+
if (query->name != NULL) {
if (event->sending_name == NULL ||
strcmp(event->sending_name, query->name) != 0)
return TRUE;
}
-bool event_filter_match(struct event_filter *filter, struct event *event)
+bool event_filter_match(struct event_filter *filter, struct event *event,
+ const struct failure_context *ctx)
{
return event_filter_match_source(filter, event, event->source_filename,
- event->source_linenum);
+ event->source_linenum, ctx);
}
bool event_filter_match_source(struct event_filter *filter, struct event *event,
const char *source_filename,
- unsigned int source_linenum)
+ unsigned int source_linenum,
+ const struct failure_context *ctx)
{
const struct event_filter_query_internal *query;
array_foreach(&filter->queries, query) {
if (event_filter_query_match(query, event, source_filename,
- source_linenum))
+ source_linenum, ctx))
return TRUE;
}
return FALSE;
struct event_filter_match_iter {
struct event_filter *filter;
struct event *event;
+ const struct failure_context *failure_ctx;
unsigned int idx;
};
struct event_filter_match_iter *
-event_filter_match_iter_init(struct event_filter *filter, struct event *event)
+event_filter_match_iter_init(struct event_filter *filter, struct event *event,
+ const struct failure_context *ctx)
{
struct event_filter_match_iter *iter;
iter = i_new(struct event_filter_match_iter, 1);
iter->filter = filter;
iter->event = event;
+ iter->failure_ctx = ctx;
if (!event_filter_match_fastpath(filter, event))
iter->idx = UINT_MAX;
return iter;
if (query->context != NULL &&
event_filter_query_match(query, iter->event,
iter->event->source_filename,
- iter->event->source_linenum))
+ iter->event->source_linenum,
+ iter->failure_ctx))
return query->context;
}
return NULL;