diff --git a/daemon/call.c b/daemon/call.c index 6b4d5f712..f484dfa4a 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -1423,6 +1423,9 @@ struct callmaster *callmaster_new(struct poller *p) { poller_add_timer(p, callmaster_timer, &c->obj); + mutex_init(&c->totalstats_lock); + c->totalstats.started = poller_now; + return c; fail: @@ -2509,10 +2512,13 @@ void call_destroy(struct call *c) { (unsigned long long) ps->stats.bytes, (unsigned long long) ps->stats.errors, (unsigned long long) ps->last_packet); + + mutex_lock(&m->totalstats_lock); m->totalstats.total_relayed_packets += (unsigned long long) ps->stats.packets; m->totalstats_interval.total_relayed_packets += (unsigned long long) ps->stats.packets; m->totalstats.total_relayed_errors += (unsigned long long) ps->stats.errors; m->totalstats_interval.total_relayed_errors += (unsigned long long) ps->stats.errors; + mutex_unlock(&m->totalstats_lock); } } if (_log_facility_cdr) @@ -2520,8 +2526,11 @@ void call_destroy(struct call *c) { } // --- for statistics getting one way stream or no relay at all + mutex_lock(&m->totalstats_lock); m->totalstats.total_nopacket_relayed_sess *= 2; m->totalstats_interval.total_nopacket_relayed_sess *= 2; + mutex_unlock(&m->totalstats_lock); + for (l = c->monologues; l; l = l->next) { ml = l->data; @@ -2558,17 +2567,22 @@ void call_destroy(struct call *c) { } } - if (ps && ps2 && ps->stats.packets!=0 && ps2->stats.packets==0) { - m->totalstats.total_oneway_stream_sess++; - m->totalstats_interval.total_oneway_stream_sess++; + if (ps && ps2 && ps2->stats.packets==0) { + mutex_lock(&m->totalstats_lock); + if (ps->stats.packets!=0) { + m->totalstats.total_oneway_stream_sess++; + m->totalstats_interval.total_oneway_stream_sess++; + } + else { + m->totalstats.total_nopacket_relayed_sess++; + m->totalstats_interval.total_nopacket_relayed_sess++; + } + mutex_unlock(&m->totalstats_lock); } + } - if (ps && ps2 && ps->stats.packets==0 && ps2->stats.packets==0) { - m->totalstats.total_nopacket_relayed_sess++; - m->totalstats_interval.total_nopacket_relayed_sess++; - } + mutex_lock(&m->totalstats_lock); - } m->totalstats.total_nopacket_relayed_sess /= 2; m->totalstats_interval.total_nopacket_relayed_sess /= 2; @@ -2598,6 +2612,8 @@ void call_destroy(struct call *c) { timeval_add(&m->totalstats_interval.total_average_call_dur,&m->totalstats_interval.total_average_call_dur,&tim_result_duration); timeval_devide(&m->totalstats_interval.total_average_call_dur,&m->totalstats_interval.total_average_call_dur,m->totalstats_interval.total_managed_sess); + mutex_unlock(&m->totalstats_lock); + if (_log_facility_cdr) /* log it */ cdrlog(cdrbuffer); diff --git a/daemon/call.h b/daemon/call.h index 2c946f062..ddd9e8778 100644 --- a/daemon/call.h +++ b/daemon/call.h @@ -410,6 +410,7 @@ struct callmaster { struct stats statsps; /* per second stats, running timer */ mutex_t statslock; struct stats stats; /* copied from statsps once a second */ + mutex_t totalstats_lock; /* for both of them */ struct totalstats totalstats; struct totalstats totalstats_interval; struct control_ng_stats* control_ng_stats; diff --git a/daemon/cli.c b/daemon/cli.c index f7547914b..3b72cd6e7 100644 --- a/daemon/cli.c +++ b/daemon/cli.c @@ -25,6 +25,9 @@ static const char* TRUNCATED = " ... Output truncated. Increase Output Buffer static void cli_incoming_list_totals(char* buffer, int len, struct callmaster* m, char* replybuffer, const char* outbufend) { int printlen=0; + + mutex_lock(&m->totalstats_lock); + printlen = snprintf(replybuffer,(outbufend-replybuffer), "\nTotal statistics (does not include current running sessions):\n\n"); ADJUSTLEN(printlen,outbufend,replybuffer); printlen = snprintf(replybuffer,(outbufend-replybuffer), " Uptime of rtpengine :%llu seconds\n", (unsigned long long)time(NULL)-m->totalstats.started); @@ -49,6 +52,9 @@ static void cli_incoming_list_totals(char* buffer, int len, struct callmaster* m ADJUSTLEN(printlen,outbufend,replybuffer); printlen = snprintf(replybuffer,(outbufend-replybuffer), " Average call duration :%ld.%06ld\n\n",m->totalstats.total_average_call_dur.tv_sec,m->totalstats.total_average_call_dur.tv_usec); ADJUSTLEN(printlen,outbufend,replybuffer); + + mutex_unlock(&m->totalstats_lock); + printlen = snprintf(replybuffer,(outbufend-replybuffer), "Control statistics:\n\n"); ADJUSTLEN(printlen,outbufend,replybuffer); printlen = snprintf(replybuffer,(outbufend-replybuffer), " %10s | %10s | %10s | %10s | %10s | %10s | %10s | %10s \n", diff --git a/daemon/graphite.c b/daemon/graphite.c index 74108fc7e..702c2ce71 100644 --- a/daemon/graphite.c +++ b/daemon/graphite.c @@ -81,6 +81,8 @@ int send_graphite_data() { char data_to_send[8192]; memset(&data_to_send,0,8192); char* ptr = data_to_send; + mutex_lock(&cm->totalstats_lock); + rc = sprintf(ptr,"%s.totals.average_call_dur.tv_sec %i %u\n",hostname, cm->totalstats_interval.total_average_call_dur.tv_sec,(unsigned)time(NULL)); ptr += rc; rc = sprintf(ptr,"%s.totals.average_call_dur.tv_usec %i %u\n",hostname, cm->totalstats_interval.total_average_call_dur.tv_usec,(unsigned)time(NULL)); ptr += rc; rc = sprintf(ptr,"%s.totals.forced_term_sess %i %u\n",hostname, cm->totalstats_interval.total_forced_term_sess,(unsigned)time(NULL)); ptr += rc; @@ -95,6 +97,8 @@ int send_graphite_data() { ZERO(cm->totalstats_interval); + mutex_unlock(&cm->totalstats_lock); + rc = write(graphite_sock, data_to_send, strlen(data_to_send)); if (rc<0) { ilog(LOG_ERROR,"Could not write to graphite socket. Disconnecting graphite server."); diff --git a/daemon/main.c b/daemon/main.c index 560615ee2..d46667597 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -614,10 +614,6 @@ no_kernel: ctx->m->conf = mc; callmaster_config_init(ctx->m); - ZERO(ctx->m->totalstats); - ZERO(ctx->m->totalstats_interval); - ctx->m->totalstats.started = time(NULL); - if (!foreground) daemonize(); wpidfile();