From 0584fd6289e1e8e7fb91651556141fbc5687b992 Mon Sep 17 00:00:00 2001 From: claudio Date: Tue, 6 Dec 2022 17:38:41 +0000 Subject: [PATCH] OpenMetrics is rather strict about naming metricsets. Add a function that a) verifies that none of the special suffixes is used and b) that the name itself is not yet used already. Also when printing a counter _total has to be added to the metric name and for info metrics _info is added. With and OK tb@ --- usr.sbin/bgpctl/ometric.c | 64 ++++++++++++++++++++++++++++++-- usr.sbin/bgpctl/output_ometric.c | 42 ++++++++++----------- 2 files changed, 82 insertions(+), 24 deletions(-) diff --git a/usr.sbin/bgpctl/ometric.c b/usr.sbin/bgpctl/ometric.c index c7fd626ee53..10341f83b5a 100644 --- a/usr.sbin/bgpctl/ometric.c +++ b/usr.sbin/bgpctl/ometric.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ometric.c,v 1.6 2022/12/06 11:27:58 claudio Exp $ */ +/* $OpenBSD: ometric.c,v 1.7 2022/12/06 17:38:41 claudio Exp $ */ /* * Copyright (c) 2022 Claudio Jeker @@ -71,6 +71,41 @@ struct ometric { STAILQ_HEAD(, ometric) ometrics = STAILQ_HEAD_INITIALIZER(ometrics); +static const char *suffixes[] = { "_total", "_created", "_count", + "_sum", "_bucket", "_gcount", "_gsum", "_info", +}; + +/* + * Return true if name has one of the above suffixes. + */ +static int +strsuffix(const char *name) +{ + const char *suffix; + size_t i; + + suffix = strrchr(name, '_'); + if (suffix == NULL) + return 0; + for (i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); i++) { + if (strcmp(suffix, suffixes[i]) == 0) + return 1; + } + return 0; +} + +static void +ometric_check(const char *name) +{ + struct ometric *om; + + if (strsuffix(name)) + errx(1, "reserved name suffix used: %s", name); + STAILQ_FOREACH(om, &ometrics, entry) + if (strcmp(name, om->name) == 0) + errx(1, "duplicate name: %s", name); +} + /* * Allocate and return new ometric. The name and help string need to remain * valid until the ometric is freed. Normally constant strings should be used. @@ -80,6 +115,8 @@ ometric_new(enum ometric_type type, const char *name, const char *help) { struct ometric *om; + ometric_check(name); + if ((om = calloc(1, sizeof(*om))) == NULL) err(1, NULL); @@ -104,6 +141,8 @@ ometric_new_state(const char * const *states, size_t statecnt, const char *name, { struct ometric *om; + ometric_check(name); + if ((om = calloc(1, sizeof(*om))) == NULL) err(1, NULL); @@ -284,6 +323,25 @@ ometric_output_value(FILE *out, const struct ovalue *ov) return -1; } +static int +ometric_output_name(FILE *out, const struct ometric *om) +{ + const char *suffix; + + switch (om->type) { + case OMT_COUNTER: + suffix = "_total"; + break; + case OMT_INFO: + suffix = "_info"; + break; + default: + suffix = ""; + break; + } + return fprintf(out, "%s%s", om->name, suffix); +} + /* * Output all metric values with TYPE and optional HELP strings. */ @@ -304,7 +362,7 @@ ometric_output_all(FILE *out) return -1; STAILQ_FOREACH(ov, &om->vals, entry) { - if (fprintf(out, "%s", om->name) < 0) + if (ometric_output_name(out, om) < 0) return -1; if (ometric_output_labels(out, ov->labels) < 0) return -1; @@ -425,7 +483,7 @@ ometric_set_state(struct ometric *om, const char *state, struct olabels *ol) if (om->type != OMT_STATESET) errx(1, "%s incorrect ometric type", __func__); - for (i = 0; i < om->setsize; i++) { + for (i = 0; i < om->setsize; i++) { if (strcasecmp(state, om->stateset[i]) == 0) val = 1; else diff --git a/usr.sbin/bgpctl/output_ometric.c b/usr.sbin/bgpctl/output_ometric.c index b9572a0bf80..053c22e66a6 100644 --- a/usr.sbin/bgpctl/output_ometric.c +++ b/usr.sbin/bgpctl/output_ometric.c @@ -1,4 +1,4 @@ -/* $OpenBSD: output_ometric.c,v 1.7 2022/12/06 11:27:58 claudio Exp $ */ +/* $OpenBSD: output_ometric.c,v 1.8 2022/12/06 17:38:41 claudio Exp $ */ /* * Copyright (c) 2022 Claudio Jeker @@ -58,7 +58,7 @@ ometric_head(struct parse_result *arg) char hostname[HOST_NAME_MAX + 1]; char *domainname; - bgpd_info = ometric_new(OMT_INFO, "bgpd_info", "bgpd information"); + bgpd_info = ometric_new(OMT_INFO, "bgpd", "bgpd information"); bgpd_scrape_time = ometric_new(OMT_GAUGE, "bgpd_scrape_seconds", "bgpd scrape time in seconds"); @@ -82,7 +82,7 @@ ometric_head(struct parse_result *arg) * per neighbor stats: attrs will be remote_as, remote_addr, * description and group */ - peer_info = ometric_new(OMT_INFO, "bgpd_peer_info", + peer_info = ometric_new(OMT_INFO, "bgpd_peer", "peer information"); peer_state = ometric_new_state(statenames, sizeof(statenames) / sizeof(statenames[0]), "bgpd_peer_state", @@ -105,65 +105,65 @@ ometric_head(struct parse_result *arg) "number of prefixes received from peer"); peer_message_transmit = ometric_new(OMT_COUNTER, - "bgpd_peer_message_transmit_total", + "bgpd_peer_message_transmit", "per message type count of transmitted messages"); peer_message_receive = ometric_new(OMT_COUNTER, - "bgpd_peer_message_receive_total", + "bgpd_peer_message_receive", "per message type count of received messages"); peer_update_transmit = ometric_new(OMT_COUNTER, - "bgpd_peer_update_transmit_total", + "bgpd_peer_update_transmit", "number of prefixes sent as update"); peer_update_pending = ometric_new(OMT_COUNTER, - "bgpd_peer_update_pending_total", + "bgpd_peer_update_pending", "number of pending update prefixes"); peer_update_receive = ometric_new(OMT_COUNTER, - "bgpd_peer_update_receive_total", + "bgpd_peer_update_receive", "number of prefixes received as update"); peer_withdraw_transmit = ometric_new(OMT_COUNTER, - "bgpd_peer_withdraw_transmit_total", + "bgpd_peer_withdraw_transmit", "number of withdrawn prefixes sent to peer"); peer_withdraw_pending = ometric_new(OMT_COUNTER, - "bgpd_peer_withdraw_pending_total", + "bgpd_peer_withdraw_pending", "number of pending withdrawn prefixes"); peer_withdraw_receive = ometric_new(OMT_COUNTER, - "bgpd_peer_withdraw_receive_total", + "bgpd_peer_withdraw_receive", "number of withdrawn prefixes received from peer"); peer_rr_req_transmit = ometric_new(OMT_COUNTER, - "bgpd_peer_route_refresh_req_transmit_total", + "bgpd_peer_route_refresh_req_transmit", "number of route-refresh request transmitted to peer"); peer_rr_req_receive = ometric_new(OMT_COUNTER, - "bgpd_peer_route_refresh_req_receive_total", + "bgpd_peer_route_refresh_req_receive", "number of route-refresh request received from peer"); peer_rr_borr_transmit = ometric_new(OMT_COUNTER, - "bgpd_peer_route_refresh_borr_transmit_total", + "bgpd_peer_route_refresh_borr_transmit", "number of ext. route-refresh BORR messages transmitted to peer"); peer_rr_borr_receive = ometric_new(OMT_COUNTER, - "bgpd_peer_route_refresh_borr_receive_total", + "bgpd_peer_route_refresh_borr_receive", "number of ext. route-refresh BORR messages received from peer"); peer_rr_eorr_transmit = ometric_new(OMT_COUNTER, - "bgpd_peer_route_refresh_eorr_transmit_total", + "bgpd_peer_route_refresh_eorr_transmit", "number of ext. route-refresh EORR messages transmitted to peer"); peer_rr_eorr_receive = ometric_new(OMT_COUNTER, - "bgpd_peer_route_refresh_eorr_receive_total", + "bgpd_peer_route_refresh_eorr_receive", "number of ext. route-refresh EORR messages received from peer"); /* RDE memory statistics */ rde_mem_size = ometric_new(OMT_GAUGE, "bgpd_rde_memory_usage_bytes", "memory usage in bytes"); rde_mem_count = ometric_new(OMT_GAUGE, - "bgpd_rde_memory_count", "number of object in use"); + "bgpd_rde_memory_usage_objects", "number of object in use"); rde_mem_ref_count = ometric_new(OMT_GAUGE, - "bgpd_rde_memory_reference_count", "number of references held"); + "bgpd_rde_memory_usage_references", "number of references held"); rde_set_size = ometric_new(OMT_GAUGE, "bgpd_rde_set_usage_bytes", "memory usage of set in bytes"); rde_set_count = ometric_new(OMT_GAUGE, - "bgpd_rde_set_count", "number of object in set"); + "bgpd_rde_set_usage_objects", "number of object in set"); rde_table_count = ometric_new(OMT_GAUGE, - "bgpd_rde_table_count", "number of as_set tables"); + "bgpd_rde_set_usage_tables", "number of as_set tables"); } static void -- 2.20.1