diff --git a/src/hss/hss-context.c b/src/hss/hss-context.c index fede57703..f80cded8d 100644 --- a/src/hss/hss-context.c +++ b/src/hss/hss-context.c @@ -337,6 +337,8 @@ int hss_context_parse_config(void) #else self.use_mongodb_change_stream = false; #endif + } else if (!strcmp(hss_key, "metrics")) { + /* handle config in metrics library */ } else ogs_warn("unknown key `%s`", hss_key); } @@ -519,6 +521,7 @@ static hss_imsi_t *imsi_add(char *id) ogs_hash_set(self.imsi_hash, imsi->id, strlen(imsi->id), imsi); ogs_list_add(&self.imsi_list, imsi); + hss_metrics_inst_global_inc(HSS_METR_GLOB_GAUGE_IMSI); return imsi; } @@ -528,6 +531,7 @@ static void imsi_remove(hss_imsi_t *imsi) ogs_assert(imsi); ogs_list_remove(&self.imsi_list, imsi); + hss_metrics_inst_global_dec(HSS_METR_GLOB_GAUGE_IMSI); ogs_assert(imsi->id); ogs_hash_set(self.imsi_hash, imsi->id, strlen(imsi->id), NULL); @@ -569,6 +573,7 @@ static hss_impi_t *impi_add(char *id) ogs_hash_set(self.impi_hash, impi->id, strlen(impi->id), impi); ogs_list_add(&self.impi_list, impi); + hss_metrics_inst_global_inc(HSS_METR_GLOB_GAUGE_IMPI); return impi; } @@ -578,6 +583,7 @@ static void impi_remove(hss_impi_t *impi) ogs_assert(impi); ogs_list_remove(&self.impi_list, impi); + hss_metrics_inst_global_dec(HSS_METR_GLOB_GAUGE_IMPI); impu_remove_all(impi); @@ -633,7 +639,9 @@ static hss_impu_t *impu_add(hss_impi_t *impi, char *id) ogs_hash_set(self.impu_hash, impu->id, strlen(impu->id), impu); impu->impi = impi; + ogs_list_add(&impi->impu_list, impu); + hss_metrics_inst_global_inc(HSS_METR_GLOB_GAUGE_IMPU); return impu; } @@ -647,6 +655,7 @@ static void impu_remove(hss_impu_t *impu) ogs_assert(impi); ogs_list_remove(&impi->impu_list, impu); + hss_metrics_inst_global_dec(HSS_METR_GLOB_GAUGE_IMPU); ogs_assert(impu->id); ogs_hash_set(self.impu_hash, impu->id, strlen(impu->id), NULL); diff --git a/src/hss/hss-context.h b/src/hss/hss-context.h index b5afd46b4..1fe0ddc70 100644 --- a/src/hss/hss-context.h +++ b/src/hss/hss-context.h @@ -25,6 +25,7 @@ #include "ogs-diameter-swx.h" #include "ogs-dbi.h" #include "ogs-app.h" +#include "metrics.h" #ifdef __cplusplus extern "C" { diff --git a/src/hss/hss-init.c b/src/hss/hss-init.c index 305d9ef22..7d8139e83 100644 --- a/src/hss/hss-init.c +++ b/src/hss/hss-init.c @@ -20,6 +20,7 @@ #include "hss-context.h" #include "hss-fd-path.h" #include "hss-sm.h" +#include "metrics.h" static ogs_thread_t *thread; @@ -35,9 +36,14 @@ int hss_initialize(void) rv = ogs_app_parse_local_conf(APP_NAME); if (rv != OGS_OK) return rv; + hss_metrics_init(); + hss_context_init(); hss_event_init(); + rv = ogs_metrics_context_parse_config(APP_NAME); + if (rv != OGS_OK) return rv; + rv = hss_context_parse_config(); if (rv != OGS_OK) return rv; @@ -45,6 +51,8 @@ int hss_initialize(void) ogs_app()->logger.domain, ogs_app()->logger.level); if (rv != OGS_OK) return rv; + ogs_metrics_context_open(ogs_metrics_self()); + rv = ogs_dbi_init(ogs_app()->db_uri); if (rv != OGS_OK) return rv; @@ -65,12 +73,14 @@ void hss_terminate(void) hss_event_term(); ogs_thread_destroy(thread); + ogs_metrics_context_close(ogs_metrics_self()); hss_fd_final(); ogs_dbi_final(); hss_context_final(); hss_event_final(); + hss_metrics_final(); return; } diff --git a/src/hss/meson.build b/src/hss/meson.build index 83130a444..378139eea 100644 --- a/src/hss/meson.build +++ b/src/hss/meson.build @@ -22,6 +22,7 @@ libhss_sources = files(''' hss-event.h hss-timer.h hss-sm.h + metrics.h hss-init.c hss-context.c @@ -34,11 +35,14 @@ libhss_sources = files(''' hss-swx-path.c hss-fd-path.c + + metrics.c '''.split()) libhss = static_library('hss', sources : libhss_sources, - dependencies : [libapp_dep, + dependencies : [libmetrics_dep, + libapp_dep, libcrypt_dep, libdbi_dep, libdiameter_s6a_dep, @@ -48,7 +52,8 @@ libhss = static_library('hss', libhss_dep = declare_dependency( link_with : libhss, - dependencies : [libapp_dep, + dependencies : [libmetrics_dep, + libapp_dep, libcrypt_dep, libdbi_dep, libdiameter_s6a_dep, diff --git a/src/hss/metrics.c b/src/hss/metrics.c new file mode 100644 index 000000000..b14426095 --- /dev/null +++ b/src/hss/metrics.c @@ -0,0 +1,93 @@ +#include "ogs-app.h" +#include "hss-context.h" + +#include "metrics.h" + +typedef struct hss_metrics_spec_def_s { + unsigned int type; + const char *name; + const char *description; + int initial_val; + unsigned int num_labels; + const char **labels; +} hss_metrics_spec_def_t; + +/* Helper generic functions: */ +static int hss_metrics_init_inst(ogs_metrics_inst_t **inst, ogs_metrics_spec_t **specs, + unsigned int len, unsigned int num_labels, const char **labels) +{ + unsigned int i; + for (i = 0; i < len; i++) + inst[i] = ogs_metrics_inst_new(specs[i], num_labels, labels); + return OGS_OK; +} + +static int hss_metrics_free_inst(ogs_metrics_inst_t **inst, + unsigned int len) +{ + unsigned int i; + for (i = 0; i < len; i++) + ogs_metrics_inst_free(inst[i]); + memset(inst, 0, sizeof(inst[0]) * len); + return OGS_OK; +} + +static int hss_metrics_init_spec(ogs_metrics_context_t *ctx, + ogs_metrics_spec_t **dst, hss_metrics_spec_def_t *src, unsigned int len) +{ + unsigned int i; + for (i = 0; i < len; i++) { + dst[i] = ogs_metrics_spec_new(ctx, src[i].type, + src[i].name, src[i].description, + src[i].initial_val, src[i].num_labels, src[i].labels, + NULL); + } + return OGS_OK; +} + +/* GLOBAL */ +ogs_metrics_spec_t *hss_metrics_spec_global[_HSS_METR_GLOB_MAX]; +ogs_metrics_inst_t *hss_metrics_inst_global[_HSS_METR_GLOB_MAX]; +hss_metrics_spec_def_t hss_metrics_spec_def_global[_HSS_METR_GLOB_MAX] = { +/* Global Gauges: */ +[HSS_METR_GLOB_GAUGE_IMSI] = { + .type = OGS_METRICS_METRIC_TYPE_GAUGE, + .name = "hss_imsi", + .description = "Number of IMSIs attached to HSS", +}, +[HSS_METR_GLOB_GAUGE_IMPI] = { + .type = OGS_METRICS_METRIC_TYPE_GAUGE, + .name = "hss_impi", + .description = "Number of IMPIs attached to HSS", +}, +[HSS_METR_GLOB_GAUGE_IMPU] = { + .type = OGS_METRICS_METRIC_TYPE_GAUGE, + .name = "hss_impu", + .description = "Number of IMPUs attached to HSS", +}, +}; +int hss_metrics_init_inst_global(void) +{ + return hss_metrics_init_inst(hss_metrics_inst_global, hss_metrics_spec_global, + _HSS_METR_GLOB_MAX, 0, NULL); +} +int hss_metrics_free_inst_global(void) +{ + return hss_metrics_free_inst(hss_metrics_inst_global, _HSS_METR_GLOB_MAX); +} + +void hss_metrics_init(void) +{ + ogs_metrics_context_t *ctx = ogs_metrics_self(); + ogs_metrics_context_init(); + + hss_metrics_init_spec(ctx, hss_metrics_spec_global, hss_metrics_spec_def_global, + _HSS_METR_GLOB_MAX); + + hss_metrics_init_inst_global(); +} + +void hss_metrics_final(void) +{ + ogs_metrics_context_final(); +} diff --git a/src/hss/metrics.h b/src/hss/metrics.h new file mode 100644 index 000000000..c0b36a33f --- /dev/null +++ b/src/hss/metrics.h @@ -0,0 +1,38 @@ +#ifndef HSS_METRICS_H +#define HSS_METRICS_H + +#include "ogs-metrics.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* GLOBAL */ +typedef enum hss_metric_type_global_s { + HSS_METR_GLOB_GAUGE_IMSI, + HSS_METR_GLOB_GAUGE_IMPI, + HSS_METR_GLOB_GAUGE_IMPU, + _HSS_METR_GLOB_MAX, +} hss_metric_type_global_t; +extern ogs_metrics_inst_t *hss_metrics_inst_global[_HSS_METR_GLOB_MAX]; + +int hss_metrics_init_inst_global(void); +int hss_metrics_free_inst_global(void); + +static inline void hss_metrics_inst_global_set(hss_metric_type_global_t t, int val) +{ ogs_metrics_inst_set(hss_metrics_inst_global[t], val); } +static inline void hss_metrics_inst_global_add(hss_metric_type_global_t t, int val) +{ ogs_metrics_inst_add(hss_metrics_inst_global[t], val); } +static inline void hss_metrics_inst_global_inc(hss_metric_type_global_t t) +{ ogs_metrics_inst_inc(hss_metrics_inst_global[t]); } +static inline void hss_metrics_inst_global_dec(hss_metric_type_global_t t) +{ ogs_metrics_inst_dec(hss_metrics_inst_global[t]); } + +void hss_metrics_init(void); +void hss_metrics_final(void); + +#ifdef __cplusplus +} +#endif + +#endif /* HSS_METRICS_H */