stats-metrics.c revision 9c675f5e259c19f9fdc40808439479131b32421e
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Copyright (c) 2017 Dovecot authors, see the included COPYING file */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "lib.h"
8aacc9e7c84f8376822823ec98c2f551d4919b2eTimo Sirainen#include "array.h"
16f816d3f3c32ae3351834253f52ddd0212bcbf3Timo Sirainen#include "timing.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "time-util.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "event-filter.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "stats-settings.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "stats-metrics.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct stats_metrics {
463e82bdf0e990f4f2252d2b53ea23a5abe5883cTimo Sirainen pool_t pool;
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen struct event_filter *filter;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ARRAY(struct metric *) metrics;
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen};
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainenstatic void
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainenstats_metric_settings_to_query(const struct stats_metric_settings *set,
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen struct event_filter_query *query_r)
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen{
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen i_zero(query_r);
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen /* generate fields for event filter */
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen if (array_is_created(&set->filter)) {
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen struct event_filter_field *filter_fields;
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen const char *const *filters;
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen unsigned int i, count;
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen filters = array_get(&set->filter, &count);
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen i_assert(count % 2 == 0);
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen count /= 2;
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen filter_fields = t_new(struct event_filter_field, count + 1);
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen for (i = 0; i < count; i++) {
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen filter_fields[i].key = filters[i*2];
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen filter_fields[i].value = filters[i*2+1];
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen }
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen query_r->fields = filter_fields;
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen }
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen /* add query to the event filter */
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen query_r->categories = t_strsplit_spaces(set->categories, " ");
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen query_r->name = set->event_name;
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen query_r->source_filename = t_strcut(set->source_location, ':');
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen query_r->source_linenum = set->parsed_source_linenum;
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen}
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainenstatic void stats_metrics_add_set(struct stats_metrics *metrics,
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen const struct stats_metric_settings *set)
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen{
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen struct event_filter_query query;
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen struct metric *metric;
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen const char *const *fields;
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen metric = p_new(metrics->pool, struct metric, 1);
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen metric->name = p_strdup(metrics->pool, set->name);
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen metric->duration_timing = timing_init();
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen fields = t_strsplit_spaces(set->fields, " ");
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen metric->fields_count = str_array_length(fields);
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen if (metric->fields_count > 0) {
a0d34d3982507f513a9d800082481e9faeb9a943Timo Sirainen metric->fields = p_new(metrics->pool, struct metric_field,
a0d34d3982507f513a9d800082481e9faeb9a943Timo Sirainen metric->fields_count);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen for (unsigned int i = 0; i < metric->fields_count; i++) {
e6d7d19c328e7043ad35d5a52c1617bde915a16fTimo Sirainen metric->fields[i].field_key =
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen p_strdup(metrics->pool, fields[i]);
d7095f3a4466fbb78b2d5eb3d322bc15a5b0ab1fTimo Sirainen metric->fields[i].timing = timing_init();
153de7823e64c67678b3fc95719c41a8ec5b864dTimo Sirainen }
153de7823e64c67678b3fc95719c41a8ec5b864dTimo Sirainen }
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen array_append(&metrics->metrics, &metric, 1);
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen
d7095f3a4466fbb78b2d5eb3d322bc15a5b0ab1fTimo Sirainen stats_metric_settings_to_query(set, &query);
d7095f3a4466fbb78b2d5eb3d322bc15a5b0ab1fTimo Sirainen query.context = metric;
8f7b00599e73fe71b1d2c6c65f8ae98aac1b23fbTimo Sirainen event_filter_add(metrics->filter, &query);
190237ce467d2389dfb809874b0fec86d3c7968dTimo Sirainen}
d7095f3a4466fbb78b2d5eb3d322bc15a5b0ab1fTimo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainenstatic void
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainenstats_metrics_add_from_settings(struct stats_metrics *metrics,
e6d7d19c328e7043ad35d5a52c1617bde915a16fTimo Sirainen const struct stats_settings *set)
9315dd69233d554452df0c12bc57002d2042a8f4Timo Sirainen{
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen struct stats_metric_settings *const *metric_setp;
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen
9315dd69233d554452df0c12bc57002d2042a8f4Timo Sirainen if (!array_is_created(&set->metrics)) {
9315dd69233d554452df0c12bc57002d2042a8f4Timo Sirainen p_array_init(&metrics->metrics, metrics->pool, 0);
9315dd69233d554452df0c12bc57002d2042a8f4Timo Sirainen return;
153de7823e64c67678b3fc95719c41a8ec5b864dTimo Sirainen }
9315dd69233d554452df0c12bc57002d2042a8f4Timo Sirainen
9315dd69233d554452df0c12bc57002d2042a8f4Timo Sirainen p_array_init(&metrics->metrics, metrics->pool,
9315dd69233d554452df0c12bc57002d2042a8f4Timo Sirainen array_count(&set->metrics));
9315dd69233d554452df0c12bc57002d2042a8f4Timo Sirainen array_foreach(&set->metrics, metric_setp) T_BEGIN {
9315dd69233d554452df0c12bc57002d2042a8f4Timo Sirainen stats_metrics_add_set(metrics, *metric_setp);
41bb0aa8e357876bc9a1916a37c9e3e78e5f8185Timo Sirainen } T_END;
538c58fc95200fcc5e91abdda8b912b574a2f968Timo Sirainen}
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainenstruct stats_metrics *stats_metrics_init(const struct stats_settings *set)
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen{
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen struct stats_metrics *metrics;
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen pool_t pool = pool_alloconly_create("stats metrics", 1024);
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen metrics = p_new(pool, struct stats_metrics, 1);
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen metrics->pool = pool;
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen metrics->filter = event_filter_create();
538c58fc95200fcc5e91abdda8b912b574a2f968Timo Sirainen stats_metrics_add_from_settings(metrics, set);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen return metrics;
8aacc9e7c84f8376822823ec98c2f551d4919b2eTimo Sirainen}
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainenstatic void stats_metric_free(struct metric *metric)
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen{
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen timing_deinit(&metric->duration_timing);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen for (unsigned int i = 0; i < metric->fields_count; i++)
d482b35af87f5fd872bad007da0475813a401a49Timo Sirainen timing_deinit(&metric->fields[i].timing);
d482b35af87f5fd872bad007da0475813a401a49Timo Sirainen}
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen
d482b35af87f5fd872bad007da0475813a401a49Timo Sirainenvoid stats_metrics_deinit(struct stats_metrics **_metrics)
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen{
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen struct stats_metrics *metrics = *_metrics;
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen struct metric *const *metricp;
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen *_metrics = NULL;
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen array_foreach(&metrics->metrics, metricp)
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen stats_metric_free(*metricp);
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen event_filter_unref(&metrics->filter);
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen pool_unref(&metrics->pool);
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen}
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainenvoid stats_metrics_reset(struct stats_metrics *metrics)
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen{
d482b35af87f5fd872bad007da0475813a401a49Timo Sirainen struct metric *const *metricp;
d482b35af87f5fd872bad007da0475813a401a49Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen array_foreach(&metrics->metrics, metricp) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen timing_reset((*metricp)->duration_timing);
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen for (unsigned int i = 0; i < (*metricp)->fields_count; i++)
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen timing_reset((*metricp)->fields[i].timing);
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen }
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen}
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct event_filter *
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainenstats_metrics_get_event_filter(struct stats_metrics *metrics)
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen{
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen return metrics->filter;
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen}
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainenstatic void
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainenstats_metric_event(struct metric *metric, struct event *event)
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen{
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen struct timeval tv_start, tv_end;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen intmax_t duration = 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (event_get_last_send_time(event, &tv_end)) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen event_get_create_time(event, &tv_start);
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen duration = timeval_diff_usecs(&tv_end, &tv_start);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen timing_add_usecs(metric->duration_timing, duration);
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen for (unsigned int i = 0; i < metric->fields_count; i++) {
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen const struct event_field *field =
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen event_find_field(event, metric->fields[i].field_key);
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen if (field == NULL)
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen continue;
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen intmax_t num = 0;
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen switch (field->value_type) {
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen case EVENT_FIELD_VALUE_TYPE_STR:
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen break;
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen case EVENT_FIELD_VALUE_TYPE_INTMAX:
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen num = field->value.intmax;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen break;
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen case EVENT_FIELD_VALUE_TYPE_TIMEVAL:
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen num = field->value.timeval.tv_sec * 1000000ULL +
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen field->value.timeval.tv_usec;
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen break;
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen }
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen timing_add_usecs(metric->fields[i].timing, num);
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen }
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen}
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainenvoid stats_metrics_event(struct stats_metrics *metrics, struct event *event)
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen{
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen struct event_filter_match_iter *iter;
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen struct metric *metric;
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen iter = event_filter_match_iter_init(metrics->filter, event);
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen while ((metric = event_filter_match_iter_next(iter)) != NULL)
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen stats_metric_event(metric, event);
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen event_filter_match_iter_deinit(&iter);
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen}
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainenstruct stats_metrics_iter {
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen struct stats_metrics *metrics;
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen unsigned int idx;
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen};
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainenstruct stats_metrics_iter *
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainenstats_metrics_iterate_init(struct stats_metrics *metrics)
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen{
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen struct stats_metrics_iter *iter;
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen iter = i_new(struct stats_metrics_iter, 1);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen iter->metrics = metrics;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return iter;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenconst struct metric *stats_metrics_iterate(struct stats_metrics_iter *iter)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct metric *const *metrics;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int count;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen metrics = array_get(&iter->metrics->metrics, &count);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (iter->idx >= count)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return NULL;
cd5ee8630497fdbd853ef588a858b4ef619a5e03Timo Sirainen return metrics[iter->idx++];
cd5ee8630497fdbd853ef588a858b4ef619a5e03Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
7394389230750c45b105cdefb5850c81cae8cdc0Timo Sirainenvoid stats_metrics_iterate_deinit(struct stats_metrics_iter **_iter)
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct stats_metrics_iter *iter = *_iter;
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen *_iter = NULL;
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen i_free(iter);
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen}
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen