static void stats_metric_free(struct metric *metric)
{
+ struct metric *const *metricp;
stats_dist_deinit(&metric->duration_stats);
for (unsigned int i = 0; i < metric->fields_count; i++)
stats_dist_deinit(&metric->fields[i].stats);
+ if (!array_is_created(&metric->sub_metrics))
+ return;
+ array_foreach(&metric->sub_metrics, metricp)
+ stats_metric_free(*metricp);
}
static void stats_export_deinit(void)
pool_unref(&metrics->pool);
}
+static void stats_metric_reset(struct metric *metric)
+{
+ struct metric *const *metricp;
+ stats_dist_reset(metric->duration_stats);
+ for (unsigned int i = 0; i < metric->fields_count; i++)
+ stats_dist_reset(metric->fields[i].stats);
+ if (!array_is_created(&metric->sub_metrics))
+ return;
+ array_foreach(&metric->sub_metrics, metricp)
+ stats_metric_reset(*metricp);
+}
+
void stats_metrics_reset(struct stats_metrics *metrics)
{
struct metric *const *metricp;
- array_foreach(&metrics->metrics, metricp) {
- stats_dist_reset((*metricp)->duration_stats);
- for (unsigned int i = 0; i < (*metricp)->fields_count; i++)
- stats_dist_reset((*metricp)->fields[i].stats);
- }
+ array_foreach(&metrics->metrics, metricp)
+ stats_metric_reset(*metricp);
}
struct event_filter *
struct metric {
const char *name;
+ /* When this metric is a sub-metric, then this is the
+ suffix for name and any sub_names before it.
+
+ So if we have
+
+ struct metric imap_command {
+ event_name = imap_command_finished
+ group_by = cmd_name
+ }
+
+ The metric.name will always be imap_command and for each sub-metric
+ metric.sub_name will be whatever the cmd_name is, such as 'select'.
+
+ This is a display name and does not guarantee uniqueness.
+ */
+ const char *sub_name;
/* Timing for how long the event existed */
struct stats_dist *duration_stats;
unsigned int fields_count;
struct metric_field *fields;
+ ARRAY(struct metric *) sub_metrics;
struct metric_export_info export_info;
};