From 40351e5a387529b51fd2cb4d9563db9a96371ff5 Mon Sep 17 00:00:00 2001 From: Bostjan Meglic Date: Mon, 13 Oct 2025 11:33:54 +0200 Subject: [PATCH] [ue-info] consolidate separate function pointers into custom endpoints Instead of predetermined endpoints in the metrics library, each NF can now set it's own endpoints on which it listens for requests to dump info (UE/PDU/gNB/eNB). --- lib/metrics/context.c | 50 +++++++++++++++--------------- lib/metrics/context.h | 18 +++++++++++ lib/metrics/ogs-metrics.h | 12 -------- lib/metrics/prometheus/context.c | 53 ++++++++------------------------ src/amf/init.c | 4 +-- src/mme/mme-init.c | 4 +-- src/smf/init.c | 2 +- 7 files changed, 61 insertions(+), 82 deletions(-) diff --git a/lib/metrics/context.c b/lib/metrics/context.c index d5d4ca6ef..016f9be6b 100644 --- a/lib/metrics/context.c +++ b/lib/metrics/context.c @@ -25,31 +25,6 @@ #define DEFAULT_PROMETHEUS_HTTP_PORT 9090 -size_t (*ogs_metrics_pdu_info_dumper)(char *buf, size_t buflen, size_t page, size_t page_size) = NULL; -size_t (*ogs_metrics_ue_info_dumper)(char *buf, size_t buflen, size_t page, size_t page_size) = NULL; -size_t (*ogs_metrics_gnb_info_dumper)(char *buf, size_t buflen, size_t page, size_t page_size) = NULL; -size_t (*ogs_metrics_enb_info_dumper)(char *buf, size_t buflen, size_t page, size_t page_size) = NULL; - -void ogs_metrics_register_ue_info(size_t (*fn)(char *buf, size_t buflen, size_t page, size_t page_size)) -{ - ogs_metrics_ue_info_dumper = fn; -} - -void ogs_metrics_register_pdu_info(size_t (*fn)(char *buf, size_t buflen, size_t page, size_t page_size)) -{ - ogs_metrics_pdu_info_dumper = fn; -} - -void ogs_metrics_register_gnb_info(size_t (*fn)(char *buf, size_t buflen, size_t page, size_t page_size)) -{ - ogs_metrics_gnb_info_dumper = fn; -} - -void ogs_metrics_register_enb_info(size_t (*fn)(char *buf, size_t buflen, size_t page, size_t page_size)) -{ - ogs_metrics_enb_info_dumper = fn; -} - int __ogs_metrics_domain; static ogs_metrics_context_t self; static int context_initialized = 0; @@ -66,6 +41,8 @@ void ogs_metrics_context_init(void) ogs_metrics_spec_init(ogs_metrics_self()); ogs_metrics_server_init(ogs_metrics_self()); + ogs_list_init(&self.custom_eps); + context_initialized = 1; } @@ -75,7 +52,15 @@ void ogs_metrics_context_open(ogs_metrics_context_t *ctx) } void ogs_metrics_context_close(ogs_metrics_context_t *ctx) { + ogs_metrics_custom_ep_t *node = NULL, *node_next = NULL; + ogs_metrics_server_close(ctx); + + ogs_list_for_each_safe(&self.custom_eps, node_next, node) { + if (node->endpoint) ogs_free(node->endpoint); + ogs_list_remove(&self.custom_eps, node); + ogs_free(node); + } } void ogs_metrics_context_final(void) @@ -291,3 +276,18 @@ int ogs_metrics_context_parse_config(const char *local) return OGS_OK; } + + +void ogs_metrics_register_custom_ep(ogs_metrics_custom_ep_hdlr_t handler, + const char *endpoint) +{ + ogs_metrics_custom_ep_t *ep; + + ep = ogs_calloc(1, sizeof(*ep)); + ogs_assert(ep); + + ep->endpoint = ogs_strdup(endpoint); + ep->handler = handler; + + ogs_list_add(&self.custom_eps, ep); +} diff --git a/lib/metrics/context.h b/lib/metrics/context.h index 5b1a92039..b8060aeec 100644 --- a/lib/metrics/context.h +++ b/lib/metrics/context.h @@ -41,6 +41,9 @@ typedef struct ogs_metrics_context_s { ogs_list_t spec_list; uint16_t metrics_port; + + /* custom endpoints */ + ogs_list_t custom_eps; } ogs_metrics_context_t; typedef enum ogs_metrics_histogram_bucket_type_s { @@ -112,6 +115,21 @@ static inline void ogs_metrics_inst_dec(ogs_metrics_inst_t *inst) ogs_metrics_inst_add(inst, -1); } + +typedef size_t (*ogs_metrics_custom_ep_hdlr_t)( + char *buf, size_t buflen, size_t page, size_t page_size); + +typedef struct ogs_metrics_custom_ep_s { + ogs_lnode_t lnode; + + char *endpoint; + ogs_metrics_custom_ep_hdlr_t handler; +} ogs_metrics_custom_ep_t; + + +void ogs_metrics_register_custom_ep(ogs_metrics_custom_ep_hdlr_t handler, + const char *endpoint); + #ifdef __cplusplus } #endif diff --git a/lib/metrics/ogs-metrics.h b/lib/metrics/ogs-metrics.h index 71c23f060..1e25c3d31 100644 --- a/lib/metrics/ogs-metrics.h +++ b/lib/metrics/ogs-metrics.h @@ -36,18 +36,6 @@ extern "C" { #endif -extern size_t (*ogs_metrics_pdu_info_dumper)(char *buf, size_t buflen, size_t page, size_t page_size); -void ogs_metrics_register_pdu_info(size_t (*fn)(char *buf, size_t buflen, size_t page, size_t page_size)); - -extern size_t (*ogs_metrics_ue_info_dumper)(char *buf, size_t buflen, size_t page, size_t page_size); -void ogs_metrics_register_ue_info(size_t (*fn)(char *buf, size_t buflen, size_t page, size_t page_size)); - -extern size_t (*ogs_metrics_gnb_info_dumper)(char *buf, size_t buflen, size_t page, size_t page_size); -void ogs_metrics_register_gnb_info(size_t (*fn)(char *buf, size_t buflen, size_t page, size_t page_size)); - -extern size_t (*ogs_metrics_enb_info_dumper)(char *buf, size_t buflen, size_t page, size_t page_size); -void ogs_metrics_register_enb_info(size_t (*fn)(char *buf, size_t buflen, size_t page, size_t page_size)); - #ifdef __cplusplus } diff --git a/lib/metrics/prometheus/context.c b/lib/metrics/prometheus/context.c index 0c3c53d34..a83329028 100644 --- a/lib/metrics/prometheus/context.c +++ b/lib/metrics/prometheus/context.c @@ -194,18 +194,11 @@ typedef int _MHD_Result; /* Small helper to serve JSON from a registered dumper */ static _MHD_Result serve_json_from_dumper(struct MHD_Connection *connection, - size_t (*dumper)(char*, size_t, size_t, size_t), - size_t page, size_t page_size, - const char *missing_msg) + ogs_metrics_custom_ep_hdlr_t handler, + size_t page, size_t page_size) { - if (!dumper) { - struct MHD_Response *rsp = MHD_create_response_from_buffer(strlen(missing_msg), - (void*)missing_msg, MHD_RESPMEM_PERSISTENT); - if (!rsp) return (_MHD_Result)MHD_NO; - int ret = MHD_queue_response(connection, MHD_HTTP_NOT_FOUND, rsp); - MHD_destroy_response(rsp); - return (_MHD_Result)ret; - } + ogs_assert(connection); + ogs_assert(handler); size_t cap = 512 * 1024; char *bufjson = (char *)ogs_malloc(cap); @@ -219,7 +212,7 @@ static _MHD_Result serve_json_from_dumper(struct MHD_Connection *connection, return (_MHD_Result)ret; } - size_t n = dumper(bufjson, cap, page, page_size); + size_t n = handler(bufjson, cap, page, page_size); if (n >= cap - 1) { /* grow once */ size_t newcap = cap * 2; @@ -235,7 +228,7 @@ static _MHD_Result serve_json_from_dumper(struct MHD_Connection *connection, return (_MHD_Result)ret; } bufjson = tmp; cap = newcap; - n = dumper(bufjson, cap, page, page_size); + n = handler(bufjson, cap, page, page_size); if (n >= cap - 1) { /* graceful fallback */ n = ogs_snprintf(bufjson, cap, "[]"); @@ -307,34 +300,14 @@ mhd_server_access_handler(void *cls, struct MHD_Connection *connection, size_t page = get_query_size_t(connection, "page", 0); size_t page_size = get_query_size_t(connection, "page_size", 100); - - /* JSON: connected PDUs (SMF) */ - if (strcmp(url, "/pdu-info") == 0) { - return serve_json_from_dumper(connection, ogs_metrics_pdu_info_dumper, - page, page_size, - "pdu-info endpoint not available on this NF\n"); - } - - /* JSON: connected gNBs (AMF) */ - if (strcmp(url, "/gnb-info") == 0) { - return serve_json_from_dumper(connection, ogs_metrics_gnb_info_dumper, - page, page_size, - "gnb-info endpoint not available on this NF\n"); - } - - /* JSON: connected eNBs (MME) */ - if (strcmp(url, "/enb-info") == 0) { - return serve_json_from_dumper(connection, ogs_metrics_enb_info_dumper, - page, page_size, - "enb-info endpoint not available on this NF\n"); - } - - /* JSON: connected UEs (AMF/MME) */ - if (strcmp(url, "/ue-info") == 0) { - return serve_json_from_dumper(connection, ogs_metrics_ue_info_dumper, - page, page_size, - "ue-info endpoint not available on this NF\n"); + ogs_metrics_custom_ep_t *node = NULL; + ogs_list_for_each(&ogs_metrics_self()->custom_eps, node) { + if (!strcmp(node->endpoint, url)) { + return serve_json_from_dumper(connection, + node->handler, + page, page_size); + } } /* No matching route */ diff --git a/src/amf/init.c b/src/amf/init.c index 7f257a34a..1ee5c9b14 100644 --- a/src/amf/init.c +++ b/src/amf/init.c @@ -62,8 +62,8 @@ int amf_initialize(void) ogs_metrics_context_open(ogs_metrics_self()); /* dumpers /gnb-info /ue-info */ - ogs_metrics_register_gnb_info(amf_dump_gnb_info); - ogs_metrics_register_ue_info(amf_dump_ue_info); + ogs_metrics_register_custom_ep(amf_dump_gnb_info, "/gnb-info"); + ogs_metrics_register_custom_ep(amf_dump_ue_info, "/ue-info"); rv = amf_sbi_open(); if (rv != OGS_OK) return rv; diff --git a/src/mme/mme-init.c b/src/mme/mme-init.c index 4895d43e1..8820493f3 100644 --- a/src/mme/mme-init.c +++ b/src/mme/mme-init.c @@ -71,8 +71,8 @@ int mme_initialize(void) ogs_metrics_context_open(ogs_metrics_self()); /* dumpers /enb-info /ue-info */ - ogs_metrics_register_enb_info(mme_dump_enb_info); - ogs_metrics_register_ue_info(mme_dump_ue_info); + ogs_metrics_register_custom_ep(mme_dump_enb_info, "/enb-info"); + ogs_metrics_register_custom_ep(mme_dump_ue_info, "/ue-info"); rv = mme_fd_init(); if (rv != OGS_OK) return OGS_ERROR; diff --git a/src/smf/init.c b/src/smf/init.c index 7eb8caa38..61d3951ea 100644 --- a/src/smf/init.c +++ b/src/smf/init.c @@ -94,7 +94,7 @@ int smf_initialize(void) if (!thread) return OGS_ERROR; /* dumper /pdu-info */ - ogs_metrics_register_pdu_info(smf_dump_pdu_info); + ogs_metrics_register_custom_ep(smf_dump_pdu_info, "/pdu-info"); initialized = 1;