From 0a57bd650e59ae3ddf68131d693383cc385830dc Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Fri, 19 Mar 2021 13:13:45 +0200 Subject: [PATCH] stats: Support group_by for string lists --- src/stats/stats-metrics.c | 48 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) 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 -- 2.47.3