From c73886a7c8bf31efb962a73d583662f92b7bf111 Mon Sep 17 00:00:00 2001 From: Eero Tamminen Date: Mon, 19 Feb 2024 17:56:56 +0200 Subject: [PATCH] WIP: write_prometheus: fix AVL tree family key Resource labels are part of metric family identification, not just the family name. Signed-off-by: Eero Tamminen --- src/write_prometheus.c | 48 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/src/write_prometheus.c b/src/write_prometheus.c index df1aab8a79..5120741e65 100644 --- a/src/write_prometheus.c +++ b/src/write_prometheus.c @@ -758,31 +758,54 @@ static int prom_init() { return 0; } + +static bool family_key(metric_family_t const *fam, strbuf_t *buf) { + bool fail = strbuf_print(buf, fam->name); + + for (size_t i = 0; i < fam->resource.num; i++) { + fail = fail || strbuf_print(buf, "/"); + fail = fail || strbuf_print(buf, fam->resource.ptr[i].name); + fail = fail || strbuf_print(buf, "="); + fail = fail || strbuf_print(buf, fam->resource.ptr[i].value); + } + + return !fail; +} + static int prom_write(metric_family_t const *fam, __attribute__((unused)) user_data_t *ud) { + strbuf_t keybuf = STRBUF_CREATE; + if (!family_key(fam, &keybuf)) { + ERROR("write_prometheus plugin: Metric \"%s\" identity creation failed.", fam->name); + STRBUF_DESTROY(keybuf); + return -1; + } pthread_mutex_lock(&prom_metrics_lock); metric_family_t *prom_fam = NULL; - if (c_avl_get(prom_metrics, fam->name, (void *)&prom_fam) != 0) { + if (c_avl_get(prom_metrics, keybuf.ptr, (void *)&prom_fam) != 0) { prom_fam = metric_family_clone(fam); if (prom_fam == NULL) { ERROR("write_prometheus plugin: Clone metric \"%s\" failed.", fam->name); pthread_mutex_unlock(&prom_metrics_lock); + STRBUF_DESTROY(keybuf); return -1; } /* Sort the metrics so that lookup is fast. */ qsort(prom_fam->metric.ptr, prom_fam->metric.num, sizeof(*prom_fam->metric.ptr), prom_metric_cmp); - int status = c_avl_insert(prom_metrics, prom_fam->name, prom_fam); + int status = c_avl_insert(prom_metrics, keybuf.ptr, prom_fam); if (status != 0) { ERROR("write_prometheus plugin: Adding \"%s\" failed.", prom_fam->name); metric_family_free(prom_fam); pthread_mutex_unlock(&prom_metrics_lock); + STRBUF_DESTROY(keybuf); return -1; } pthread_mutex_unlock(&prom_metrics_lock); + STRBUF_DESTROY(keybuf); return 0; } @@ -827,11 +850,20 @@ static int prom_write(metric_family_t const *fam, static int prom_missing(metric_family_t const *fam, __attribute__((unused)) user_data_t *ud) { + strbuf_t keybuf = STRBUF_CREATE; + if (!family_key(fam, &keybuf)) { + ERROR("write_prometheus plugin: Metric \"%s\" identity creation failed.", fam->name); + STRBUF_DESTROY(keybuf); + return -1; + } pthread_mutex_lock(&prom_metrics_lock); metric_family_t *prom_fam = NULL; - if (c_avl_get(prom_metrics, fam->name, (void *)&prom_fam) != 0) + if (c_avl_get(prom_metrics, keybuf.ptr, (void *)&prom_fam) != 0) { + pthread_mutex_unlock(&prom_metrics_lock); + STRBUF_DESTROY(keybuf); return 0; + } for (size_t i = 0; i < fam->metric.num; i++) { metric_t const *m = &fam->metric.ptr[i]; @@ -850,7 +882,7 @@ static int prom_missing(metric_family_t const *fam, } if (prom_fam->metric.num == 0) { - int status = c_avl_remove(prom_metrics, prom_fam->name, NULL, NULL); + int status = c_avl_remove(prom_metrics, keybuf.ptr, NULL, NULL); if (status != 0) { ERROR("write_prometheus plugin: Deleting metric family \"%s\" failed " "with status %d", @@ -863,6 +895,7 @@ static int prom_missing(metric_family_t const *fam, } pthread_mutex_unlock(&prom_metrics_lock); + STRBUF_DESTROY(keybuf); return 0; } @@ -877,8 +910,11 @@ static int prom_shutdown() { char *name; metric_family_t *prom_fam; while (c_avl_pick(prom_metrics, (void *)&name, (void *)&prom_fam) == 0) { - assert(name == prom_fam->name); - name = NULL; + strbuf_t keybuf = STRBUF_CREATE; + if (family_key(prom_fam, &keybuf)) { + assert(name == keybuf.ptr); + } + STRBUF_DESTROY(keybuf); metric_family_free(prom_fam); } c_avl_destroy(prom_metrics);