Browse Source

TT#82410 unify stats gathering functions

Change-Id: I5be2f728a40d69e76b7fcdd04b9d7cb62e34665e
changes/95/40295/16
Richard Fuchs 6 years ago
parent
commit
ac765d1b54
3 changed files with 350 additions and 241 deletions
  1. +27
    -241
      daemon/cli.c
  2. +310
    -0
      daemon/statistics.c
  3. +13
    -0
      include/statistics.h

+ 27
- 241
daemon/cli.c View File

@ -400,104 +400,21 @@ static void cli_incoming_list_counters(str *instr, struct streambuf *replybuffer
}
static void cli_incoming_list_totals(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, "\nTotal statistics (does not include current running sessions):\n\n");
streambuf_printf(replybuffer, " Uptime of rtpengine :%llu seconds\n", (unsigned long long)time(NULL)-rtpe_totalstats.started);
streambuf_printf(replybuffer, " Total managed sessions :"UINT64F"\n", num_sessions);
streambuf_printf(replybuffer, " Total rejected sessions :"UINT64F"\n", atomic64_get(&rtpe_totalstats.total_rejected_sess));
streambuf_printf(replybuffer, " Total timed-out sessions via TIMEOUT :"UINT64F"\n",atomic64_get(&rtpe_totalstats.total_timeout_sess));
streambuf_printf(replybuffer, " Total timed-out sessions via SILENT_TIMEOUT :"UINT64F"\n",atomic64_get(&rtpe_totalstats.total_silent_timeout_sess));
streambuf_printf(replybuffer, " Total timed-out sessions via FINAL_TIMEOUT :"UINT64F"\n",atomic64_get(&rtpe_totalstats.total_final_timeout_sess));
streambuf_printf(replybuffer, " Total timed-out sessions via OFFER_TIMEOUT :"UINT64F"\n",atomic64_get(&rtpe_totalstats.total_offer_timeout_sess));
streambuf_printf(replybuffer, " Total regular terminated sessions :"UINT64F"\n",atomic64_get(&rtpe_totalstats.total_regular_term_sess));
streambuf_printf(replybuffer, " Total forced terminated sessions :"UINT64F"\n",atomic64_get(&rtpe_totalstats.total_forced_term_sess));
streambuf_printf(replybuffer, " Total relayed packets :"UINT64F"\n",atomic64_get(&rtpe_totalstats.total_relayed_packets));
streambuf_printf(replybuffer, " Total relayed packet errors :"UINT64F"\n",atomic64_get(&rtpe_totalstats.total_relayed_errors));
streambuf_printf(replybuffer, " Total number of streams with no relayed packets :"UINT64F"\n", atomic64_get(&rtpe_totalstats.total_nopacket_relayed_sess));
streambuf_printf(replybuffer, " Total number of 1-way streams :"UINT64F"\n",atomic64_get(&rtpe_totalstats.total_oneway_stream_sess));
streambuf_printf(replybuffer, " Average call duration :%ld.%06ld\n\n",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, "\nGraphite interval statistics (last reported values to graphite):\n");
streambuf_printf(replybuffer, " Total calls duration :%ld.%06ld\n\n",calls_dur_iv.tv_sec,calls_dur_iv.tv_usec);
streambuf_printf(replybuffer, " Min managed sessions :"UINT64F"\n", min_sess_iv);
streambuf_printf(replybuffer, " Max managed sessions :"UINT64F"\n", max_sess_iv);
streambuf_printf(replybuffer, " Min/Max/Avg offer processing delay :%llu.%06llu/%llu.%06llu/%llu.%06llu sec\n",
(unsigned long long)offer_iv.time_min.tv_sec,(unsigned long long)offer_iv.time_min.tv_usec,
(unsigned long long)offer_iv.time_max.tv_sec,(unsigned long long)offer_iv.time_max.tv_usec,
(unsigned long long)offer_iv.time_avg.tv_sec,(unsigned long long)offer_iv.time_avg.tv_usec);
streambuf_printf(replybuffer, " Min/Max/Avg answer processing delay :%llu.%06llu/%llu.%06llu/%llu.%06llu sec\n",
(unsigned long long)answer_iv.time_min.tv_sec,(unsigned long long)answer_iv.time_min.tv_usec,
(unsigned long long)answer_iv.time_max.tv_sec,(unsigned long long)answer_iv.time_max.tv_usec,
(unsigned long long)answer_iv.time_avg.tv_sec,(unsigned long long)answer_iv.time_avg.tv_usec);
streambuf_printf(replybuffer, " Min/Max/Avg delete processing delay :%llu.%06llu/%llu.%06llu/%llu.%06llu sec\n",
(unsigned long long)delete_iv.time_min.tv_sec,(unsigned long long)delete_iv.time_min.tv_usec,
(unsigned long long)delete_iv.time_max.tv_sec,(unsigned long long)delete_iv.time_max.tv_usec,
(unsigned long long)delete_iv.time_avg.tv_sec,(unsigned long long)delete_iv.time_avg.tv_usec);
streambuf_printf(replybuffer, " Min/Max/Avg offer requests per second :%llu/%llu/%llu per sec\n",
(unsigned long long)offers_ps.ps_min,
(unsigned long long)offers_ps.ps_max,
(unsigned long long)offers_ps.ps_avg);
streambuf_printf(replybuffer, " Min/Max/Avg answer requests per second :%llu/%llu/%llu per sec\n", (unsigned long long)answers_ps.ps_min,
(unsigned long long)answers_ps.ps_max,
(unsigned long long)answers_ps.ps_avg);
streambuf_printf(replybuffer, " Min/Max/Avg delete requests per second :%llu/%llu/%llu per sec\n",
(unsigned long long)deletes_ps.ps_min,
(unsigned long long)deletes_ps.ps_max,
(unsigned long long)deletes_ps.ps_avg);
streambuf_printf(replybuffer, "\n\n");
streambuf_printf(replybuffer, "Control statistics:\n\n");
streambuf_printf(replybuffer, " %20s | %10s | %10s | %10s | %10s | %10s | %10s | %10s | %10s | %10s | %10s | %10s \n",
"Proxy", "Offer", "Answer", "Delete", "Ping", "List", "Query", "StartRec", "StopRec", "Errors", "BlkDTMF", "UnblkDTMF");
mutex_lock(&rtpe_cngs_lock);
GList *list = g_hash_table_get_values(rtpe_cngs_hash);
if (!list) {
streambuf_printf(replybuffer, "\n No proxies have yet tried to send data.");
}
for (GList *l = list; l; l = l->next) {
struct control_ng_stats* cur = l->data;
streambuf_printf(replybuffer, " %20s | %10u | %10u | %10u | %10u | %10u | %10u | %10u | %10u | %10u | %10u | %10u \n",
sockaddr_print_buf(&cur->proxy),
cur->offer,
cur->answer,
cur->delete,
cur->ping,
cur->list,
cur->query,
cur->start_recording,
cur->stop_recording,
cur->errors,
cur->block_dtmf,
cur->unblock_dtmf);
AUTO_CLEANUP_INIT(GQueue *metrics, statistics_free_metrics, statistics_gather_metrics());
for (GList *l = metrics->head; l; l = l->next) {
struct stats_metric *m = l->data;
if (!m->descr)
continue;
if (m->value_long) {
if (!strcmp(m->descr, ""))
streambuf_printf(replybuffer, "%s\n", m->value_long);
else
streambuf_printf(replybuffer, " %-48s:%s\n", m->descr, m->value_long);
}
else
streambuf_printf(replybuffer, "%s\n", m->descr);
}
streambuf_printf(replybuffer, "\n\n");
mutex_unlock(&rtpe_cngs_lock);
g_list_free(list);
}
static void cli_incoming_list_numsessions(str *instr, struct streambuf *replybuffer) {
@ -1398,154 +1315,23 @@ static void cli_incoming_list_interfaces(str *instr, struct streambuf *replybuff
}
static void cli_incoming_list_jsonstats(str *instr, struct streambuf *replybuffer) {
u_int64_t cur_sessions, num_sessions, min_sess_iv, max_sess_iv;
struct timeval avg, calls_dur_iv;
struct request_time offer_iv, answer_iv, delete_iv;
struct requests_ps offers_ps, answers_ps, deletes_ps;
AUTO_CLEANUP_INIT(GQueue *metrics, statistics_free_metrics, statistics_gather_metrics());
streambuf_printf(replybuffer, "{\"currentstatistics\":{");
rwlock_lock_r(&rtpe_callhash_lock);
cur_sessions = g_hash_table_size(rtpe_callhash);
rwlock_unlock_r(&rtpe_callhash_lock);
for (GList *l = metrics->head; l; l = l->next) {
struct stats_metric *m = l->data;
if (!m->label)
continue;
streambuf_printf(replybuffer, "\"sessionsown\":"UINT64F",", cur_sessions - atomic64_get(&rtpe_stats.foreign_sessions));
streambuf_printf(replybuffer, "\"sessionsforeign\":"UINT64F",", atomic64_get(&rtpe_stats.foreign_sessions));
streambuf_printf(replybuffer, "\"sessionstotal\":%i,", cur_sessions);
streambuf_printf(replybuffer, "\"packetrate\":%"PRIu64",", atomic64_get(&rtpe_stats.packets));
streambuf_printf(replybuffer, "\"byterate\":%"PRIu64",", atomic64_get(&rtpe_stats.bytes));
streambuf_printf(replybuffer, "\"errorrate\":%"PRIu64"", atomic64_get(&rtpe_stats.errors));
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\":{\"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);
for (GList *l = list; l; l = l->next) {
if (l != list)
if (m->is_follow_up)
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, "\"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, "\"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, "\"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);
if (m->value_short)
streambuf_printf(replybuffer, "\"%s\":%s", m->label, m->value_short);
else if (m->is_bracket)
streambuf_printf(replybuffer, "%s", m->label);
else
streambuf_printf(replybuffer, "\"%s\":", m->label);
}
mutex_unlock(&rtpe_cngs_lock);
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);
}
static void cli_incoming_list_transcoders(str *instr, struct streambuf *replybuffer) {


+ 310
- 0
daemon/statistics.c View File

@ -2,6 +2,7 @@
#include "statistics.h"
#include "graphite.h"
#include "main.h"
#include "control_ng.h"
struct totalstats rtpe_totalstats;
@ -227,6 +228,315 @@ void statistics_update_oneway(struct call* c) {
}
#pragma GCC diagnostic ignored "-Wformat-zero-length"
#define SM_PUSH(ret, m) \
do { \
if (!m->is_bracket && ret->tail) { \
struct stats_metric *last = ret->tail->data; \
if (!last->is_bracket || last->is_close_bracket) \
m->is_follow_up = 1; \
} \
g_queue_push_tail(ret, m); \
} while (0)
#define METRIC(lb, dsc, fmt1, fmt2, ...) \
do { \
struct stats_metric *m = g_slice_alloc0(sizeof(*m)); \
m->label = g_strdup(lb); \
m->descr = g_strdup(dsc); \
if (fmt1) \
m->value_short = g_strdup_printf(fmt1, ## __VA_ARGS__); \
if (fmt2) \
m->value_long = g_strdup_printf(fmt2, ## __VA_ARGS__); \
SM_PUSH(ret, m); \
} while (0)
#define METRICl(dsc, fmt2, ...) \
do { \
struct stats_metric *m = g_slice_alloc0(sizeof(*m)); \
m->descr = g_strdup(dsc); \
m->value_long = g_strdup_printf(fmt2, ## __VA_ARGS__); \
SM_PUSH(ret, m); \
} while (0)
#define METRICs(lb, fmt1, ...) \
do { \
struct stats_metric *m = g_slice_alloc0(sizeof(*m)); \
m->label = g_strdup(lb); \
m->value_short = g_strdup_printf(fmt1, ## __VA_ARGS__); \
SM_PUSH(ret, m); \
} while (0)
#define HEADER(fmt1, fmt2, ...) \
do { \
struct stats_metric *m = g_slice_alloc0(sizeof(*m)); \
if (fmt1) \
m->label = g_strdup_printf(fmt1, ## __VA_ARGS__); \
if (fmt2) \
m->descr = g_strdup_printf(fmt2, ## __VA_ARGS__); \
if (m->label && ( \
m->label[0] == '[' \
|| m->label[0] == '{' \
|| m->label[0] == '}' \
|| m->label[0] == ']') \
&& m->label[1] == 0) { \
m->is_bracket = 1; \
if (m->label[0] == '}' || m->label[0] == ']') \
m->is_close_bracket = 1; \
} \
SM_PUSH(ret, m); \
} while (0)
#define HEADERl(fmt2, ...) \
do { \
struct stats_metric *m = g_slice_alloc0(sizeof(*m)); \
m->descr = g_strdup_printf(fmt2, ## __VA_ARGS__); \
SM_PUSH(ret, m); \
} while (0)
GQueue *statistics_gather_metrics(void) {
GQueue *ret = g_queue_new();
struct timeval avg, calls_dur_iv;
u_int64_t cur_sessions, 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);
HEADER("{", "");
METRIC("currentstatistics", "Statistics over currently running sessions:", NULL, NULL);
HEADER("{", "");
rwlock_lock_r(&rtpe_callhash_lock);
cur_sessions = g_hash_table_size(rtpe_callhash);
rwlock_unlock_r(&rtpe_callhash_lock);
METRIC("sessionsown", "Owned sessions", UINT64F, UINT64F, cur_sessions - atomic64_get(&rtpe_stats.foreign_sessions));
METRIC("sessionsforeign", "Foreign sessions", UINT64F, UINT64F, atomic64_get(&rtpe_stats.foreign_sessions));
METRIC("sessionstotal", "Total sessions", UINT64F, UINT64F, cur_sessions);
METRIC("transcodedmedia", "Transcoded media", UINT64F, UINT64F, atomic64_get(&rtpe_stats.transcoded_media));
METRIC("packetrate", "Packets per second", UINT64F, UINT64F, atomic64_get(&rtpe_stats.packets));
METRIC("byterate", "Bytes per second", UINT64F, UINT64F, atomic64_get(&rtpe_stats.bytes));
METRIC("errorrate", "Errors per second", UINT64F, UINT64F, atomic64_get(&rtpe_stats.errors));
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);
HEADER("}", "");
METRIC("totalstatistics", "Total statistics (does not include current running sessions):", NULL, NULL);
HEADER("{", "");
METRIC("uptime", "Uptime of rtpengine", "%llu", "%llu seconds", (unsigned long long) time(NULL)-rtpe_totalstats.started);
METRIC("managedsessions", "Total managed sessions", UINT64F, UINT64F, num_sessions);
METRIC("rejectedsessions", "Total rejected sessions", UINT64F, UINT64F, atomic64_get(&rtpe_totalstats.total_rejected_sess));
METRIC("timeoutsessions", "Total timed-out sessions via TIMEOUT", UINT64F, UINT64F, atomic64_get(&rtpe_totalstats.total_timeout_sess));
METRIC("silenttimeoutsessions", "Total timed-out sessions via SILENT_TIMEOUT", UINT64F, UINT64F,atomic64_get(&rtpe_totalstats.total_silent_timeout_sess));
METRIC("finaltimeoutsessions", "Total timed-out sessions via FINAL_TIMEOUT", UINT64F, UINT64F,atomic64_get(&rtpe_totalstats.total_final_timeout_sess));
METRIC("offertimeoutsessions", "Total timed-out sessions via OFFER_TIMEOUT", UINT64F, UINT64F,atomic64_get(&rtpe_totalstats.total_offer_timeout_sess));
METRIC("regularterminatedsessions", "Total regular terminated sessions", UINT64F, UINT64F, atomic64_get(&rtpe_totalstats.total_regular_term_sess));
METRIC("forcedterminatedsessions", "Total forced terminated sessions", UINT64F, UINT64F, atomic64_get(&rtpe_totalstats.total_forced_term_sess));
METRIC("relayedpackets", "Total relayed packets", UINT64F, UINT64F, atomic64_get(&rtpe_totalstats.total_relayed_packets));
METRIC("relayedpacketerrors", "Total relayed packet errors", UINT64F, UINT64F, atomic64_get(&rtpe_totalstats.total_relayed_errors));
METRIC("zerowaystreams", "Total number of streams with no relayed packets", UINT64F, UINT64F, atomic64_get(&rtpe_totalstats.total_nopacket_relayed_sess));
METRIC("onewaystreams", "Total number of 1-way streams", UINT64F, UINT64F,atomic64_get(&rtpe_totalstats.total_oneway_stream_sess));
METRIC("avgcallduration", "Average call duration", "%ld.%06ld", "%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);
HEADER(NULL, "");
HEADER("}", "");
METRIC("intervalstatistics", "Graphite interval statistics (last reported values to graphite):", NULL, NULL);
HEADER("{", NULL);
METRIC("totalcallsduration", "Total calls duration", "%ld.%06ld", "%ld.%06ld", calls_dur_iv.tv_sec,calls_dur_iv.tv_usec);
HEADER(NULL, "");
METRIC("minmanagedsessions", "Min managed sessions", UINT64F, UINT64F, min_sess_iv);
METRIC("maxmanagedsessions", "Max managed sessions", UINT64F, UINT64F, max_sess_iv);
METRICl("Min/Max/Avg offer processing delay", "%llu.%06llu/%llu.%06llu/%llu.%06llu sec",
(unsigned long long)offer_iv.time_min.tv_sec,(unsigned long long)offer_iv.time_min.tv_usec,
(unsigned long long)offer_iv.time_max.tv_sec,(unsigned long long)offer_iv.time_max.tv_usec,
(unsigned long long)offer_iv.time_avg.tv_sec,(unsigned long long)offer_iv.time_avg.tv_usec);
METRICs("minofferdelay", "%llu.%06llu", (unsigned long long)offer_iv.time_min.tv_sec,(unsigned long long)offer_iv.time_min.tv_usec);
METRICs("maxofferdelay", "%llu.%06llu", (unsigned long long)offer_iv.time_max.tv_sec,(unsigned long long)offer_iv.time_max.tv_usec);
METRICs("avgofferdelay", "%llu.%06llu", (unsigned long long)offer_iv.time_avg.tv_sec,(unsigned long long)offer_iv.time_avg.tv_usec);
METRICl("Min/Max/Avg answer processing delay", "%llu.%06llu/%llu.%06llu/%llu.%06llu sec",
(unsigned long long)answer_iv.time_min.tv_sec,(unsigned long long)answer_iv.time_min.tv_usec,
(unsigned long long)answer_iv.time_max.tv_sec,(unsigned long long)answer_iv.time_max.tv_usec,
(unsigned long long)answer_iv.time_avg.tv_sec,(unsigned long long)answer_iv.time_avg.tv_usec);
METRICs("minanswerdelay", "%llu.%06llu", (unsigned long long)answer_iv.time_min.tv_sec,(unsigned long long)answer_iv.time_min.tv_usec);
METRICs("maxanswerdelay", "%llu.%06llu", (unsigned long long)answer_iv.time_max.tv_sec,(unsigned long long)answer_iv.time_max.tv_usec);
METRICs("avganswerdelay", "%llu.%06llu", (unsigned long long)answer_iv.time_avg.tv_sec,(unsigned long long)answer_iv.time_avg.tv_usec);
METRICl("Min/Max/Avg delete processing delay", "%llu.%06llu/%llu.%06llu/%llu.%06llu sec",
(unsigned long long)delete_iv.time_min.tv_sec,(unsigned long long)delete_iv.time_min.tv_usec,
(unsigned long long)delete_iv.time_max.tv_sec,(unsigned long long)delete_iv.time_max.tv_usec,
(unsigned long long)delete_iv.time_avg.tv_sec,(unsigned long long)delete_iv.time_avg.tv_usec);
METRICs("mindeletedelay", "%llu.%06llu", (unsigned long long)delete_iv.time_min.tv_sec,(unsigned long long)delete_iv.time_min.tv_usec);
METRICs("maxdeletedelay", "%llu.%06llu", (unsigned long long)delete_iv.time_max.tv_sec,(unsigned long long)delete_iv.time_max.tv_usec);
METRICs("avgdeletedelay", "%llu.%06llu", (unsigned long long)delete_iv.time_avg.tv_sec,(unsigned long long)delete_iv.time_avg.tv_usec);
METRICl("Min/Max/Avg offer requests per second", "%llu/%llu/%llu per sec",
(unsigned long long)offers_ps.ps_min,
(unsigned long long)offers_ps.ps_max,
(unsigned long long)offers_ps.ps_avg);
METRICs("minofferrequestrate", "%llu", (unsigned long long)offers_ps.ps_min);
METRICs("maxofferrequestrate", "%llu", (unsigned long long)offers_ps.ps_max);
METRICs("avgofferrequestrate", "%llu", (unsigned long long)offers_ps.ps_avg);
METRICl("Min/Max/Avg answer requests per second", "%llu/%llu/%llu per sec",
(unsigned long long)answers_ps.ps_min,
(unsigned long long)answers_ps.ps_max,
(unsigned long long)answers_ps.ps_avg);
METRICs("minanswerrequestrate", "%llu", (unsigned long long)answers_ps.ps_min);
METRICs("maxanswerrequestrate", "%llu", (unsigned long long)answers_ps.ps_max);
METRICs("avganswerrequestrate", "%llu", (unsigned long long)answers_ps.ps_avg);
METRICl("Min/Max/Avg delete requests per second", "%llu/%llu/%llu per sec",
(unsigned long long)deletes_ps.ps_min,
(unsigned long long)deletes_ps.ps_max,
(unsigned long long)deletes_ps.ps_avg);
METRICs("mindeleterequestrate", "%llu", (unsigned long long)deletes_ps.ps_min);
METRICs("maxdeleterequestrate", "%llu", (unsigned long long)deletes_ps.ps_max);
METRICs("avgdeleterequestrate", "%llu", (unsigned long long)deletes_ps.ps_avg);
HEADER(NULL, "");
HEADER("}", "");
METRIC("controlstatistics", "Control statistics:", NULL, NULL);
HEADER("{", "");
HEADER("proxies", NULL);
HEADER("[", NULL);
HEADERl(" %20s | %10s | %10s | %10s | %10s | %10s | %10s | %10s | %10s | %10s | %10s | %10s ",
"Proxy", "Offer", "Answer", "Delete", "Ping", "List", "Query", "StartRec", "StopRec", "Errors", "BlkDTMF", "UnblkDTMF");
struct control_ng_stats total = {0,};
mutex_lock(&rtpe_cngs_lock);
GList *list = g_hash_table_get_values(rtpe_cngs_hash);
if (!list) {
//streambuf_printf(replybuffer, "\n No proxies have yet tried to send data.");
}
for (GList *l = list; l; l = l->next) {
struct control_ng_stats* cur = l->data;
METRICl("", " %20s | %10u | %10u | %10u | %10u | %10u | %10u | %10u | %10u | %10u | %10u | %10u",
sockaddr_print_buf(&cur->proxy),
cur->offer,
cur->answer,
cur->delete,
cur->ping,
cur->list,
cur->query,
cur->start_recording,
cur->stop_recording,
cur->errors,
cur->block_dtmf,
cur->unblock_dtmf);
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;
HEADER("{", NULL);
METRICs("proxy", "\"%s\"", sockaddr_print_buf(&cur->proxy));
METRICs("pingcount", "%u", cur->ping);
METRICs("offercount", "%u", cur->offer);
METRICs("answercount", "%u", cur->answer);
METRICs("deletecount", "%u", cur->delete);
METRICs("querycount", "%u", cur->query);
METRICs("listcount", "%u", cur->list);
METRICs("startreccount", "%u", cur->start_recording);
METRICs("stopreccount", "%u", cur->stop_recording);
METRICs("startfwdcount", "%u", cur->start_forwarding);
METRICs("stopfwdcount", "%u", cur->stop_forwarding);
METRICs("blkdtmfcount", "%u", cur->block_dtmf);
METRICs("unblkdtmfcount", "%u", cur->unblock_dtmf);
METRICs("blkmedia", "%u", cur->block_media);
METRICs("unblkmedia", "%u", cur->unblock_media);
METRICs("playmedia", "%u", cur->play_media);
METRICs("stopmedia", "%u", cur->stop_media);
METRICs("playdtmf", "%u", cur->play_dtmf);
METRICs("errorcount", "%u", cur->errors);
HEADER("}", NULL);
}
mutex_unlock(&rtpe_cngs_lock);
g_list_free(list);
HEADER("]", "");
METRICs("totalpingcount", "%u", total.ping);
METRICs("totaloffercount", "%u", total.offer);
METRICs("totalanswercount", "%u", total.answer);
METRICs("totaldeletecount", "%u", total.delete);
METRICs("totalquerycount", "%u", total.query);
METRICs("totallistcount", "%u", total.list);
METRICs("totalstartreccount", "%u", total.start_recording);
METRICs("totalstopreccount", "%u", total.stop_recording);
METRICs("totalstartfwdcount", "%u", total.start_forwarding);
METRICs("totalstopfwdcount", "%u", total.stop_forwarding);
METRICs("totalblkdtmfcount", "%u", total.block_dtmf);
METRICs("totalunblkdtmfcount", "%u", total.unblock_dtmf);
METRICs("totalblkmedia", "%u", total.block_media);
METRICs("totalunblkmedia", "%u", total.unblock_media);
METRICs("totalplaymedia", "%u", total.play_media);
METRICs("totalstopmedia", "%u", total.stop_media);
METRICs("totalplaydtmf", "%u", total.play_dtmf);
METRICs("totalerrorcount", "%u", total.errors);
HEADER("}", "");
HEADER("}", NULL);
return ret;
}
#pragma GCC diagnostic warning "-Wformat-zero-length"
static void free_stats_metric(void *p) {
struct stats_metric *m = p;
g_free(m->descr);
g_free(m->label);
g_free(m->value_long);
g_free(m->value_short);
g_slice_free1(sizeof(*m), m);
}
void statistics_free_metrics(GQueue **q) {
g_queue_free_full(*q, free_stats_metric);
*q = NULL;
}
void statistics_init() {
mutex_init(&rtpe_totalstats.total_average_lock);
mutex_init(&rtpe_totalstats_interval.total_average_lock);


+ 13
- 0
include/statistics.h View File

@ -92,6 +92,16 @@ struct codec_stats {
atomic64 pcm_samples[3];
};
struct stats_metric {
char *label;
char *descr;
char *value_short;
char *value_long;
int is_bracket;
int is_close_bracket;
int is_follow_up;
};
struct call_stats {
time_t last_packet;
@ -111,6 +121,9 @@ void statistics_update_foreignown_dec(struct call *);
void statistics_update_foreignown_inc(struct call* c);
void statistics_update_totals(struct packet_stream *) ;
GQueue *statistics_gather_metrics(void);
void statistics_free_metrics(GQueue **);
void statistics_init(void);
#endif /* STATISTICS_H_ */

Loading…
Cancel
Save