From: Florian Forster Date: Fri, 22 Dec 2023 22:18:01 +0000 (+0100) Subject: write_prometheus plugin: Emit special a "target info" metric. X-Git-Tag: 6.0.0-rc0~23^2~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dd38f7223ea0469b859a1b692832f9fa119919d1;p=thirdparty%2Fcollectd.git write_prometheus plugin: Emit special a "target info" metric. --- diff --git a/src/write_prometheus.c b/src/write_prometheus.c index c6c11f71d..9c1040fcd 100644 --- a/src/write_prometheus.c +++ b/src/write_prometheus.c @@ -26,7 +26,8 @@ #include "collectd.h" -#include "plugin.h" +#include "daemon/plugin.h" +#include "daemon/resource.h" #include "utils/avltree/avltree.h" #include "utils/common/common.h" #include "utils_complain.h" @@ -171,7 +172,36 @@ void format_metric_family(strbuf_t *buf, metric_family_t const *prom_fam) { } } +/* target_info prints a special "info" metric that contains all the "target + * labels" aka. resource attributes. + * See + * https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md#supporting-target-metadata-in-both-push-based-and-pull-based-systems + * for more details. */ +/* visible for testing */ +void target_info(strbuf_t *buf, label_set_t resource) { + if (resource.num == 0) { + return; + } + + strbuf_print(buf, "# TYPE target info\n"); + strbuf_print(buf, "# HELP target Target metadata\n"); + + metric_t m = { + .family = + &(metric_family_t){ + .name = "target_info", + }, + .label = resource, + }; + format_metric(buf, &m); + + strbuf_print(buf, " 1\n"); +} + static void format_text(strbuf_t *buf) { + label_set_t resource = default_resource_attributes(); + target_info(buf, resource); + pthread_mutex_lock(&prom_metrics_lock); char *unused; diff --git a/src/write_prometheus_test.c b/src/write_prometheus_test.c index 957c1b0d6..54a67ca78 100644 --- a/src/write_prometheus_test.c +++ b/src/write_prometheus_test.c @@ -150,8 +150,43 @@ DEF_TEST(format_metric_family) { return 0; } +void target_info(strbuf_t *buf, label_set_t resource); + +DEF_TEST(target_info) { + struct { + char const *name; + label_set_t resource; + char const *want; + } cases[] = { + { + .name = "single resource attribute", + .resource = + { + .ptr = &(label_pair_t){"foo", "bar"}, + .num = 1, + }, + .want = "# TYPE target info\n" + "# HELP target Target metadata\n" + "target_info{foo=\"bar\"} 1\n", + }, + }; + + for (size_t i = 0; i < STATIC_ARRAY_SIZE(cases); i++) { + printf("# Case %zu: %s\n", i, cases[i].name); + strbuf_t got = STRBUF_CREATE; + + target_info(&got, cases[i].resource); + EXPECT_EQ_STR(cases[i].want, got.ptr); + + STRBUF_DESTROY(got); + } + + return 0; +} + int main(void) { RUN_TEST(format_metric_family); + RUN_TEST(target_info); END_TEST; }