open5gs/src/pcf/metrics.c

315 lines
9.1 KiB
C
Raw Normal View History

[PCF] Add metrics support Expose metrics with labels according to ETSI TS 128 552 V16.13.0 in PCF by using hash. The metrics are named respecting the rule: <generation>_<measurement_object_class>_<measurement_family_name>_<metric_name_as_in_TS_128_552> Since slice itself is not unique, the plmnid label is exposed in addition to snssai. AM policy: fivegs_pcffunction_pa_policyamassoreq and fivegs_pcffunction_pa_policyamassosucc do not expose snssai label since it is not available at the time of exposure. plmnid is defined during AM policy processing, so not to lose the difference to ...succ, the basic metric fivegs_pcffunction_pa_policyamassoreq is preserved. SM policy: snssai is defined during SM policy processing, so not to lose the difference to ...succ, the basic metric fivegs_pcffunction_pa_policysmassoreq is preserved. Those 2 basic metrics retain their position but are exposed with empty labels. Metrics with labels are called later, when the label values are known. Exposed metrics example: -standard counters: fivegs_pcffunction_pa_policyamassoreq{plmnid=""} 3 fivegs_pcffunction_pa_policyamassoreq{plmnid="99970"} 3 fivegs_pcffunction_pa_policyamassosucc{plmnid="99970"} 3 fivegs_pcffunction_pa_policysmassoreq{plmnid="",snssai=""} 3 fivegs_pcffunction_pa_policysmassoreq{plmnid="99970",snssai="1000009"} 3 fivegs_pcffunction_pa_policysmassosucc{plmnid="99970",snssai="1000009"} 3 -nonstandard gauge (added for controlling purposes - same metric as existing metric on AMF and SMF): fivegs_pcffunction_pa_sessionnbr{plmnid="99970",snssai="1000009"} 0
2022-08-18 10:20:26 +00:00
#include "ogs-app.h"
#include "context.h"
#include "metrics.h"
typedef struct pcf_metrics_spec_def_s {
unsigned int type;
const char *name;
const char *description;
int initial_val;
unsigned int num_labels;
const char **labels;
} pcf_metrics_spec_def_t;
/* Helper generic functions: */
static int pcf_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 pcf_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 pcf_metrics_init_spec(ogs_metrics_context_t *ctx,
ogs_metrics_spec_t **dst, pcf_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);
}
return OGS_OK;
}
/* GLOBAL */
ogs_metrics_spec_t *pcf_metrics_spec_global[_PCF_METR_GLOB_MAX];
ogs_metrics_inst_t *pcf_metrics_inst_global[_PCF_METR_GLOB_MAX];
pcf_metrics_spec_def_t pcf_metrics_spec_def_global[_PCF_METR_GLOB_MAX] = {
/* Global Counters: */
/* Global Gauges: */
};
int pcf_metrics_init_inst_global(void)
[PCF] Add metrics support Expose metrics with labels according to ETSI TS 128 552 V16.13.0 in PCF by using hash. The metrics are named respecting the rule: <generation>_<measurement_object_class>_<measurement_family_name>_<metric_name_as_in_TS_128_552> Since slice itself is not unique, the plmnid label is exposed in addition to snssai. AM policy: fivegs_pcffunction_pa_policyamassoreq and fivegs_pcffunction_pa_policyamassosucc do not expose snssai label since it is not available at the time of exposure. plmnid is defined during AM policy processing, so not to lose the difference to ...succ, the basic metric fivegs_pcffunction_pa_policyamassoreq is preserved. SM policy: snssai is defined during SM policy processing, so not to lose the difference to ...succ, the basic metric fivegs_pcffunction_pa_policysmassoreq is preserved. Those 2 basic metrics retain their position but are exposed with empty labels. Metrics with labels are called later, when the label values are known. Exposed metrics example: -standard counters: fivegs_pcffunction_pa_policyamassoreq{plmnid=""} 3 fivegs_pcffunction_pa_policyamassoreq{plmnid="99970"} 3 fivegs_pcffunction_pa_policyamassosucc{plmnid="99970"} 3 fivegs_pcffunction_pa_policysmassoreq{plmnid="",snssai=""} 3 fivegs_pcffunction_pa_policysmassoreq{plmnid="99970",snssai="1000009"} 3 fivegs_pcffunction_pa_policysmassosucc{plmnid="99970",snssai="1000009"} 3 -nonstandard gauge (added for controlling purposes - same metric as existing metric on AMF and SMF): fivegs_pcffunction_pa_sessionnbr{plmnid="99970",snssai="1000009"} 0
2022-08-18 10:20:26 +00:00
{
return pcf_metrics_init_inst(pcf_metrics_inst_global,
pcf_metrics_spec_global, _PCF_METR_GLOB_MAX, 0, NULL);
}
int pcf_metrics_free_inst_global(void)
[PCF] Add metrics support Expose metrics with labels according to ETSI TS 128 552 V16.13.0 in PCF by using hash. The metrics are named respecting the rule: <generation>_<measurement_object_class>_<measurement_family_name>_<metric_name_as_in_TS_128_552> Since slice itself is not unique, the plmnid label is exposed in addition to snssai. AM policy: fivegs_pcffunction_pa_policyamassoreq and fivegs_pcffunction_pa_policyamassosucc do not expose snssai label since it is not available at the time of exposure. plmnid is defined during AM policy processing, so not to lose the difference to ...succ, the basic metric fivegs_pcffunction_pa_policyamassoreq is preserved. SM policy: snssai is defined during SM policy processing, so not to lose the difference to ...succ, the basic metric fivegs_pcffunction_pa_policysmassoreq is preserved. Those 2 basic metrics retain their position but are exposed with empty labels. Metrics with labels are called later, when the label values are known. Exposed metrics example: -standard counters: fivegs_pcffunction_pa_policyamassoreq{plmnid=""} 3 fivegs_pcffunction_pa_policyamassoreq{plmnid="99970"} 3 fivegs_pcffunction_pa_policyamassosucc{plmnid="99970"} 3 fivegs_pcffunction_pa_policysmassoreq{plmnid="",snssai=""} 3 fivegs_pcffunction_pa_policysmassoreq{plmnid="99970",snssai="1000009"} 3 fivegs_pcffunction_pa_policysmassosucc{plmnid="99970",snssai="1000009"} 3 -nonstandard gauge (added for controlling purposes - same metric as existing metric on AMF and SMF): fivegs_pcffunction_pa_sessionnbr{plmnid="99970",snssai="1000009"} 0
2022-08-18 10:20:26 +00:00
{
return pcf_metrics_free_inst(pcf_metrics_inst_global, _PCF_METR_GLOB_MAX);
}
/* BY_PLMN */
const char *labels_plmn[] = {
"plmnid"
};
#define PCF_METR_BY_PLMN_CTR_ENTRY(_id, _name, _desc) \
[_id] = { \
.type = OGS_METRICS_METRIC_TYPE_COUNTER, \
.name = _name, \
.description = _desc, \
.num_labels = OGS_ARRAY_SIZE(labels_plmn), \
.labels = labels_plmn, \
},
ogs_metrics_spec_t *pcf_metrics_spec_by_plmn[_PCF_METR_BY_PLMN_MAX];
ogs_hash_t *metrics_hash_by_plmn = NULL; /* hash table for PLMN label */
pcf_metrics_spec_def_t pcf_metrics_spec_def_by_plmn[_PCF_METR_BY_PLMN_MAX] = {
/* Counters: */
PCF_METR_BY_PLMN_CTR_ENTRY(
PCF_METR_CTR_PA_POLICYAMASSOREQ,
"fivegs_pcffunction_pa_policyamassoreq",
"Number of AM policy association requests")
PCF_METR_BY_PLMN_CTR_ENTRY(
PCF_METR_CTR_PA_POLICYAMASSOSUCC,
"fivegs_pcffunction_pa_policyamassosucc",
"Number of successful AM policy associations")
};
void pcf_metrics_init_by_plmn(void);
int pcf_metrics_free_inst_by_plmn(ogs_metrics_inst_t **inst);
typedef struct pcf_metric_key_by_plmn_s {
ogs_plmn_id_t plmn_id;
pcf_metric_type_by_plmn_t t;
} pcf_metric_key_by_plmn_t;
void pcf_metrics_init_by_plmn(void)
{
metrics_hash_by_plmn = ogs_hash_make();
ogs_assert(metrics_hash_by_plmn);
}
void pcf_metrics_inst_by_plmn_add(ogs_plmn_id_t *plmn,
pcf_metric_type_by_plmn_t t, int val)
{
ogs_metrics_inst_t *metrics = NULL;
pcf_metric_key_by_plmn_t *plmn_key;
plmn_key = ogs_calloc(1, sizeof(*plmn_key));
ogs_assert(plmn_key);
if (plmn) {
plmn_key->plmn_id = *plmn;
}
plmn_key->t = t;
metrics = ogs_hash_get(metrics_hash_by_plmn,
plmn_key, sizeof(*plmn_key));
if (!metrics) {
char plmn_id[OGS_PLMNIDSTRLEN] = "";
if (plmn) {
ogs_plmn_id_to_string(plmn, plmn_id);
}
metrics = ogs_metrics_inst_new(pcf_metrics_spec_by_plmn[t],
pcf_metrics_spec_def_by_plmn->num_labels,
(const char *[]){ plmn_id });
ogs_assert(metrics);
ogs_hash_set(metrics_hash_by_plmn,
plmn_key, sizeof(*plmn_key), metrics);
} else {
ogs_free(plmn_key);
}
ogs_metrics_inst_add(metrics, val);
}
int pcf_metrics_free_inst_by_plmn(ogs_metrics_inst_t **inst)
{
return pcf_metrics_free_inst(inst, _PCF_METR_BY_PLMN_MAX);
}
/* BY_SLICE */
const char *labels_slice[] = {
"plmnid",
"snssai"
};
#define PCF_METR_BY_SLICE_CTR_ENTRY(_id, _name, _desc) \
[_id] = { \
.type = OGS_METRICS_METRIC_TYPE_COUNTER, \
.name = _name, \
.description = _desc, \
.num_labels = OGS_ARRAY_SIZE(labels_slice), \
.labels = labels_slice, \
},
#define PCF_METR_BY_SLICE_GAUGE_ENTRY(_id, _name, _desc) \
[_id] = { \
.type = OGS_METRICS_METRIC_TYPE_GAUGE, \
.name = _name, \
.description = _desc, \
.num_labels = OGS_ARRAY_SIZE(labels_slice), \
.labels = labels_slice, \
},
ogs_metrics_spec_t *pcf_metrics_spec_by_slice[_PCF_METR_BY_SLICE_MAX];
ogs_hash_t *metrics_hash_by_slice = NULL; /* hash table for SLICE labels */
pcf_metrics_spec_def_t pcf_metrics_spec_def_by_slice[_PCF_METR_BY_SLICE_MAX] = {
/* Counters: */
PCF_METR_BY_SLICE_CTR_ENTRY(
PCF_METR_CTR_PA_POLICYSMASSOREQ,
"fivegs_pcffunction_pa_policysmassoreq",
"Number of SM policy association requests")
PCF_METR_BY_SLICE_CTR_ENTRY(
PCF_METR_CTR_PA_POLICYSMASSOSUCC,
"fivegs_pcffunction_pa_policysmassosucc",
"Number of successful SM policy associations")
/* Gauges: */
PCF_METR_BY_SLICE_GAUGE_ENTRY(
PCF_METR_GAUGE_PA_SESSIONNBR,
"fivegs_pcffunction_pa_sessionnbr",
"Active Sessions")
};
void pcf_metrics_init_by_slice(void);
int pcf_metrics_free_inst_by_slice(ogs_metrics_inst_t **inst);
typedef struct pcf_metric_key_by_slice_s {
ogs_plmn_id_t plmn_id;
ogs_s_nssai_t snssai;
pcf_metric_type_by_slice_t t;
} pcf_metric_key_by_slice_t;
void pcf_metrics_init_by_slice(void)
{
metrics_hash_by_slice = ogs_hash_make();
ogs_assert(metrics_hash_by_slice);
}
void pcf_metrics_inst_by_slice_add(ogs_plmn_id_t *plmn,
ogs_s_nssai_t *snssai, pcf_metric_type_by_slice_t t, int val)
{
ogs_metrics_inst_t *metrics = NULL;
pcf_metric_key_by_slice_t *slice_key;
slice_key = ogs_calloc(1, sizeof(*slice_key));
ogs_assert(slice_key);
if (plmn) {
slice_key->plmn_id = *plmn;
}
if (snssai) {
slice_key->snssai = *snssai;
} else {
slice_key->snssai.sst = 0;
slice_key->snssai.sd.v = OGS_S_NSSAI_NO_SD_VALUE;
}
slice_key->t = t;
metrics = ogs_hash_get(metrics_hash_by_slice,
slice_key, sizeof(*slice_key));
if (!metrics) {
char plmn_id[OGS_PLMNIDSTRLEN] = "";
char *s_nssai = NULL;
if (plmn) {
ogs_plmn_id_to_string(plmn, plmn_id);
}
if (snssai) {
s_nssai = ogs_sbi_s_nssai_to_string_plain(snssai);
} else {
s_nssai = ogs_strdup("");
}
metrics = ogs_metrics_inst_new(pcf_metrics_spec_by_slice[t],
pcf_metrics_spec_def_by_slice->num_labels,
(const char *[]){ plmn_id, s_nssai });
ogs_assert(metrics);
ogs_hash_set(metrics_hash_by_slice,
slice_key, sizeof(*slice_key), metrics);
if (s_nssai)
ogs_free(s_nssai);
} else {
ogs_free(slice_key);
}
ogs_metrics_inst_add(metrics, val);
}
int pcf_metrics_free_inst_by_slice(ogs_metrics_inst_t **inst)
{
return pcf_metrics_free_inst(inst, _PCF_METR_BY_SLICE_MAX);
}
void pcf_metrics_init(void)
[PCF] Add metrics support Expose metrics with labels according to ETSI TS 128 552 V16.13.0 in PCF by using hash. The metrics are named respecting the rule: <generation>_<measurement_object_class>_<measurement_family_name>_<metric_name_as_in_TS_128_552> Since slice itself is not unique, the plmnid label is exposed in addition to snssai. AM policy: fivegs_pcffunction_pa_policyamassoreq and fivegs_pcffunction_pa_policyamassosucc do not expose snssai label since it is not available at the time of exposure. plmnid is defined during AM policy processing, so not to lose the difference to ...succ, the basic metric fivegs_pcffunction_pa_policyamassoreq is preserved. SM policy: snssai is defined during SM policy processing, so not to lose the difference to ...succ, the basic metric fivegs_pcffunction_pa_policysmassoreq is preserved. Those 2 basic metrics retain their position but are exposed with empty labels. Metrics with labels are called later, when the label values are known. Exposed metrics example: -standard counters: fivegs_pcffunction_pa_policyamassoreq{plmnid=""} 3 fivegs_pcffunction_pa_policyamassoreq{plmnid="99970"} 3 fivegs_pcffunction_pa_policyamassosucc{plmnid="99970"} 3 fivegs_pcffunction_pa_policysmassoreq{plmnid="",snssai=""} 3 fivegs_pcffunction_pa_policysmassoreq{plmnid="99970",snssai="1000009"} 3 fivegs_pcffunction_pa_policysmassosucc{plmnid="99970",snssai="1000009"} 3 -nonstandard gauge (added for controlling purposes - same metric as existing metric on AMF and SMF): fivegs_pcffunction_pa_sessionnbr{plmnid="99970",snssai="1000009"} 0
2022-08-18 10:20:26 +00:00
{
ogs_metrics_context_t *ctx = ogs_metrics_self();
ogs_metrics_context_init();
[PCF] Add metrics support Expose metrics with labels according to ETSI TS 128 552 V16.13.0 in PCF by using hash. The metrics are named respecting the rule: <generation>_<measurement_object_class>_<measurement_family_name>_<metric_name_as_in_TS_128_552> Since slice itself is not unique, the plmnid label is exposed in addition to snssai. AM policy: fivegs_pcffunction_pa_policyamassoreq and fivegs_pcffunction_pa_policyamassosucc do not expose snssai label since it is not available at the time of exposure. plmnid is defined during AM policy processing, so not to lose the difference to ...succ, the basic metric fivegs_pcffunction_pa_policyamassoreq is preserved. SM policy: snssai is defined during SM policy processing, so not to lose the difference to ...succ, the basic metric fivegs_pcffunction_pa_policysmassoreq is preserved. Those 2 basic metrics retain their position but are exposed with empty labels. Metrics with labels are called later, when the label values are known. Exposed metrics example: -standard counters: fivegs_pcffunction_pa_policyamassoreq{plmnid=""} 3 fivegs_pcffunction_pa_policyamassoreq{plmnid="99970"} 3 fivegs_pcffunction_pa_policyamassosucc{plmnid="99970"} 3 fivegs_pcffunction_pa_policysmassoreq{plmnid="",snssai=""} 3 fivegs_pcffunction_pa_policysmassoreq{plmnid="99970",snssai="1000009"} 3 fivegs_pcffunction_pa_policysmassosucc{plmnid="99970",snssai="1000009"} 3 -nonstandard gauge (added for controlling purposes - same metric as existing metric on AMF and SMF): fivegs_pcffunction_pa_sessionnbr{plmnid="99970",snssai="1000009"} 0
2022-08-18 10:20:26 +00:00
pcf_metrics_init_spec(ctx, pcf_metrics_spec_global,
pcf_metrics_spec_def_global, _PCF_METR_GLOB_MAX);
pcf_metrics_init_spec(ctx, pcf_metrics_spec_by_plmn,
pcf_metrics_spec_def_by_plmn, _PCF_METR_BY_PLMN_MAX);
pcf_metrics_init_spec(ctx, pcf_metrics_spec_by_slice,
pcf_metrics_spec_def_by_slice, _PCF_METR_BY_SLICE_MAX);
pcf_metrics_init_inst_global();
pcf_metrics_init_by_plmn();
pcf_metrics_init_by_slice();
}
void pcf_metrics_final(void)
[PCF] Add metrics support Expose metrics with labels according to ETSI TS 128 552 V16.13.0 in PCF by using hash. The metrics are named respecting the rule: <generation>_<measurement_object_class>_<measurement_family_name>_<metric_name_as_in_TS_128_552> Since slice itself is not unique, the plmnid label is exposed in addition to snssai. AM policy: fivegs_pcffunction_pa_policyamassoreq and fivegs_pcffunction_pa_policyamassosucc do not expose snssai label since it is not available at the time of exposure. plmnid is defined during AM policy processing, so not to lose the difference to ...succ, the basic metric fivegs_pcffunction_pa_policyamassoreq is preserved. SM policy: snssai is defined during SM policy processing, so not to lose the difference to ...succ, the basic metric fivegs_pcffunction_pa_policysmassoreq is preserved. Those 2 basic metrics retain their position but are exposed with empty labels. Metrics with labels are called later, when the label values are known. Exposed metrics example: -standard counters: fivegs_pcffunction_pa_policyamassoreq{plmnid=""} 3 fivegs_pcffunction_pa_policyamassoreq{plmnid="99970"} 3 fivegs_pcffunction_pa_policyamassosucc{plmnid="99970"} 3 fivegs_pcffunction_pa_policysmassoreq{plmnid="",snssai=""} 3 fivegs_pcffunction_pa_policysmassoreq{plmnid="99970",snssai="1000009"} 3 fivegs_pcffunction_pa_policysmassosucc{plmnid="99970",snssai="1000009"} 3 -nonstandard gauge (added for controlling purposes - same metric as existing metric on AMF and SMF): fivegs_pcffunction_pa_sessionnbr{plmnid="99970",snssai="1000009"} 0
2022-08-18 10:20:26 +00:00
{
ogs_hash_index_t *hi;
if (metrics_hash_by_slice) {
for (hi = ogs_hash_first(metrics_hash_by_slice); hi; hi = ogs_hash_next(hi)) {
pcf_metric_key_by_slice_t *key =
(pcf_metric_key_by_slice_t *)ogs_hash_this_key(hi);
//void *val = ogs_hash_this_val(hi);
ogs_hash_set(metrics_hash_by_slice, key, sizeof(*key), NULL);
ogs_free(key);
/* don't free val (metric itself) -
* it will be free'd by ogs_metrics_context_final() */
//ogs_free(val);
}
ogs_hash_destroy(metrics_hash_by_slice);
}
if (metrics_hash_by_plmn) {
for (hi = ogs_hash_first(metrics_hash_by_plmn); hi; hi = ogs_hash_next(hi)) {
pcf_metric_key_by_plmn_t *key =
(pcf_metric_key_by_plmn_t *)ogs_hash_this_key(hi);
//void *val = ogs_hash_this_val(hi);
ogs_hash_set(metrics_hash_by_plmn, key, sizeof(*key), NULL);
ogs_free(key);
/* don't free val (metric ifself) -
* it will be free'd by ogs_metrics_context_final() */
//ogs_free(val);
}
ogs_hash_destroy(metrics_hash_by_plmn);
}
ogs_metrics_context_final();
[PCF] Add metrics support Expose metrics with labels according to ETSI TS 128 552 V16.13.0 in PCF by using hash. The metrics are named respecting the rule: <generation>_<measurement_object_class>_<measurement_family_name>_<metric_name_as_in_TS_128_552> Since slice itself is not unique, the plmnid label is exposed in addition to snssai. AM policy: fivegs_pcffunction_pa_policyamassoreq and fivegs_pcffunction_pa_policyamassosucc do not expose snssai label since it is not available at the time of exposure. plmnid is defined during AM policy processing, so not to lose the difference to ...succ, the basic metric fivegs_pcffunction_pa_policyamassoreq is preserved. SM policy: snssai is defined during SM policy processing, so not to lose the difference to ...succ, the basic metric fivegs_pcffunction_pa_policysmassoreq is preserved. Those 2 basic metrics retain their position but are exposed with empty labels. Metrics with labels are called later, when the label values are known. Exposed metrics example: -standard counters: fivegs_pcffunction_pa_policyamassoreq{plmnid=""} 3 fivegs_pcffunction_pa_policyamassoreq{plmnid="99970"} 3 fivegs_pcffunction_pa_policyamassosucc{plmnid="99970"} 3 fivegs_pcffunction_pa_policysmassoreq{plmnid="",snssai=""} 3 fivegs_pcffunction_pa_policysmassoreq{plmnid="99970",snssai="1000009"} 3 fivegs_pcffunction_pa_policysmassosucc{plmnid="99970",snssai="1000009"} 3 -nonstandard gauge (added for controlling purposes - same metric as existing metric on AMF and SMF): fivegs_pcffunction_pa_sessionnbr{plmnid="99970",snssai="1000009"} 0
2022-08-18 10:20:26 +00:00
}