From: Aki Tuomi Date: Sun, 1 Dec 2019 14:06:42 +0000 (+0200) Subject: stats: Dump sub-metrics X-Git-Tag: 2.3.10~177 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=408b92097d408f4bea4dc8ed93eb8f49bd0fd560;p=thirdparty%2Fdovecot%2Fcore.git stats: Dump sub-metrics --- diff --git a/src/stats/client-reader.c b/src/stats/client-reader.c index 84423e0c87..bd220ea03e 100644 --- a/src/stats/client-reader.c +++ b/src/stats/client-reader.c @@ -1,6 +1,7 @@ /* Copyright (c) 2017-2018 Dovecot authors, see the included COPYING file */ #include "lib.h" +#include "array.h" #include "str.h" #include "stats-dist.h" #include "strescape.h" @@ -65,27 +66,57 @@ static void reader_client_dump_stats(string_t *str, struct stats_dist *stats, } } +static void reader_client_dump_metric(string_t *str, const struct metric *metric, + const char *const *fields) +{ + reader_client_dump_stats(str, metric->duration_stats, fields); + for (unsigned int i = 0; i < metric->fields_count; i++) { + str_append_c(str, '\t'); + str_append_tabescaped(str, metric->fields[i].field_key); + reader_client_dump_stats(str, metric->fields[i].stats, fields); + } + str_append_c(str, '\n'); +} + +static void +reader_client_dump_sub_metrics(struct ostream *output, const struct metric *metric, + const char *sub_name, const char *const *fields) +{ + size_t pos; + struct metric *const *sub_metrics; + if (!array_is_created(&metric->sub_metrics)) + return; + string_t *str = t_str_new(128); + str_append_tabescaped(str, sub_name); + str_append_c(str, '_'); + pos = str->used; + + array_foreach(&metric->sub_metrics, sub_metrics) { + str_append_tabescaped(str, (*sub_metrics)->sub_name); + reader_client_dump_metric(str, *sub_metrics, fields); + o_stream_nsend(output, str_data(str), str_len(str)); + str_truncate(str, pos); + reader_client_dump_sub_metrics(output, *sub_metrics, + str_c(str), fields); + } +} + static int reader_client_input_dump(struct reader_client *client, const char *const *args) { struct stats_metrics_iter *iter; const struct metric *metric; - string_t *str = t_str_new(128); o_stream_cork(client->conn.output); iter = stats_metrics_iterate_init(client->metrics); - while ((metric = stats_metrics_iterate(iter)) != NULL) { - str_truncate(str, 0); + while ((metric = stats_metrics_iterate(iter)) != NULL) T_BEGIN { + string_t *str = t_str_new(128); str_append_tabescaped(str, metric->name); - reader_client_dump_stats(str, metric->duration_stats, args); - for (unsigned int i = 0; i < metric->fields_count; i++) { - str_append_c(str, '\t'); - str_append_tabescaped(str, metric->fields[i].field_key); - reader_client_dump_stats(str, metric->fields[i].stats, args); - } - str_append_c(str, '\n'); + reader_client_dump_metric(str, metric, args); o_stream_nsend(client->conn.output, str_data(str), str_len(str)); - } + reader_client_dump_sub_metrics(client->conn.output, metric, + metric->name, args); + } T_END; o_stream_nsend(client->conn.output, "\n", 1); stats_metrics_iterate_deinit(&iter); o_stream_uncork(client->conn.output);