diff --git a/src/pcrf/metrics.c b/src/pcrf/metrics.c index 6499bbc70..d4820483f 100644 --- a/src/pcrf/metrics.c +++ b/src/pcrf/metrics.c @@ -50,6 +50,88 @@ ogs_metrics_spec_t *pcrf_metrics_spec_global[_PCRF_METR_GLOB_MAX]; ogs_metrics_inst_t *pcrf_metrics_inst_global[_PCRF_METR_GLOB_MAX]; pcrf_metrics_spec_def_t pcrf_metrics_spec_def_global[_PCRF_METR_GLOB_MAX] = { /* Global Counters: */ +/* Global Counters: Gx */ +[PCRF_METR_GLOB_CTR_Gx_RX_UNKNOWN] = { + .type = OGS_METRICS_METRIC_TYPE_COUNTER, + .name = "gx_rx_unknown", + .description = "Received Gx unknown messages", +}, +[PCRF_METR_GLOB_CTR_Gx_RX_CCR] = { + .type = OGS_METRICS_METRIC_TYPE_COUNTER, + .name = "gx_rx_ccr", + .description = "Received Gx CCR messages", +}, +[PCRF_METR_GLOB_CTR_Gx_RX_CCR_ERROR] = { + .type = OGS_METRICS_METRIC_TYPE_COUNTER, + .name = "gx_rx_ccr_error", + .description = "Received Gx CCR messages failed", +}, +[PCRF_METR_GLOB_CTR_Gx_RX_RAA] = { + .type = OGS_METRICS_METRIC_TYPE_COUNTER, + .name = "gx_rx_raa", + .description = "Received Gx RAA messages", +}, +[PCRF_METR_GLOB_CTR_Gx_TX_CCA] = { + .type = OGS_METRICS_METRIC_TYPE_COUNTER, + .name = "gx_tx_cca", + .description = "Received Gx RAA messages failed", +}, +[PCRF_METR_GLOB_CTR_Gx_TX_RAR] = { + .type = OGS_METRICS_METRIC_TYPE_COUNTER, + .name = "gx_tx_rar", + .description = "Transmitted Gx RAR messages", +}, +[PCRF_METR_GLOB_CTR_Gx_TX_RAR_ERROR] = { + .type = OGS_METRICS_METRIC_TYPE_COUNTER, + .name = "gx_tx_rar_error", + .description = "Failed to transmit Gx RAR messages", +}, +/* Global Counters: Rx */ +[PCRF_METR_GLOB_CTR_Rx_RX_UNKNOWN] = { + .type = OGS_METRICS_METRIC_TYPE_COUNTER, + .name = "rx_rx_unknown", + .description = "Received Rx unknown messages", +}, +[PCRF_METR_GLOB_CTR_Rx_RX_AAR] = { + .type = OGS_METRICS_METRIC_TYPE_COUNTER, + .name = "rx_rx_aar", + .description = "Received Rx AAR messages", +}, +[PCRF_METR_GLOB_CTR_Rx_RX_AAR_ERROR] = { + .type = OGS_METRICS_METRIC_TYPE_COUNTER, + .name = "rx_rx_aar_error", + .description = "Received Rx AAR messages failed", +}, +[PCRF_METR_GLOB_CTR_Rx_RX_ASA] = { + .type = OGS_METRICS_METRIC_TYPE_COUNTER, + .name = "rx_rx_asa", + .description = "Received Rx ASA messages", +}, +[PCRF_METR_GLOB_CTR_Rx_RX_STR] = { + .type = OGS_METRICS_METRIC_TYPE_COUNTER, + .name = "rx_rx_asa_error", + .description = "Received Rx ASA messages failed", +}, +[PCRF_METR_GLOB_CTR_Rx_RX_STR_ERROR] = { + .type = OGS_METRICS_METRIC_TYPE_COUNTER, + .name = "rx_rx_str_error", + .description = "Received Rx STR messages failed", +}, +[PCRF_METR_GLOB_CTR_Rx_TX_AAA] = { + .type = OGS_METRICS_METRIC_TYPE_COUNTER, + .name = "rx_tx_aaa", + .description = "Transmitted Rx AAA messages", +}, +[PCRF_METR_GLOB_CTR_Rx_TX_SAR] = { + .type = OGS_METRICS_METRIC_TYPE_COUNTER, + .name = "rx_tx_sar", + .description = "Transmitted Rx SAR messages", +}, +[PCRF_METR_GLOB_CTR_Rx_TX_STA] = { + .type = OGS_METRICS_METRIC_TYPE_COUNTER, + .name = "rx_tx_sta", + .description = "Transmitted Rx STA messages", +}, /* Global Gauges: */ }; int pcrf_metrics_init_inst_global(void) diff --git a/src/pcrf/metrics.h b/src/pcrf/metrics.h index e437d5bdf..f6205456e 100644 --- a/src/pcrf/metrics.h +++ b/src/pcrf/metrics.h @@ -9,7 +9,24 @@ extern "C" { /* GLOBAL */ typedef enum pcrf_metric_type_global_s { - /* TODO: add PCRF specific metrics here. */ + PCRF_METR_GLOB_CTR_Gx_RX_UNKNOWN, + PCRF_METR_GLOB_CTR_Gx_RX_CCR, + PCRF_METR_GLOB_CTR_Gx_RX_CCR_ERROR, + PCRF_METR_GLOB_CTR_Gx_RX_RAA, + PCRF_METR_GLOB_CTR_Gx_TX_CCA, + PCRF_METR_GLOB_CTR_Gx_TX_RAR, + PCRF_METR_GLOB_CTR_Gx_TX_RAR_ERROR, + + PCRF_METR_GLOB_CTR_Rx_RX_UNKNOWN, + PCRF_METR_GLOB_CTR_Rx_RX_AAR, + PCRF_METR_GLOB_CTR_Rx_RX_AAR_ERROR, + PCRF_METR_GLOB_CTR_Rx_RX_ASA, + PCRF_METR_GLOB_CTR_Rx_RX_STR, + PCRF_METR_GLOB_CTR_Rx_RX_STR_ERROR, + PCRF_METR_GLOB_CTR_Rx_TX_AAA, + PCRF_METR_GLOB_CTR_Rx_TX_SAR, + PCRF_METR_GLOB_CTR_Rx_TX_STA, + _PCRF_METR_GLOB_MAX, } pcrf_metric_type_global_t; extern ogs_metrics_inst_t *pcrf_metrics_inst_global[_PCRF_METR_GLOB_MAX]; diff --git a/src/pcrf/pcrf-context.c b/src/pcrf/pcrf-context.c index 99fb209b8..3d70edaf6 100644 --- a/src/pcrf/pcrf-context.c +++ b/src/pcrf/pcrf-context.c @@ -19,6 +19,7 @@ #include "ogs-dbi.h" #include "pcrf-context.h" +#include "pcrf-fd-path.h" static pcrf_context_t self; static ogs_diam_config_t g_diam_conf; @@ -72,6 +73,7 @@ static int pcrf_context_prepare(void) { self.diam_config->cnf_port = DIAMETER_PORT; self.diam_config->cnf_port_tls = DIAMETER_SECURE_PORT; + self.diam_config->stats.priv_stats_size = sizeof(pcrf_diam_stats_t); return OGS_OK; } @@ -342,6 +344,9 @@ int pcrf_context_parse_config(void) ogs_error("parse_session_conf() failed"); return rv; } + } else if (!strcmp(pcrf_key, "diameter_stats_interval")) { + const char *v = ogs_yaml_iter_value(&pcrf_iter); + if (v) self.diam_config->stats.interval_sec = atoi(v); } else if (!strcmp(pcrf_key, "metrics")) { /* handle config in metrics library */ } else diff --git a/src/pcrf/pcrf-context.h b/src/pcrf/pcrf-context.h index 3ee31c36a..026297e43 100644 --- a/src/pcrf/pcrf-context.h +++ b/src/pcrf/pcrf-context.h @@ -24,6 +24,7 @@ #include "ogs-diameter-rx.h" #include "ogs-dbi.h" #include "ogs-app.h" +#include "metrics.h" #ifdef __cplusplus extern "C" { diff --git a/src/pcrf/pcrf-fd-path.c b/src/pcrf/pcrf-fd-path.c index 05010f1ee..a72d0820b 100644 --- a/src/pcrf/pcrf-fd-path.c +++ b/src/pcrf/pcrf-fd-path.c @@ -20,6 +20,41 @@ #include "pcrf-context.h" #include "pcrf-fd-path.h" +static pcrf_diam_stats_t prev_st; + +static void pcrf_diam_stats_update_cb(const ogs_diam_stats_t *stats, const void *priv_stats) +{ + const pcrf_diam_stats_t *st = (const pcrf_diam_stats_t *)priv_stats; + + ogs_debug("%s(): Update PCRF diameter metrics", __func__); + + #define METRIC_ADD(metric_name, field) \ + { \ + int diff = st->field - prev_st.field; \ + if (diff > 0) pcrf_metrics_inst_global_add(metric_name, diff); \ + } + + METRIC_ADD(PCRF_METR_GLOB_CTR_Gx_RX_UNKNOWN, gx.rx_unknown); + METRIC_ADD(PCRF_METR_GLOB_CTR_Gx_RX_CCR, gx.rx_ccr); + METRIC_ADD(PCRF_METR_GLOB_CTR_Gx_RX_CCR_ERROR, gx.rx_ccr_error); + METRIC_ADD(PCRF_METR_GLOB_CTR_Gx_RX_RAA, gx.rx_raa); + METRIC_ADD(PCRF_METR_GLOB_CTR_Gx_TX_CCA, gx.tx_cca); + METRIC_ADD(PCRF_METR_GLOB_CTR_Gx_TX_RAR, gx.tx_rar); + METRIC_ADD(PCRF_METR_GLOB_CTR_Gx_TX_RAR_ERROR, gx.tx_rar_error); + + METRIC_ADD(PCRF_METR_GLOB_CTR_Rx_RX_UNKNOWN, rx.rx_unknown); + METRIC_ADD(PCRF_METR_GLOB_CTR_Rx_RX_AAR, rx.rx_aar); + METRIC_ADD(PCRF_METR_GLOB_CTR_Rx_RX_AAR_ERROR, rx.rx_aar_error); + METRIC_ADD(PCRF_METR_GLOB_CTR_Rx_RX_ASA, rx.rx_asa); + METRIC_ADD(PCRF_METR_GLOB_CTR_Rx_RX_STR, rx.rx_str); + METRIC_ADD(PCRF_METR_GLOB_CTR_Rx_RX_STR_ERROR, rx.rx_str_error); + METRIC_ADD(PCRF_METR_GLOB_CTR_Rx_TX_AAA, rx.tx_aaa); + METRIC_ADD(PCRF_METR_GLOB_CTR_Rx_TX_SAR, rx.tx_sar); + METRIC_ADD(PCRF_METR_GLOB_CTR_Rx_TX_STA, rx.tx_sta); + + memcpy(&prev_st, st, sizeof(*st)); +} + int pcrf_fd_init(void) { int rv; @@ -33,6 +68,8 @@ int pcrf_fd_init(void) rv = pcrf_rx_init(); ogs_assert(rv == OGS_OK); + ogs_diam_stats_update_cb_register(pcrf_diam_stats_update_cb); + rv = ogs_diam_start(); ogs_assert(rv == 0); diff --git a/src/pcrf/pcrf-fd-path.h b/src/pcrf/pcrf-fd-path.h index 5a808da25..01d4a8849 100644 --- a/src/pcrf/pcrf-fd-path.h +++ b/src/pcrf/pcrf-fd-path.h @@ -27,6 +27,36 @@ extern "C" { struct sess_state; typedef struct ogs_diam_rx_message_s ogs_diam_rx_message_t; +typedef struct pcrf_diam_stats_gx_s { + unsigned long long rx_unknown; + unsigned long long rx_ccr; + unsigned long long rx_ccr_error; + unsigned long long rx_raa; + unsigned long long tx_cca; + unsigned long long tx_rar; + unsigned long long tx_rar_error; +} pcrf_diam_stats_gx_t; + +typedef struct pcrf_diam_stats_rx_s { + unsigned long long rx_unknown; + unsigned long long rx_aar; + unsigned long long rx_aar_error; + unsigned long long rx_asa; + unsigned long long rx_str; + unsigned long long rx_str_error; + unsigned long long tx_aaa; + unsigned long long tx_sar; + unsigned long long tx_sta; +} pcrf_diam_stats_rx_t; + +typedef struct pcrf_diam_stats_s { + pcrf_diam_stats_gx_t gx; + pcrf_diam_stats_rx_t rx; +} pcrf_diam_stats_t; + +#define PCRF_DIAM_PRIV_STATS_ADD(field, val) ((pcrf_diam_stats_t *)ogs_diam_stats_self()->priv_stats)->field += val +#define PCRF_DIAM_PRIV_STATS_INC(field) PCRF_DIAM_PRIV_STATS_ADD(field, 1) + int pcrf_fd_init(void); void pcrf_fd_final(void); diff --git a/src/pcrf/pcrf-gx-path.c b/src/pcrf/pcrf-gx-path.c index f6ddd1a1b..54b414a70 100644 --- a/src/pcrf/pcrf-gx-path.c +++ b/src/pcrf/pcrf-gx-path.c @@ -214,6 +214,10 @@ static int pcrf_gx_fb_cb(struct msg **msg, struct avp *avp, /* This CB should never be called */ ogs_warn("Unexpected message received!"); + OGS_DIAM_STATS_MTX( + PCRF_DIAM_PRIV_STATS_INC(gx.rx_unknown); + ) + return ENOTSUP; } @@ -621,9 +625,11 @@ static int pcrf_gx_ccr_cb( struct msg **msg, struct avp *avp, ogs_debug("Tx Credit-Control-Answer"); /* Add this value to the stats */ - ogs_assert(pthread_mutex_lock(&ogs_diam_stats_self()->stats_lock) == 0); - ogs_diam_stats_self()->stats.nb_echoed++; - ogs_assert(pthread_mutex_unlock(&ogs_diam_stats_self()->stats_lock) ==0); + OGS_DIAM_STATS_MTX( + OGS_DIAM_STATS_INC(nb_echoed); + PCRF_DIAM_PRIV_STATS_INC(gx.rx_ccr); + PCRF_DIAM_PRIV_STATS_INC(gx.tx_cca); + ) OGS_SESSION_DATA_FREE(&gx_message.session_data); @@ -662,6 +668,11 @@ out: ret = fd_msg_send(msg, NULL, NULL); ogs_assert(ret == 0); + OGS_DIAM_STATS_MTX( + PCRF_DIAM_PRIV_STATS_INC(gx.rx_ccr); + PCRF_DIAM_PRIV_STATS_INC(gx.rx_ccr_error); + ) + OGS_SESSION_DATA_FREE(&gx_message.session_data); return 0; @@ -1013,9 +1024,10 @@ int pcrf_gx_send_rar( ogs_assert(ret == 0); /* Increment the counter */ - ogs_assert(pthread_mutex_lock(&ogs_diam_stats_self()->stats_lock) == 0); - ogs_diam_stats_self()->stats.nb_sent++; - ogs_assert(pthread_mutex_unlock(&ogs_diam_stats_self()->stats_lock) == 0); + OGS_DIAM_STATS_MTX( + OGS_DIAM_STATS_INC(nb_sent); + PCRF_DIAM_PRIV_STATS_INC(gx.tx_rar); + ) /* Set no error */ rx_message->result_code = ER_DIAMETER_SUCCESS; @@ -1029,6 +1041,11 @@ out: ret = fd_sess_state_store(pcrf_gx_reg, session, &sess_data); ogs_assert(sess_data == NULL); + OGS_DIAM_STATS_MTX( + OGS_DIAM_STATS_INC(nb_sent); + PCRF_DIAM_PRIV_STATS_INC(gx.tx_rar_error); + ) + OGS_SESSION_DATA_FREE(&gx_message.session_data); return OGS_ERROR; @@ -1121,30 +1138,31 @@ static void pcrf_gx_raa_cb(void *data, struct msg **msg) } /* Free the message */ - ogs_assert(pthread_mutex_lock(&ogs_diam_stats_self()->stats_lock) == 0); - dur = ((ts.tv_sec - sess_data->ts.tv_sec) * 1000000) + - ((ts.tv_nsec - sess_data->ts.tv_nsec) / 1000); - if (ogs_diam_stats_self()->stats.nb_recv) { - /* Ponderate in the avg */ - ogs_diam_stats_self()->stats.avg = (ogs_diam_stats_self()->stats.avg * - ogs_diam_stats_self()->stats.nb_recv + dur) / - (ogs_diam_stats_self()->stats.nb_recv + 1); - /* Min, max */ - if (dur < ogs_diam_stats_self()->stats.shortest) + OGS_DIAM_STATS_MTX( + dur = ((ts.tv_sec - sess_data->ts.tv_sec) * 1000000) + + ((ts.tv_nsec - sess_data->ts.tv_nsec) / 1000); + if (ogs_diam_stats_self()->stats.nb_recv) { + /* Ponderate in the avg */ + ogs_diam_stats_self()->stats.avg = (ogs_diam_stats_self()->stats.avg * + ogs_diam_stats_self()->stats.nb_recv + dur) / + (ogs_diam_stats_self()->stats.nb_recv + 1); + /* Min, max */ + if (dur < ogs_diam_stats_self()->stats.shortest) + ogs_diam_stats_self()->stats.shortest = dur; + if (dur > ogs_diam_stats_self()->stats.longest) + ogs_diam_stats_self()->stats.longest = dur; + } else { ogs_diam_stats_self()->stats.shortest = dur; - if (dur > ogs_diam_stats_self()->stats.longest) ogs_diam_stats_self()->stats.longest = dur; - } else { - ogs_diam_stats_self()->stats.shortest = dur; - ogs_diam_stats_self()->stats.longest = dur; - ogs_diam_stats_self()->stats.avg = dur; - } - if (error) - ogs_diam_stats_self()->stats.nb_errs++; - else - ogs_diam_stats_self()->stats.nb_recv++; + ogs_diam_stats_self()->stats.avg = dur; + } + if (error) + ogs_diam_stats_self()->stats.nb_errs++; + else + ogs_diam_stats_self()->stats.nb_recv++; - ogs_assert(pthread_mutex_unlock(&ogs_diam_stats_self()->stats_lock) == 0); + PCRF_DIAM_PRIV_STATS_INC(gx.rx_raa); + ) /* Display how long it took */ if (ts.tv_nsec > sess_data->ts.tv_nsec) diff --git a/src/pcrf/pcrf-rx-path.c b/src/pcrf/pcrf-rx-path.c index 5b4559ba3..dd691ccf1 100644 --- a/src/pcrf/pcrf-rx-path.c +++ b/src/pcrf/pcrf-rx-path.c @@ -97,6 +97,10 @@ static int pcrf_rx_fb_cb(struct msg **msg, struct avp *avp, /* This CB should never be called */ ogs_warn("Unexpected message received!"); + OGS_DIAM_STATS_MTX( + PCRF_DIAM_PRIV_STATS_INC(rx.rx_unknown); + ) + return ENOTSUP; } @@ -413,9 +417,11 @@ static int pcrf_rx_aar_cb( struct msg **msg, struct avp *avp, ogs_debug("[PCRF] Tx AA-Answer"); /* Add this value to the stats */ - ogs_assert(pthread_mutex_lock(&ogs_diam_stats_self()->stats_lock) == 0); - ogs_diam_stats_self()->stats.nb_echoed++; - ogs_assert(pthread_mutex_unlock(&ogs_diam_stats_self()->stats_lock) == 0); + OGS_DIAM_STATS_MTX( + OGS_DIAM_STATS_INC(nb_echoed); + PCRF_DIAM_PRIV_STATS_INC(rx.rx_aar); + PCRF_DIAM_PRIV_STATS_INC(rx.tx_aaa); + ) ogs_ims_data_free(&rx_message.ims_data); @@ -442,6 +448,11 @@ out: ret = fd_msg_send(msg, NULL, NULL); ogs_assert(ret == 0); + OGS_DIAM_STATS_MTX( + PCRF_DIAM_PRIV_STATS_INC(rx.rx_aar); + PCRF_DIAM_PRIV_STATS_INC(rx.rx_aar_error); + ) + state_cleanup(sess_data, NULL, NULL); ogs_ims_data_free(&rx_message.ims_data); @@ -561,9 +572,10 @@ int pcrf_rx_send_asr(uint8_t *rx_sid, uint32_t abort_cause) ogs_assert(ret == 0); /* Increment the counter */ - ogs_assert(pthread_mutex_lock(&ogs_diam_stats_self()->stats_lock) == 0); - ogs_diam_stats_self()->stats.nb_sent++; - ogs_assert(pthread_mutex_unlock(&ogs_diam_stats_self()->stats_lock) == 0); + OGS_DIAM_STATS_MTX( + OGS_DIAM_STATS_INC(nb_sent); + PCRF_DIAM_PRIV_STATS_INC(rx.tx_sar); + ) return OGS_OK; } @@ -639,6 +651,10 @@ static void pcrf_rx_asa_cb(void *data, struct msg **msg) ogs_error("ERROR DIAMETER Result Code(%d)", result_code); } + OGS_DIAM_STATS_MTX( + PCRF_DIAM_PRIV_STATS_INC(rx.rx_asa); + ) + ret = fd_msg_free(*msg); ogs_assert(ret == 0); *msg = NULL; @@ -746,9 +762,11 @@ static int pcrf_rx_str_cb( struct msg **msg, struct avp *avp, ogs_debug("[PCRF] Tx Session-Termination-Answer"); /* Add this value to the stats */ - ogs_assert(pthread_mutex_lock(&ogs_diam_stats_self()->stats_lock) == 0); - ogs_diam_stats_self()->stats.nb_echoed++; - ogs_assert(pthread_mutex_unlock(&ogs_diam_stats_self()->stats_lock) == 0); + OGS_DIAM_STATS_MTX( + OGS_DIAM_STATS_INC(nb_echoed); + PCRF_DIAM_PRIV_STATS_INC(rx.rx_str); + PCRF_DIAM_PRIV_STATS_INC(rx.tx_sta); + ) state_cleanup(sess_data, NULL, NULL); ogs_ims_data_free(&rx_message.ims_data); @@ -778,6 +796,12 @@ out: ogs_assert(ret == 0); ogs_debug("[PCRF] Tx Session-Termination-Answer"); + OGS_DIAM_STATS_MTX( + PCRF_DIAM_PRIV_STATS_INC(rx.rx_str); + PCRF_DIAM_PRIV_STATS_INC(rx.rx_str_error); + PCRF_DIAM_PRIV_STATS_INC(rx.tx_sta); + ) + if (sess_data) state_cleanup(sess_data, NULL, NULL); ogs_ims_data_free(&rx_message.ims_data);