]> git.ipfire.org Git - thirdparty/collectd.git/commitdiff
write_prometheus plugin: Emit special a "target info" metric.
authorFlorian Forster <octo@collectd.org>
Fri, 22 Dec 2023 22:18:01 +0000 (23:18 +0100)
committerFlorian Forster <octo@collectd.org>
Thu, 28 Dec 2023 19:13:31 +0000 (20:13 +0100)
src/write_prometheus.c
src/write_prometheus_test.c

index c6c11f71d7ab08be07574f183ef5d1715f4103c7..9c1040fcd4e33d5b4c40a6e5bf9d42fbfb512b13 100644 (file)
@@ -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;
index 957c1b0d6b73090b234146b8363d1dbb9ac2ad2c..54a67ca783212e4763042a7209b524ef47832ac4 100644 (file)
@@ -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;
 }