From: Timo Sirainen Date: Fri, 19 Mar 2021 11:13:45 +0000 (+0200) Subject: stats: Support group_by for string lists X-Git-Tag: 2.3.18~371 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0a57bd650e59ae3ddf68131d693383cc385830dc;p=thirdparty%2Fdovecot%2Fcore.git stats: Support group_by for string lists --- diff --git a/src/stats/stats-metrics.c b/src/stats/stats-metrics.c index 46283b06cf..3529262bf2 100644 --- a/src/stats/stats-metrics.c +++ b/src/stats/stats-metrics.c @@ -525,6 +525,23 @@ stats_metric_group_by_field(struct metric *metric, struct event *event, stats_metric_event(sub_metric, event, pool); } +static void +stats_event_get_strlist(struct event *event, const char *name, + ARRAY_TYPE(const_string) *strings) +{ + if (event == NULL) + return; + + const struct event_field *field = + event_find_field_nonrecursive(event, name); + if (field != NULL) { + const char *str; + array_foreach_elem(&field->value.strlist, str) + array_push_back(strings, &str); + } + stats_event_get_strlist(event_get_parent(event), name, strings); +} + static void stats_metric_group_by(struct metric *metric, struct event *event, pool_t pool) { @@ -535,7 +552,36 @@ stats_metric_group_by(struct metric *metric, struct event *event, pool_t pool) if (field == NULL) return; - stats_metric_group_by_field(metric, event, field, pool); + if (field->value_type != EVENT_FIELD_VALUE_TYPE_STRLIST) + stats_metric_group_by_field(metric, event, field, pool); + else { + /* Handle each string in strlist separately. The strlist needs + to be combined from the event and its parents, as well as + the global event and its parents. */ + ARRAY_TYPE(const_string) strings; + + t_array_init(&strings, 8); + stats_event_get_strlist(event, metric->group_by[0].field, + &strings); + stats_event_get_strlist(event_get_global(), + metric->group_by[0].field, &strings); + + struct event_field str_field = { + .value_type = EVENT_FIELD_VALUE_TYPE_STR, + }; + const char *str; + + /* sort strings so duplicates can be easily skipped */ + array_sort(&strings, i_strcmp_p); + array_foreach_elem(&strings, str) { + if (str_field.value.str == NULL || + strcmp(str_field.value.str, str) != 0) { + str_field.value.str = str; + stats_metric_group_by_field(metric, event, + &str_field, pool); + } + } + } } static void