Skip to content

Commit

Permalink
WIP: write_prometheus: fix AVL tree family key
Browse files Browse the repository at this point in the history
Resource labels are part of metric family identification, not just the
family name.

Signed-off-by: Eero Tamminen <[email protected]>
  • Loading branch information
eero-t committed Feb 19, 2024
1 parent 37f32b9 commit c73886a
Showing 1 changed file with 42 additions and 6 deletions.
48 changes: 42 additions & 6 deletions src/write_prometheus.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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];
Expand All @@ -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",
Expand All @@ -863,6 +895,7 @@ static int prom_missing(metric_family_t const *fam,
}

pthread_mutex_unlock(&prom_metrics_lock);
STRBUF_DESTROY(keybuf);
return 0;
}

Expand All @@ -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);
Expand Down

0 comments on commit c73886a

Please sign in to comment.