From: Florian Forster Date: Tue, 7 Jul 2020 07:52:57 +0000 (+0200) Subject: src/daemon/metric.[ch]: Implement metric_family_append(). X-Git-Tag: 6.0.0-rc0~145^2~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8674c34c3f6fbed744ca926a21f49f7dc9a154cd;p=thirdparty%2Fcollectd.git src/daemon/metric.[ch]: Implement metric_family_append(). --- diff --git a/src/daemon/metric.c b/src/daemon/metric.c index 3efa5de60..60625a9f0 100644 --- a/src/daemon/metric.c +++ b/src/daemon/metric.c @@ -372,6 +372,39 @@ int metric_family_metric_append(metric_family_t *fam, metric_t m) { return metric_list_add(&fam->metric, m); } +int metric_family_append(metric_family_t *fam, char const *lname, + char const *lvalue, value_t v, metric_t const *templ) { + if ((fam == NULL) || ((lname == NULL) != (lvalue == NULL))) { + return EINVAL; + } + + metric_t m = { + .family = fam, + .value = v, + }; + if (templ != NULL) { + int status = label_set_clone(&m.label, templ->label); + if (status != 0) { + return status; + } + + m.time = templ->time; + m.interval = templ->interval; + m.meta = meta_data_clone(templ->meta); + } + + if (lname != NULL) { + int status = metric_label_set(&m, lname, lvalue); + if (status != 0) { + return status; + } + } + + int status = metric_family_metric_append(fam, m); + metric_reset(&m); + return status; +} + int metric_family_metric_reset(metric_family_t *fam) { if (fam == NULL) { return EINVAL; diff --git a/src/daemon/metric.h b/src/daemon/metric.h index 66d36380d..f849a3703 100644 --- a/src/daemon/metric.h +++ b/src/daemon/metric.h @@ -149,6 +149,18 @@ struct metric_family_s { * allocates memory which must be freed using metric_family_metric_reset. */ int metric_family_metric_append(metric_family_t *fam, metric_t m); +/* metric_family_append constructs a new metric_t and appends it to fam. It is + * a convenience function that is funcitonally approximately equivalent to the + * following code, but without modifying templ: + * + * metric_t m = *templ; + * m.value = v; + * metric_label_set(&m, lname, lvalue); + * metric_family_metric_append(fam, m); + */ +int metric_family_append(metric_family_t *fam, char const *lname, + char const *lvalue, value_t v, metric_t const *templ); + /* metric_family_metric_reset frees all metrics in the metric family and * resets the count to zero. */ int metric_family_metric_reset(metric_family_t *fam); diff --git a/src/daemon/metric_test.c b/src/daemon/metric_test.c index da7b4731b..128162046 100644 --- a/src/daemon/metric_test.c +++ b/src/daemon/metric_test.c @@ -159,9 +159,111 @@ DEF_TEST(metric_identity) { return 0; } +DEF_TEST(metric_family_append) { + struct { + char const *lname; + char const *lvalue; + gauge_t v; + metric_t *templ; + int want_err; + label_t *want_labels; + size_t want_labels_num; + gauge_t want_value; + cdtime_t want_time; + cdtime_t want_interval; + } cases[] = { + { + .v = 42, + .want_value = 42, + }, + { + .lname = "type", + .lvalue = "test", + .v = 42, + .want_labels = + (label_t[]){ + {"type", "test"}, + }, + .want_labels_num = 1, + .want_value = 42, + }, + { + .v = 42, + .templ = + &(metric_t){ + .time = TIME_T_TO_CDTIME_T(1594107920), + }, + .want_value = 42, + .want_time = TIME_T_TO_CDTIME_T(1594107920), + }, + { + .v = 42, + .templ = + &(metric_t){ + .interval = TIME_T_TO_CDTIME_T(10), + }, + .want_value = 42, + .want_interval = TIME_T_TO_CDTIME_T(10), + }, + { + .lname = "type", + .lvalue = "test", + .v = 42, + .templ = + &(metric_t){ + .label = + { + .ptr = &(label_pair_t){"common", "label"}, + .num = 1, + }, + }, + .want_labels = + (label_t[]){ + {"common", "label"}, + {"type", "test"}, + }, + .want_labels_num = 2, + .want_value = 42, + }, + }; + + for (size_t i = 0; i < (sizeof(cases) / sizeof(cases[0])); i++) { + metric_family_t fam = { + .name = "test_total", + .type = METRIC_TYPE_GAUGE, + }; + + EXPECT_EQ_INT(cases[i].want_err, + metric_family_append(&fam, cases[i].lname, cases[i].lvalue, + (value_t){.gauge = cases[i].v}, + cases[i].templ)); + if (cases[i].want_err != 0) { + continue; + } + + EXPECT_EQ_INT(1, fam.metric.num); + metric_t const *m = fam.metric.ptr; + + EXPECT_EQ_INT(cases[i].want_labels_num, m->label.num); + for (size_t j = 0; j < cases[i].want_labels_num; j++) { + EXPECT_EQ_STR(cases[i].want_labels[j].value, + metric_label_get(m, cases[i].want_labels[j].name)); + } + + EXPECT_EQ_DOUBLE(cases[i].want_value, m->value.gauge); + EXPECT_EQ_UINT64(cases[i].want_time, m->time); + EXPECT_EQ_UINT64(cases[i].want_interval, m->interval); + + metric_family_metric_reset(&fam); + } + + return 0; +} + int main(void) { RUN_TEST(metric_label_set); RUN_TEST(metric_identity); + RUN_TEST(metric_family_append); END_TEST; }