/* 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"
}
}
+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);