From 5be0640fdd2f9cc71ba9a0808c05b09cdf35a53f Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 26 Apr 2010 04:14:57 -0400 Subject: [PATCH] mod_sofia: add failed call statistics to gateways (MODENDP-238) --- src/mod/endpoints/mod_sofia/mod_sofia.c | 117 +++++++++++++++++++++++- src/mod/endpoints/mod_sofia/mod_sofia.h | 2 + src/mod/endpoints/mod_sofia/sofia.c | 4 + 3 files changed, 120 insertions(+), 3 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 12a69d000d..a7276a30cd 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -392,7 +392,13 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session) switch_call_cause_t cause = switch_channel_get_cause(channel); int sip_cause = hangup_cause_to_sip(cause); const char *ps_cause = NULL, *use_my_cause; + const char *gateway_name = NULL; + sofia_gateway_t *gateway_ptr = NULL; + if ((gateway_name = switch_channel_get_variable(channel, "sip_gateway_name"))) { + gateway_ptr = sofia_reg_find_gateway(gateway_name); + } + switch_mutex_lock(tech_pvt->sofia_mutex); sofia_clear_flag(tech_pvt, TFLAG_RECOVERING); @@ -405,6 +411,18 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session) } else { tech_pvt->profile->ib_failed_calls++; } + + if (gateway_ptr) { + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { + gateway_ptr->ob_failed_calls++; + } else { + gateway_ptr->ib_failed_calls++; + } + } + } + + if (gateway_ptr) { + sofia_reg_release_gateway(gateway_ptr); } if (!((use_my_cause = switch_channel_get_variable(channel, "sip_ignore_remote_cause")) && switch_true(use_my_cause))) { @@ -2175,7 +2193,56 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t if (argc > 0) { if (argc == 1) { - stream->write_function(stream, "Invalid Syntax!\n"); + /* show summary of all gateways*/ + + uint32_t ib_failed = 0; + uint32_t ib = 0; + uint32_t ob_failed = 0; + uint32_t ob = 0; + + stream->write_function(stream, "%25s\t%32s\t%s\t%s\t%s\n", "Profile::Gateway-Name", " Data ", "State", "IB Calls(F/T)", "OB Calls(F/T)"); + stream->write_function(stream, "%s\n", line); + switch_mutex_lock(mod_sofia_globals.hash_mutex); + for (hi = switch_hash_first(NULL, mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) { + switch_hash_this(hi, &vvar, NULL, &val); + profile = (sofia_profile_t *) val; + if (sofia_test_pflag(profile, PFLAG_RUNNING)) { + + if (!strcmp(vvar, profile->name)) { /* not an alias */ + for (gp = profile->gateways; gp; gp = gp->next) { + char *pkey = switch_mprintf("%s::%s", profile->name, gp->name); + + switch_assert(gp->state < REG_STATE_LAST); + + c++; + ib_failed += gp->ib_failed_calls; + ib += gp->ib_calls; + ob_failed += gp->ob_failed_calls; + ob += gp->ob_calls; + + stream->write_function(stream, "%25s\t%32s\t%s\t%ld/%ld\t%ld/%ld", + pkey, gp->register_to, sofia_state_names[gp->state], + gp->ib_failed_calls, gp->ib_calls, gp->ob_failed_calls, gp->ob_calls); + + if (gp->state == REG_STATE_FAILED || gp->state == REG_STATE_TRYING) { + time_t now = switch_epoch_time_now(NULL); + if (gp->retry > now) { + stream->write_function(stream, " (retry: %ds)", gp->retry - now); + } else { + stream->write_function(stream, " (retry: NEVER)"); + } + } + stream->write_function(stream, "\n"); + } + } + } + } + switch_mutex_unlock(mod_sofia_globals.hash_mutex); + stream->write_function(stream, "%s\n", line); + stream->write_function(stream, "%d gateway%s: Inound(Failed/Total): %ld/%ld," + "Outbound(Failed/Total):%ld/%ld\n", c, c == 1 ? "" : "s", + ib_failed, ib, ob_failed, ob); + return SWITCH_STATUS_SUCCESS; } @@ -2205,6 +2272,8 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t stream->write_function(stream, "Status \t%s%s\n", status_names[gp->status], gp->pinging ? " (ping)" : ""); stream->write_function(stream, "CallsIN \t%d\n", gp->ib_calls); stream->write_function(stream, "CallsOUT\t%d\n", gp->ob_calls); + stream->write_function(stream, "FailedCallsIN\t%d\n", gp->ib_failed_calls); + stream->write_function(stream, "FailedCallsOUT\t%d\n", gp->ob_failed_calls); stream->write_function(stream, "%s\n", line); sofia_reg_release_gateway(gp); } else { @@ -2412,7 +2481,46 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl if (argc > 0) { if (argc == 1) { - stream->write_function(stream, "Invalid Syntax!\n"); + /* show summary of all gateways */ + + stream->write_function(stream, "%s\n", header); + stream->write_function(stream, "\n", header); + + switch_mutex_lock(mod_sofia_globals.hash_mutex); + for (hi = switch_hash_first(NULL, mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) { + switch_hash_this(hi, &vvar, NULL, &val); + profile = (sofia_profile_t *) val; + if (sofia_test_pflag(profile, PFLAG_RUNNING)) { + + if (!strcmp(vvar, profile->name)) { /* not an alias */ + for (gp = profile->gateways; gp; gp = gp->next) { + switch_assert(gp->state < REG_STATE_LAST); + + stream->write_function(stream, "\t\n"); + stream->write_function(stream, "\t\t%s\n", profile->name); + stream->write_function(stream, "\t\t%s\n", gp->register_to); + stream->write_function(stream, "\t\t%s\n", sofia_state_names[gp->state]); + stream->write_function(stream, "\t\t%ld\n", gp->ib_calls); + stream->write_function(stream, "\t\t%ld\n", gp->ob_calls); + stream->write_function(stream, "\t\t%ld\n", gp->ib_failed_calls); + stream->write_function(stream, "\t\t%ld\n", gp->ob_failed_calls); + + if (gp->state == REG_STATE_FAILED || gp->state == REG_STATE_TRYING) { + time_t now = switch_epoch_time_now(NULL); + if (gp->retry > now) { + stream->write_function(stream, "\t\t%ds\n", gp->retry - now); + } else { + stream->write_function(stream, "\t\tNEVER\n"); + } + } + stream->write_function(stream, "\t\n"); + } + } + } + } + switch_mutex_unlock(mod_sofia_globals.hash_mutex); + stream->write_function(stream, "\n"); + return SWITCH_STATUS_SUCCESS; } if (!strcasecmp(argv[0], "gateway")) { @@ -2440,7 +2548,8 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl stream->write_function(stream, " %s%s\n", status_names[gp->status], gp->pinging ? " (ping)" : ""); stream->write_function(stream, " %d\n", gp->ib_calls); stream->write_function(stream, " %d\n", gp->ob_calls); - + stream->write_function(stream, " %d\n", gp->ib_failed_calls); + stream->write_function(stream, " %d\n", gp->ob_failed_calls); stream->write_function(stream, " \n"); sofia_reg_release_gateway(gp); } else { @@ -3255,6 +3364,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session if (gateway_ptr->status != SOFIA_GATEWAY_UP) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Gateway is down!\n"); cause = SWITCH_CAUSE_NETWORK_OUT_OF_ORDER; + gateway_ptr->ob_failed_calls++; sofia_reg_release_gateway(gateway_ptr); gateway_ptr = NULL; goto error; @@ -3280,6 +3390,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session tech_pvt->transport = sofia_glue_str2transport(tp_param); if (tech_pvt->transport == SOFIA_TRANSPORT_UNKNOWN) { cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; + gateway_ptr->ob_failed_calls++; goto error; } } diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index e1b1e61d53..7fe7c5fe2b 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -402,6 +402,8 @@ struct sofia_gateway { switch_event_t *ob_vars; uint32_t ib_calls; uint32_t ob_calls; + uint32_t ib_failed_calls; + uint32_t ob_failed_calls; char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; int failures; struct sofia_gateway *next; diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 8338663e30..3d0dc95f21 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -1758,6 +1758,10 @@ static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag) gateway->ping_max = 0; gateway->ping_min = 0; gateway->ping_count = 0; + gateway->ib_calls = 0; + gateway->ob_calls = 0; + gateway->ib_failed_calls = 0; + gateway->ob_failed_calls = 0; if ((x_params = switch_xml_child(gateway_tag, "variables"))) { param = switch_xml_child(x_params, "variable");