From 032c6e473cce0c7b7a799ff8c0750ce22ef49a4e Mon Sep 17 00:00:00 2001 From: attermann Date: Mon, 13 Apr 2020 12:11:21 -0600 Subject: [PATCH 1/2] Added cli command for parseable stats. Added support for "list jsonstats" CLI command that return the same stats as "list totals" but in easily parseble json format. --- daemon/cli.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/daemon/cli.c b/daemon/cli.c index 97e28b2e6..2123f3a47 100644 --- a/daemon/cli.c +++ b/daemon/cli.c @@ -88,6 +88,7 @@ static void cli_incoming_list_redisconnecttimeout(str *instr, struct streambuf * static void cli_incoming_list_rediscmdtimeout(str *instr, struct streambuf *replybuffer); static void cli_incoming_list_controltos(str *instr, struct streambuf *replybuffer); static void cli_incoming_list_interfaces(str *instr, struct streambuf *replybuffer); +static void cli_incoming_list_jsonstats(str *instr, struct streambuf *replybuffer); static const cli_handler_t cli_top_handlers[] = { { "list", cli_incoming_list }, @@ -139,6 +140,7 @@ static const cli_handler_t cli_list_handlers[] = { { "rediscmdtimeout", cli_incoming_list_rediscmdtimeout }, { "controltos", cli_incoming_list_controltos }, { "interfaces", cli_incoming_list_interfaces }, + { "jsonstats", cli_incoming_list_jsonstats }, { NULL, }, }; @@ -1392,6 +1394,97 @@ static void cli_incoming_list_interfaces(str *instr, struct streambuf *replybuff } } +static void cli_incoming_list_jsonstats(str *instr, struct streambuf *replybuffer) { + struct timeval avg, calls_dur_iv; + u_int64_t num_sessions, min_sess_iv, max_sess_iv; + struct request_time offer_iv, answer_iv, delete_iv; + struct requests_ps offers_ps, answers_ps, deletes_ps; + + mutex_lock(&rtpe_totalstats.total_average_lock); + avg = rtpe_totalstats.total_average_call_dur; + num_sessions = rtpe_totalstats.total_managed_sess; + mutex_unlock(&rtpe_totalstats.total_average_lock); + + streambuf_printf(replybuffer, "{\"totalstatistics\":{"); + streambuf_printf(replybuffer, "\"uptime\":%llu,", (unsigned long long)time(NULL)-rtpe_totalstats.started); + streambuf_printf(replybuffer, "\"managedsessions\":"UINT64F",", num_sessions); + streambuf_printf(replybuffer, "\"rejectedsessions\":"UINT64F",", atomic64_get(&rtpe_totalstats.total_rejected_sess)); + streambuf_printf(replybuffer, "\"timeoutsessions\":"UINT64F",",atomic64_get(&rtpe_totalstats.total_timeout_sess)); + streambuf_printf(replybuffer, "\"silenttimeoutsessions\":"UINT64F",",atomic64_get(&rtpe_totalstats.total_silent_timeout_sess)); + streambuf_printf(replybuffer, "\"finaltimeoutsessions\":"UINT64F",",atomic64_get(&rtpe_totalstats.total_final_timeout_sess)); + streambuf_printf(replybuffer, "\"offertimeoutsessions\":"UINT64F",",atomic64_get(&rtpe_totalstats.total_offer_timeout_sess)); + streambuf_printf(replybuffer, "\"regularterminatedsessions\":"UINT64F",",atomic64_get(&rtpe_totalstats.total_regular_term_sess)); + streambuf_printf(replybuffer, "\"forcedterminatedsessions\":"UINT64F",",atomic64_get(&rtpe_totalstats.total_forced_term_sess)); + streambuf_printf(replybuffer, "\"relayedpackets\":"UINT64F",",atomic64_get(&rtpe_totalstats.total_relayed_packets)); + streambuf_printf(replybuffer, "\"relayedpacketerrors\":"UINT64F",",atomic64_get(&rtpe_totalstats.total_relayed_errors)); + streambuf_printf(replybuffer, "\"zerowaystreams\":"UINT64F",", atomic64_get(&rtpe_totalstats.total_nopacket_relayed_sess)); + streambuf_printf(replybuffer, "\"onewaystreams\":"UINT64F",",atomic64_get(&rtpe_totalstats.total_oneway_stream_sess)); + streambuf_printf(replybuffer, "\"avgcallduration\":%ld.%06ld",avg.tv_sec,avg.tv_usec); + + mutex_lock(&rtpe_totalstats_lastinterval_lock); + calls_dur_iv = rtpe_totalstats_lastinterval.total_calls_duration_interval; + min_sess_iv = rtpe_totalstats_lastinterval.managed_sess_min; + max_sess_iv = rtpe_totalstats_lastinterval.managed_sess_max; + offer_iv = rtpe_totalstats_lastinterval.offer; + answer_iv = rtpe_totalstats_lastinterval.answer; + delete_iv = rtpe_totalstats_lastinterval.delete; + offers_ps = rtpe_totalstats_lastinterval.offers_ps; + answers_ps = rtpe_totalstats_lastinterval.answers_ps; + deletes_ps = rtpe_totalstats_lastinterval.deletes_ps; + mutex_unlock(&rtpe_totalstats_lastinterval_lock); + + streambuf_printf(replybuffer, "},\"intervalstatistics\":{"); + streambuf_printf(replybuffer, "\"totalcallsduration\":%ld.%06ld,",calls_dur_iv.tv_sec,calls_dur_iv.tv_usec); + streambuf_printf(replybuffer, "\"minmanagedsessions\":"UINT64F",", min_sess_iv); + streambuf_printf(replybuffer, "\"maxmanagedsessions\":"UINT64F",", max_sess_iv); + streambuf_printf(replybuffer, "\"minofferdelay\":%llu.%06llu,", (unsigned long long)offer_iv.time_min.tv_sec,(unsigned long long)offer_iv.time_min.tv_usec); + streambuf_printf(replybuffer, "\"maxofferdelay\":%llu.%06llu,", (unsigned long long)offer_iv.time_max.tv_sec,(unsigned long long)offer_iv.time_max.tv_usec); + streambuf_printf(replybuffer, "\"avgofferdelay\":%llu.%06llu,", (unsigned long long)offer_iv.time_avg.tv_sec,(unsigned long long)offer_iv.time_avg.tv_usec); + streambuf_printf(replybuffer, "\"minanswerdelay\":%llu.%06llu,", (unsigned long long)answer_iv.time_min.tv_sec,(unsigned long long)answer_iv.time_min.tv_usec); + streambuf_printf(replybuffer, "\"maxanswerdelay\":%llu.%06llu,", (unsigned long long)answer_iv.time_max.tv_sec,(unsigned long long)answer_iv.time_max.tv_usec); + streambuf_printf(replybuffer, "\"avganswerdelay\":%llu.%06llu,", (unsigned long long)answer_iv.time_avg.tv_sec,(unsigned long long)answer_iv.time_avg.tv_usec); + streambuf_printf(replybuffer, "\"mindeletedelay\":%llu.%06llu,", (unsigned long long)delete_iv.time_min.tv_sec,(unsigned long long)delete_iv.time_min.tv_usec); + streambuf_printf(replybuffer, "\"maxdeletedelay\":%llu.%06llu,", (unsigned long long)delete_iv.time_max.tv_sec,(unsigned long long)delete_iv.time_max.tv_usec); + streambuf_printf(replybuffer, "\"avgdeletedelay\":%llu.%06llu,", (unsigned long long)delete_iv.time_avg.tv_sec,(unsigned long long)delete_iv.time_avg.tv_usec); + + streambuf_printf(replybuffer, "\"minofferrequestrate\":%llu,", (unsigned long long)offers_ps.ps_min); + streambuf_printf(replybuffer, "\"maxofferrequestrate\":%llu,", (unsigned long long)offers_ps.ps_max); + streambuf_printf(replybuffer, "\"avgofferrequestrate\":%llu,", (unsigned long long)offers_ps.ps_avg); + streambuf_printf(replybuffer, "\"minanswerrequestrate\":%llu,", (unsigned long long)answers_ps.ps_min); + streambuf_printf(replybuffer, "\"maxanswerrequestrate\":%llu,", (unsigned long long)answers_ps.ps_max); + streambuf_printf(replybuffer, "\"avganswerrequestrate\":%llu,", (unsigned long long)answers_ps.ps_avg); + streambuf_printf(replybuffer, "\"mindeleterequestrate\":%llu,", (unsigned long long)deletes_ps.ps_min); + streambuf_printf(replybuffer, "\"maxdeleterequestrate\":%llu,", (unsigned long long)deletes_ps.ps_max); + streambuf_printf(replybuffer, "\"avgdeleterequestrate\":%llu", (unsigned long long)deletes_ps.ps_avg); + + streambuf_printf(replybuffer, "},\"controlstatistics\":["); + + mutex_lock(&rtpe_cngs_lock); + GList *list = g_hash_table_get_values(rtpe_cngs_hash); + + for (GList *l = list; l; l = l->next) { + if (l != list) + streambuf_printf(replybuffer, ","); + struct control_ng_stats* cur = l->data; + streambuf_printf(replybuffer, "{\"proxy\":\"%s\",", sockaddr_print_buf(&cur->proxy)); + streambuf_printf(replybuffer, "\"offercount\":%u,", cur->offer); + streambuf_printf(replybuffer, "\"answercount\":%u,", cur->answer); + streambuf_printf(replybuffer, "\"deletecount\":%u,", cur->delete); + streambuf_printf(replybuffer, "\"pingcount\":%u,", cur->ping); + streambuf_printf(replybuffer, "\"listcount\":%u,", cur->list); + streambuf_printf(replybuffer, "\"querycount\":%u,", cur->query); + streambuf_printf(replybuffer, "\"startreccount\":%u,", cur->start_recording); + streambuf_printf(replybuffer, "\"stopreccount\":%u,", cur->stop_recording); + streambuf_printf(replybuffer, "\"errorcount\":%u,", cur->errors); + streambuf_printf(replybuffer, "\"blkdtmfcount\":%u,", cur->block_dtmf); + streambuf_printf(replybuffer, "\"unblkdtmfcount\":%u}", cur->unblock_dtmf); + } + mutex_unlock(&rtpe_cngs_lock); + + streambuf_printf(replybuffer, "]}"); + g_list_free(list); +} + static void cli_incoming_list_controltos(str *instr, struct streambuf *replybuffer) { rwlock_lock_r(&rtpe_config.config_lock); streambuf_printf(replybuffer, "%d\n", rtpe_config.control_tos); From ccf1d4698aaa1fb6c8fdab6b44ba6dc884a5d934 Mon Sep 17 00:00:00 2001 From: attermann Date: Mon, 13 Apr 2020 14:13:19 -0600 Subject: [PATCH 2/2] Extended json control statistics Added missing control statistics as well as aggregate counts for all proxies. --- daemon/cli.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 7 deletions(-) diff --git a/daemon/cli.c b/daemon/cli.c index 2123f3a47..7067158df 100644 --- a/daemon/cli.c +++ b/daemon/cli.c @@ -1457,7 +1457,10 @@ static void cli_incoming_list_jsonstats(str *instr, struct streambuf *replybuffe streambuf_printf(replybuffer, "\"maxdeleterequestrate\":%llu,", (unsigned long long)deletes_ps.ps_max); streambuf_printf(replybuffer, "\"avgdeleterequestrate\":%llu", (unsigned long long)deletes_ps.ps_avg); - streambuf_printf(replybuffer, "},\"controlstatistics\":["); + streambuf_printf(replybuffer, "},\"controlstatistics\":{\"proxies\":["); + + struct control_ng_stats total; + memset (&total, 0, sizeof(total)); mutex_lock(&rtpe_cngs_lock); GList *list = g_hash_table_get_values(rtpe_cngs_hash); @@ -1466,22 +1469,65 @@ static void cli_incoming_list_jsonstats(str *instr, struct streambuf *replybuffe if (l != list) streambuf_printf(replybuffer, ","); struct control_ng_stats* cur = l->data; + total.ping += cur->ping; + total.offer += cur->offer; + total.answer += cur->answer; + total.delete += cur->delete; + total.query += cur->query; + total.list += cur->list; + total.start_recording += cur->start_recording; + total.stop_recording += cur->stop_recording; + total.start_forwarding += cur->start_forwarding; + total.stop_forwarding += cur->stop_forwarding; + total.block_dtmf += cur->block_dtmf; + total.unblock_dtmf += cur->unblock_dtmf; + total.block_media += cur->block_media; + total.unblock_media += cur->unblock_media; + total.play_media += cur->play_media; + total.stop_media += cur->stop_media; + total.play_dtmf += cur->play_dtmf; + total.errors += cur->errors; streambuf_printf(replybuffer, "{\"proxy\":\"%s\",", sockaddr_print_buf(&cur->proxy)); + streambuf_printf(replybuffer, "\"pingcount\":%u,", cur->ping); streambuf_printf(replybuffer, "\"offercount\":%u,", cur->offer); streambuf_printf(replybuffer, "\"answercount\":%u,", cur->answer); streambuf_printf(replybuffer, "\"deletecount\":%u,", cur->delete); - streambuf_printf(replybuffer, "\"pingcount\":%u,", cur->ping); - streambuf_printf(replybuffer, "\"listcount\":%u,", cur->list); streambuf_printf(replybuffer, "\"querycount\":%u,", cur->query); + streambuf_printf(replybuffer, "\"listcount\":%u,", cur->list); streambuf_printf(replybuffer, "\"startreccount\":%u,", cur->start_recording); streambuf_printf(replybuffer, "\"stopreccount\":%u,", cur->stop_recording); - streambuf_printf(replybuffer, "\"errorcount\":%u,", cur->errors); + streambuf_printf(replybuffer, "\"startfwdcount\":%u,", cur->start_forwarding); + streambuf_printf(replybuffer, "\"stopfwdcount\":%u,", cur->stop_forwarding); streambuf_printf(replybuffer, "\"blkdtmfcount\":%u,", cur->block_dtmf); - streambuf_printf(replybuffer, "\"unblkdtmfcount\":%u}", cur->unblock_dtmf); + streambuf_printf(replybuffer, "\"unblkdtmfcount\":%u,", cur->unblock_dtmf); + streambuf_printf(replybuffer, "\"blkmedia\":%u,", cur->block_media); + streambuf_printf(replybuffer, "\"unblkmedia\":%u,", cur->unblock_media); + streambuf_printf(replybuffer, "\"playmedia\":%u,", cur->play_media); + streambuf_printf(replybuffer, "\"stopmedia\":%u,", cur->stop_media); + streambuf_printf(replybuffer, "\"playdtmf\":%u,", cur->play_dtmf); + streambuf_printf(replybuffer, "\"errorcount\":%u}", cur->errors); } mutex_unlock(&rtpe_cngs_lock); - - streambuf_printf(replybuffer, "]}"); + streambuf_printf(replybuffer, "],\"totalpingcount\":%u,", total.ping); + streambuf_printf(replybuffer, "\"totaloffercount\":%u,", total.offer); + streambuf_printf(replybuffer, "\"totalanswercount\":%u,", total.answer); + streambuf_printf(replybuffer, "\"totaldeletecount\":%u,", total.delete); + streambuf_printf(replybuffer, "\"totalquerycount\":%u,", total.query); + streambuf_printf(replybuffer, "\"totallistcount\":%u,", total.list); + streambuf_printf(replybuffer, "\"totalstartreccount\":%u,", total.start_recording); + streambuf_printf(replybuffer, "\"totalstopreccount\":%u,", total.stop_recording); + streambuf_printf(replybuffer, "\"totalstartfwdcount\":%u,", total.start_forwarding); + streambuf_printf(replybuffer, "\"totalstopfwdcount\":%u,", total.stop_forwarding); + streambuf_printf(replybuffer, "\"totalblkdtmfcount\":%u,", total.block_dtmf); + streambuf_printf(replybuffer, "\"totalunblkdtmfcount\":%u,", total.unblock_dtmf); + streambuf_printf(replybuffer, "\"totalblkmedia\":%u,", total.block_media); + streambuf_printf(replybuffer, "\"totalunblkmedia\":%u,", total.unblock_media); + streambuf_printf(replybuffer, "\"totalplaymedia\":%u,", total.play_media); + streambuf_printf(replybuffer, "\"totalstopmedia\":%u,", total.stop_media); + streambuf_printf(replybuffer, "\"totalplaydtmf\":%u,", total.play_dtmf); + streambuf_printf(replybuffer, "\"totalerrorcount\":%u", total.errors); + + streambuf_printf(replybuffer, "}}"); g_list_free(list); }