Browse Source

ims_charging: added some stats

- billed_secs
- ccr_avg_response_time
- ccr_responses_time
- failed_final_ccrs
- failed_initial_ccrs
- failed_interim_ccr
- final_ccrs
- initial_ccrs
- interim_ccrs
- killed_calls
- successful_final_ccrs
- successful_initial_ccrs
- successful_interim_ccr
Carlos Ruiz Diaz 12 năm trước cách đây
mục cha
commit
1200242cad

+ 2 - 2
modules/ims_charging/dialog.c

@@ -112,7 +112,7 @@ void dlg_terminated(struct dlg_cell *dlg, int type, struct dlg_cb_params *_param
 			if ((ro_session = lookup_ro_session(dlg->h_entry, &dlg->callid, 0, 0))) {
 				ro_session_entry =
 						&(ro_session_table->entries[ro_session->h_entry]);
-				
+
 				//if the Ro session is not active we don't need to do anything. This prevents
 				//double processing for various dialog_terminated callback events.
 				//If however, the call was never answered, then we can continue as normal
@@ -137,7 +137,7 @@ void dlg_terminated(struct dlg_cell *dlg, int type, struct dlg_cb_params *_param
 				LM_DBG("Sending CCR STOP on Ro_Session [%p]\n", ro_session);
 				send_ccr_stop(ro_session);
 				ro_session->active = 0;
-
+				//ro_session->start_time;
 				ro_session_unlock(ro_session_table, ro_session_entry);
 				unref_ro_session(ro_session, 2+unref);
 			}

+ 20 - 20
modules/ims_charging/ims_ro.c

@@ -28,6 +28,7 @@
 #include "ccr.h"
 #include "config.h"
 #include "ro_session_hash.h"
+#include "stats.h"
 
 extern struct tm_binds tmb;
 extern struct cdp_binds cdpb;
@@ -628,6 +629,7 @@ void send_ccr_interim(struct ro_session* ro_session, unsigned int used, unsigned
 
     Ro_free_CCR(ro_ccr_data);
 
+    update_stat(interim_ccrs, 1);
     return;
 error:
 	LM_ERR("error trying to reserve interim credit\n");
@@ -649,6 +651,8 @@ static void resume_on_interim_ccr(int is_timeout, void *param, AAAMessage *cca,
 	struct interim_ccr *i_req	= (struct interim_ccr *) param;
 	Ro_CCA_t * ro_cca_data = NULL;
 
+    update_stat(ccr_responses_time, elapsed_msecs);
+
 	if (!i_req) {
 		LM_ERR("This is so wrong: ro session is NULL\n");
 		goto error;
@@ -683,6 +687,7 @@ static void resume_on_interim_ccr(int is_timeout, void *param, AAAMessage *cca,
 	Ro_free_CCA(ro_cca_data);
 	cdpb.AAAFreeMessage(&cca);
 
+	update_stat(successful_interim_ccrs, 1);
 	goto success;
 
 error:
@@ -715,6 +720,8 @@ void send_ccr_stop(struct ro_session *ro_session) {
         used = time(0) - ro_session->last_event_timestamp;
     }
 
+    update_stat(billed_secs, used);
+
     event_type_t *event_type;
     int node_role = 0;
 
@@ -806,6 +813,7 @@ void send_ccr_stop(struct ro_session *ro_session) {
 
     Ro_free_CCR(ro_ccr_data);
 
+    update_stat(final_ccrs, 1);
     return;
 
 error1:
@@ -825,6 +833,8 @@ error0:
 static void resume_on_termination_ccr(int is_timeout, void *param, AAAMessage *cca, long elapsed_msecs) {
     Ro_CCA_t *ro_cca_data = NULL;
 
+    update_stat(ccr_responses_time, elapsed_msecs);
+
     if (!cca) {
     	LM_ERR("Error in termination CCR.\n");
         return;
@@ -848,6 +858,8 @@ static void resume_on_termination_ccr(int is_timeout, void *param, AAAMessage *c
     Ro_free_CCA(ro_cca_data);
     cdpb.AAAFreeMessage(&cca);
 
+    update_stat(successful_final_ccrs, 1);
+
     return;
 
 error:
@@ -883,11 +895,6 @@ int Ro_Send_CCR(struct sip_msg *msg, str* direction, str* charge_type, str* unit
     int cc_event_number = 0;						//According to IOT tests this should start at 0
     int cc_event_type = RO_CC_START;
 
-    if (msg->first_line.type != SIP_REQUEST) {
-    	LM_ERR("Ro_CCR() called from SIP reply.");
-    	goto error;
-    }
-
     //make sure we can get the dialog! if not, we can't continue
 	struct dlg_cell* dlg = dlgb.get_dlg(msg);
 	if (!dlg) {
@@ -973,23 +980,11 @@ int Ro_Send_CCR(struct sip_msg *msg, str* direction, str* charge_type, str* unit
     LM_DBG("new CC Ro Session ID: [%.*s]\n", cc_acc_session->id.len, cc_acc_session->id.s);
 
     LM_DBG("Sending CCR Diameter message.\n");
-    /* send synchronously so we can respond to callplan (cfg file), so a decision can be made to process the invite */
     cdpb.AAASessionsUnlock(cc_acc_session->hash);
-
-    //AAAMessage *cca = cdpb.AAASendRecvMessageToPeer(ccr, &cfg.destination_host);
     cdpb.AAASendMessageToPeer(ccr, &cfg.destination_host, resume_on_initial_ccr, (void *) ssd);
 
     Ro_free_CCR(ro_ccr_data);
 
-/*    Ro_free_CCA(ro_cca_data);
-    if (cca){
-    	LM_DBG("Freeing CCA message\n");
-    	cdpb.AAAFreeMessage(&cca);
-    }
-
-    link_ro_session(new_session, 1);            //create extra ref for the fact that dialog has a handle in the callbacks
-    unref_ro_session(new_session, 1);
-*/
     //TODO: if the following fail, we should clean up the Ro session.......
     if (dlgb.register_dlgcb(dlg, DLGCB_RESPONSE_FWDED, dlg_reply, (void*)new_session ,NULL ) != 0) {
     	LM_CRIT("cannot register callback for dialog confirmation\n");
@@ -1002,6 +997,8 @@ int Ro_Send_CCR(struct sip_msg *msg, str* direction, str* charge_type, str* unit
     	goto error;
     }
 
+    update_stat(initial_ccrs, 1);
+
     return RO_RETURN_TRUE;
 
 error:
@@ -1013,8 +1010,7 @@ error:
 
     if (ssd)
     	pkg_free(ssd);
-/* Ro_free_CCA(ro_cca_data);
-    */
+
     LM_DBG("Trying to reserve credit on initial INVITE failed.\n");
     return RO_RETURN_ERROR;
 }
@@ -1025,6 +1021,8 @@ static void resume_on_initial_ccr(int is_timeout, void *param, AAAMessage *cca,
     struct session_setup_data *ssd = (struct session_setup_data *) param;
     int error_code	= RO_RETURN_ERROR;
 
+    update_stat(ccr_responses_time, elapsed_msecs);
+
     if (!cca) {
     	LM_ERR("Error reserving credit for CCA.\n");
     	error_code	= RO_RETURN_ERROR;
@@ -1090,6 +1088,8 @@ static void resume_on_initial_ccr(int is_timeout, void *param, AAAMessage *cca,
 
     tmb.t_continue(ssd->tindex, ssd->tlabel, ssd->action);
     shm_free(ssd);
+
+    update_stat(successful_initial_ccrs, 1);
     return;
 
 error1:
@@ -1153,7 +1153,7 @@ static int create_cca_return_code(int result) {
 
     avp_val.s.len = 2; */
 
-    rc = add_avp(AVP_NAME_STR, avp_name, avp_val);
+    rc = add_avp(AVP_NAME_STR/*|AVP_VAL_STR*/, avp_name, avp_val);
 
     if (rc < 0)
         LM_ERR("Couldn't create ["RO_AVP_CCA_RETURN_CODE"] AVP\n");

+ 45 - 11
modules/ims_charging/mod.c

@@ -12,6 +12,7 @@
 #include "../cdp/cdp_load.h"
 #include "../cdp_avp/mod_export.h"
 #include "../../parser/parse_to.h"
+#include "stats.h"
 #include "ro_timer.h"
 #include "ro_session_hash.h"
 #include "ims_ro.h"
@@ -50,6 +51,16 @@ int cdp_event_latency = 1; /*flag: report slow processing of CDP callback events
 int cdp_event_threshold = 500; /*time in ms above which we should report slow processing of CDP callback event - default 500ms*/
 int cdp_event_latency_loglevel = 0; /*log-level to use to report slow processing of CDP callback event - default ERROR*/
 
+stat_var *initial_ccrs;
+stat_var *interim_ccrs;
+stat_var *final_ccrs;
+stat_var *successful_initial_ccrs;
+stat_var *successful_interim_ccrs;
+stat_var *successful_final_ccrs;
+stat_var *ccr_responses_time;
+stat_var *billed_secs;
+stat_var *killed_calls;
+
 /** module functions */
 static int mod_init(void);
 static int mod_child_init(int);
@@ -88,17 +99,28 @@ static param_export_t params[] = {
 		{ 0, 0, 0 }
 };
 
-stat_export_t mod_stats[] = {
-		/*{"ccr_avg_response_time" ,  STAT_IS_FUNC, 	(stat_var**)get_avg_ccr_response_time	},*/
-		/*{"ccr_timeouts" ,  			0, 				(stat_var**)&stat_ccr_timeouts  		},*/
-		{ 0, 0, 0 }
+stat_export_t charging_stats[] = {
+    {"initial_ccrs", STAT_NO_RESET, &initial_ccrs},
+    {"interim_ccrs", STAT_NO_RESET, &interim_ccrs},
+    {"final_ccrs", STAT_NO_RESET, &final_ccrs},
+    {"successful_initial_ccrs", STAT_NO_RESET, &successful_initial_ccrs},
+    {"successful_interim_ccr", STAT_NO_RESET, &successful_interim_ccrs},
+    {"successful_final_ccrs", STAT_NO_RESET, &successful_final_ccrs},
+    {"failed_initial_ccrs", STAT_IS_FUNC, (stat_var**) get_failed_initial_ccrs},
+    {"failed_interim_ccr", STAT_IS_FUNC, (stat_var**) get_failed_interim_ccrs},
+    {"failed_final_ccrs", STAT_IS_FUNC, (stat_var**) get_failed_final_ccrs},
+    {"ccr_avg_response_time", STAT_IS_FUNC, (stat_var**) get_ccr_avg_response_time},
+    {"ccr_responses_time", STAT_NO_RESET, &ccr_responses_time},
+    {"billed_secs", STAT_NO_RESET, &billed_secs},
+    {"killed_calls", STAT_NO_RESET, &killed_calls},
+    {0, 0, 0}
 };
 
 /** module exports */
-struct module_exports exports = { "ims_charging", DEFAULT_DLFLAGS, /* dlopen flags */
+struct module_exports exports = { MOD_NAME, DEFAULT_DLFLAGS, /* dlopen flags */
 		cmds, 		/* Exported functions */
 		params, 	/* Exported params */
-		0, 			/* exported statistics */
+		charging_stats,	/* exported statistics */
 		0, 			/* exported MI functions */
 		0, 			/* exported pseudo-variables */
 		0, 			/* extra processes */
@@ -233,9 +255,20 @@ static int mod_init(void) {
 		goto error;
 	}
 
+	 /* register statistics */
+	if (register_module_stats(exports.name, charging_stats) != 0) {
+		LM_ERR("failed to register core statistics\n");
+		return -1;
+	}
+
+	/*if (register_stat(MOD_NAME, "ccr_responses_time", &ccr_responses_time, 0)) {
+		LM_ERR("failed to register core statistics\n");
+		return -1;
+	}*/
+
 	return 0;
 
-	error:
+error:
 	LM_ERR("Failed to initialise ims_qos module\n");
 	return RO_RETURN_FALSE;
 
@@ -275,9 +308,11 @@ static int w_ro_ccr(struct sip_msg *msg, str* route_name, str* direction, str* c
 			reservation_units,
 			route_name->len, route_name->s);
 
-//	if (msg->REQ_METHOD != METHOD_INVITE)
-//		return RO_RETURN_FALSE;
-//
+    if (msg->first_line.type != SIP_REQUEST) {
+    	LM_ERR("Ro_CCR() called from SIP reply.");
+    	return -1;
+    }
+
 	LM_DBG("Looking for route block [%.*s]\n", route_name->len, route_name->s);
 
 	int ri = route_get(&main_rt, route_name->s);
@@ -312,7 +347,6 @@ static int w_ro_ccr(struct sip_msg *msg, str* route_name, str* direction, str* c
 		return RO_RETURN_ERROR;
 	}
 
-	LM_DBG("index=%d label=%d\n", tindex, tlabel);
 	return Ro_Send_CCR(msg, direction, charge_type, unit_type, reservation_units, cfg_action, tindex, tlabel);
 }
 

+ 5 - 0
modules/ims_charging/ro_timer.c

@@ -14,6 +14,7 @@
 #include "ro_timer.h"
 #include "ro_session_hash.h"
 #include "ims_ro.h"
+#include "stats.h"
 
 extern int interim_request_credits;
 extern int ro_timer_buffer;
@@ -374,6 +375,8 @@ void ro_session_ontimeout(struct ro_tl *tl) {
 		used_secs = now - ro_session->last_event_timestamp;
 		call_time = now - ro_session->start_time;
 
+		update_stat(billed_secs, used_secs);
+
 		if (ro_session->callid.s != NULL
 				&& ro_session->dlg_h_entry	> 0
 				&& ro_session->dlg_h_id > 0
@@ -430,6 +433,8 @@ void ro_session_ontimeout(struct ro_tl *tl) {
 		dlgb.lookup_terminate_dlg(ro_session->dlg_h_entry, ro_session->dlg_h_id, NULL );
 	}
 
+	update_stat(killed_calls, 1);
+
 	ro_session_unlock(ro_session_table, ro_session_entry);
 	unref_ro_session(ro_session, 1); //unref from the initial timer that fired this event.
 

+ 45 - 0
modules/ims_charging/stats.c

@@ -0,0 +1,45 @@
+/*
+ * stats.c
+ *
+ *  Created on: Sep 30, 2013
+ *      Author: carlos
+ */
+
+#include "stats.h"
+
+unsigned long get_failed_initial_ccrs() {
+
+	unsigned long success_number = get_stat_val(successful_initial_ccrs),
+		 total_number	= get_stat_val(initial_ccrs);
+
+	return total_number - success_number;
+}
+
+unsigned long get_failed_interim_ccrs() {
+
+	unsigned long success_number = get_stat_val(successful_interim_ccrs),
+		 total_number	= get_stat_val(interim_ccrs);
+
+	return total_number - success_number;
+}
+
+unsigned long get_failed_final_ccrs() {
+
+	unsigned long success_number = get_stat_val(successful_final_ccrs),
+		 total_number	= get_stat_val(final_ccrs);
+
+	return total_number - success_number;
+}
+
+unsigned long get_ccr_avg_response_time() {
+
+	unsigned long responses_time = get_stat_val(ccr_responses_time),
+				  ccrs	= get_stat_val(initial_ccrs)
+				  	  	  + get_stat_val(interim_ccrs)
+				  	  	  + get_stat_val(final_ccrs);
+
+	if (responses_time == 0 || ccrs == 0)
+		return 0;
+
+	return responses_time / ccrs;
+}

+ 28 - 0
modules/ims_charging/stats.h

@@ -0,0 +1,28 @@
+/*
+ * stats.h
+ *
+ *  Created on: Sep 30, 2013
+ *      Author: carlos
+ */
+
+#ifndef STATS_H_
+#define STATS_H_
+
+#include "../../lib/kcore/statistics.h"
+
+extern stat_var *initial_ccrs;
+extern stat_var *interim_ccrs;
+extern stat_var *final_ccrs;
+extern stat_var *successful_initial_ccrs;
+extern stat_var *successful_interim_ccrs;
+extern stat_var *successful_final_ccrs;
+extern stat_var *ccr_responses_time;
+extern stat_var *billed_secs;
+extern stat_var *killed_calls;
+
+unsigned long get_failed_initial_ccrs();
+unsigned long get_failed_interim_ccrs();
+unsigned long get_failed_final_ccrs();
+unsigned long get_ccr_avg_response_time();
+
+#endif /* STATS_H_ */