Added functionality to report statistics to graphite

pull/69/head^2
Frederic-Philippe Metz 10 years ago
parent e24253a709
commit 2ae0e35de4

@ -184,6 +184,8 @@ option and which are reproduced below:
-d, --delete-delay Delay for deleting a session from memory. -d, --delete-delay Delay for deleting a session from memory.
--sip-source Use SIP source address by default --sip-source Use SIP source address by default
--dtls-passive Always prefer DTLS passive role --dtls-passive Always prefer DTLS passive role
-g, --graphite=[IP46:]PORT TCP address of graphite statistics server
-w, --graphite-interval=INT Graphite data statistics send interval
Most of these options are indeed optional, with two exceptions. It's mandatory to specify at least one local Most of these options are indeed optional, with two exceptions. It's mandatory to specify at least one local
IP address through `--interface`, and at least one of the `--listen-...` options must be given. IP address through `--interface`, and at least one of the `--listen-...` options must be given.
@ -354,6 +356,14 @@ The options are described in more detail below.
NGCP-specific options NGCP-specific options
* -g, --graphite
Address of the graphite statistics server.
* -w, --graphite-interval
Interval of the time when information is sent to the graphite server.
A typical command line (enabling both UDP and NG protocols) thus may look like: A typical command line (enabling both UDP and NG protocols) thus may look like:
/usr/sbin/rtpengine --table=0 --interface=10.64.73.31 --interface=2001:db8::4f3:3d \ /usr/sbin/rtpengine --table=0 --interface=10.64.73.31 --interface=2001:db8::4f3:3d \

@ -63,7 +63,7 @@ endif
SRCS= main.c kernel.c poller.c aux.c control_tcp.c streambuf.c call.c control_udp.c redis.c \ SRCS= main.c kernel.c poller.c aux.c control_tcp.c streambuf.c call.c control_udp.c redis.c \
bencode.c cookie_cache.c udp_listener.c control_ng.c sdp.c str.c stun.c rtcp.c \ bencode.c cookie_cache.c udp_listener.c control_ng.c sdp.c str.c stun.c rtcp.c \
crypto.c rtp.c call_interfaces.c dtls.c log.c cli.c crypto.c rtp.c call_interfaces.c dtls.c log.c cli.c graphite.c
OBJS= $(SRCS:.c=.o) OBJS= $(SRCS:.c=.o)

@ -2505,7 +2505,9 @@ void call_destroy(struct call *c) {
(unsigned long long) ps->stats.bytes, (unsigned long long) ps->stats.bytes,
(unsigned long long) ps->stats.errors); (unsigned long long) ps->stats.errors);
m->totalstats.total_relayed_packets += (unsigned long long) ps->stats.packets; 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.total_relayed_errors += (unsigned long long) ps->stats.errors;
m->totalstats_interval.total_relayed_errors += (unsigned long long) ps->stats.errors;
} }
} }
if (_log_facility_cdr) if (_log_facility_cdr)
@ -2514,6 +2516,7 @@ void call_destroy(struct call *c) {
// --- for statistics getting one way stream or no relay at all // --- for statistics getting one way stream or no relay at all
m->totalstats.total_nopacket_relayed_sess *= 2; m->totalstats.total_nopacket_relayed_sess *= 2;
m->totalstats_interval.total_nopacket_relayed_sess *= 2;
for (l = c->monologues; l; l = l->next) { for (l = c->monologues; l; l = l->next) {
ml = l->data; ml = l->data;
@ -2550,32 +2553,46 @@ void call_destroy(struct call *c) {
} }
} }
if (ps && ps2 && ps->stats.packets!=0 && ps2->stats.packets==0) if (ps && ps2 && ps->stats.packets!=0 && ps2->stats.packets==0) {
m->totalstats.total_oneway_stream_sess++; m->totalstats.total_oneway_stream_sess++;
m->totalstats_interval.total_oneway_stream_sess++;
}
if (ps && ps2 && ps->stats.packets==0 && ps2->stats.packets==0) if (ps && ps2 && ps->stats.packets==0 && ps2->stats.packets==0) {
m->totalstats.total_nopacket_relayed_sess++; m->totalstats.total_nopacket_relayed_sess++;
m->totalstats_interval.total_nopacket_relayed_sess++;
}
} }
m->totalstats.total_nopacket_relayed_sess /= 2; m->totalstats.total_nopacket_relayed_sess /= 2;
m->totalstats_interval.total_nopacket_relayed_sess /= 2;
m->totalstats.total_managed_sess += 1; m->totalstats.total_managed_sess += 1;
m->totalstats_interval.total_managed_sess += 1;
ml = c->monologues->data; ml = c->monologues->data;
if (ml->term_reason==TIMEOUT) { if (ml->term_reason==TIMEOUT) {
m->totalstats.total_timeout_sess++; m->totalstats.total_timeout_sess++;
m->totalstats_interval.total_timeout_sess++;
} else if (ml->term_reason==SILENT_TIMEOUT) { } else if (ml->term_reason==SILENT_TIMEOUT) {
m->totalstats.total_silent_timeout_sess++; m->totalstats.total_silent_timeout_sess++;
m->totalstats_interval.total_silent_timeout_sess++;
} else if (ml->term_reason==REGULAR) { } else if (ml->term_reason==REGULAR) {
m->totalstats.total_regular_term_sess++; m->totalstats.total_regular_term_sess++;
m->totalstats_interval.total_regular_term_sess++;
} else if (ml->term_reason==FORCED) { } else if (ml->term_reason==FORCED) {
m->totalstats.total_forced_term_sess++; m->totalstats.total_forced_term_sess++;
m->totalstats_interval.total_forced_term_sess++;
} }
timeval_multiply(&m->totalstats.total_average_call_dur,&m->totalstats.total_average_call_dur,m->totalstats.total_managed_sess-1); timeval_multiply(&m->totalstats.total_average_call_dur,&m->totalstats.total_average_call_dur,m->totalstats.total_managed_sess-1);
timeval_add(&m->totalstats.total_average_call_dur,&m->totalstats.total_average_call_dur,&tim_result_duration); timeval_add(&m->totalstats.total_average_call_dur,&m->totalstats.total_average_call_dur,&tim_result_duration);
timeval_devide(&m->totalstats.total_average_call_dur,&m->totalstats.total_average_call_dur,m->totalstats.total_managed_sess); timeval_devide(&m->totalstats.total_average_call_dur,&m->totalstats.total_average_call_dur,m->totalstats.total_managed_sess);
timeval_multiply(&m->totalstats_interval.total_average_call_dur,&m->totalstats_interval.total_average_call_dur,m->totalstats_interval.total_managed_sess-1);
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);
if (_log_facility_cdr) if (_log_facility_cdr)
/* log it */ /* log it */
cdrlog(cdrbuffer); cdrlog(cdrbuffer);

@ -411,6 +411,7 @@ struct callmaster {
mutex_t statslock; mutex_t statslock;
struct stats stats; /* copied from statsps once a second */ struct stats stats; /* copied from statsps once a second */
struct totalstats totalstats; struct totalstats totalstats;
struct totalstats totalstats_interval;
struct poller *poller; struct poller *poller;
pcre *info_re; pcre *info_re;

@ -26,7 +26,7 @@
#include "dtls.h" #include "dtls.h"
#include "call_interfaces.h" #include "call_interfaces.h"
#include "cli.h" #include "cli.h"
#include "graphite.h"
@ -108,7 +108,9 @@ static char *b2b_url;
static enum xmlrpc_format xmlrpc_fmt = XF_SEMS; static enum xmlrpc_format xmlrpc_fmt = XF_SEMS;
static int num_threads; static int num_threads;
static int delete_delay = 30; static int delete_delay = 30;
static u_int32_t graphite_ip = NULL;
static u_int16_t graphite_port;
static int graphite_interval = 0;
static void sighandler(gpointer x) { static void sighandler(gpointer x) {
sigset_t ss; sigset_t ss;
@ -254,6 +256,7 @@ static void options(int *argc, char ***argv) {
char *listenudps = NULL; char *listenudps = NULL;
char *listenngs = NULL; char *listenngs = NULL;
char *listencli = NULL; char *listencli = NULL;
char *graphitep = NULL;
char *redisps = NULL; char *redisps = NULL;
char *log_facility_s = NULL; char *log_facility_s = NULL;
char *log_facility_cdr_s = NULL; char *log_facility_cdr_s = NULL;
@ -269,6 +272,8 @@ static void options(int *argc, char ***argv) {
{ "listen-udp", 'u', 0, G_OPTION_ARG_STRING, &listenudps, "UDP port to listen on", "[IP46:]PORT" }, { "listen-udp", 'u', 0, G_OPTION_ARG_STRING, &listenudps, "UDP port to listen on", "[IP46:]PORT" },
{ "listen-ng", 'n', 0, G_OPTION_ARG_STRING, &listenngs, "UDP port to listen on, NG protocol", "[IP46:]PORT" }, { "listen-ng", 'n', 0, G_OPTION_ARG_STRING, &listenngs, "UDP port to listen on, NG protocol", "[IP46:]PORT" },
{ "listen-cli", 'c', 0, G_OPTION_ARG_STRING, &listencli, "UDP port to listen on, CLI", "[IP46:]PORT" }, { "listen-cli", 'c', 0, G_OPTION_ARG_STRING, &listencli, "UDP port to listen on, CLI", "[IP46:]PORT" },
{ "graphite", 'g', 0, G_OPTION_ARG_STRING, &graphitep, "Address of the graphite server", "[IP46:]PORT" },
{ "graphite-interval", 'w', 0, G_OPTION_ARG_INT, &graphite_interval, "Graphite send interval in seconds", "INT" },
{ "tos", 'T', 0, G_OPTION_ARG_INT, &tos, "Default TOS value to set on streams", "INT" }, { "tos", 'T', 0, G_OPTION_ARG_INT, &tos, "Default TOS value to set on streams", "INT" },
{ "timeout", 'o', 0, G_OPTION_ARG_INT, &timeout, "RTP timeout", "SECS" }, { "timeout", 'o', 0, G_OPTION_ARG_INT, &timeout, "RTP timeout", "SECS" },
{ "silent-timeout",'s',0,G_OPTION_ARG_INT, &silent_timeout,"RTP timeout for muted", "SECS" }, { "silent-timeout",'s',0,G_OPTION_ARG_INT, &silent_timeout,"RTP timeout for muted", "SECS" },
@ -331,6 +336,10 @@ static void options(int *argc, char ***argv) {
die("Invalid IP or port (--listen-cli)"); die("Invalid IP or port (--listen-cli)");
} }
if (graphitep) {if (parse_ip_port(&graphite_ip, &graphite_port, graphitep))
die("Invalid IP or port (--graphite)");
}
if (tos < 0 || tos > 255) if (tos < 0 || tos > 255)
die("Invalid TOS value"); die("Invalid TOS value");
@ -606,6 +615,7 @@ no_kernel:
callmaster_config_init(ctx->m); callmaster_config_init(ctx->m);
ZERO(ctx->m->totalstats); ZERO(ctx->m->totalstats);
ZERO(ctx->m->totalstats_interval);
ctx->m->totalstats.started = time(NULL); ctx->m->totalstats.started = time(NULL);
if (!foreground) if (!foreground)
@ -623,6 +633,20 @@ static void timer_loop(void *d) {
poller_timers_wait_run(p, 100); poller_timers_wait_run(p, 100);
} }
static void graphite_loop(void *d) {
struct callmaster *cm = d;
if (!graphite_interval) {
ilog(LOG_WARNING,"Graphite send interval was not set. Setting it to 1 second.");
graphite_interval=1;
}
connect_to_graphite_server(graphite_ip,graphite_port);
while (!global_shutdown)
graphite_loop_run(cm,graphite_interval); // time in seconds
}
static void poller_loop(void *d) { static void poller_loop(void *d) {
struct poller *p = d; struct poller *p = d;
@ -642,6 +666,8 @@ int main(int argc, char **argv) {
thread_create_detach(sighandler, NULL); thread_create_detach(sighandler, NULL);
thread_create_detach(timer_loop, ctx.p); thread_create_detach(timer_loop, ctx.p);
if (graphite_ip)
thread_create_detach(graphite_loop, ctx.m);
if (num_threads < 1) { if (num_threads < 1) {
#ifdef _SC_NPROCESSORS_ONLN #ifdef _SC_NPROCESSORS_ONLN

@ -23,3 +23,5 @@ TABLE=0
# LOG_FACILITY_CDR=daemon # LOG_FACILITY_CDR=daemon
# NUM_THREADS=5 # NUM_THREADS=5
# DELETE_DELAY=30 # DELETE_DELAY=30
# GRAPHITE=9006
# GRAPHITE_INTERVAL=60

@ -72,6 +72,8 @@ OPTIONS="$OPTIONS --table=$TABLE"
[ -z "$LOG_FACILITY_CDR" ] || OPTIONS="$OPTIONS --log-facility-cdr=$LOG_FACILITY_CDR" [ -z "$LOG_FACILITY_CDR" ] || OPTIONS="$OPTIONS --log-facility-cdr=$LOG_FACILITY_CDR"
[ -z "$NUM_THREADS" ] || OPTIONS="$OPTIONS --num-threads=$NUM_THREADS" [ -z "$NUM_THREADS" ] || OPTIONS="$OPTIONS --num-threads=$NUM_THREADS"
[ -z "$DELETE_DELAY" ] || OPTIONS="$OPTIONS --delete-delay=$DELETE_DELAY" [ -z "$DELETE_DELAY" ] || OPTIONS="$OPTIONS --delete-delay=$DELETE_DELAY"
[ -z "$GRAPHITE" ] || OPTIONS="$OPTIONS --graphite=$GRAPHITE"
[ -z "$GRAPHITE_INTERVAL" ] || OPTIONS="$OPTIONS --graphite-interval=$GRAPHITE_INTERVAL"
if test "$FORK" = "no" ; then if test "$FORK" = "no" ; then
OPTIONS="$OPTIONS --foreground" OPTIONS="$OPTIONS --foreground"
fi fi

@ -143,6 +143,16 @@ build_opts() {
OPTS+=" --delete-delay=$DELETE_DELAY" OPTS+=" --delete-delay=$DELETE_DELAY"
fi fi
if [[ -n "$GRAPHITE" ]]
then
OPTS+=" --graphite=$GRAPHITE"
fi
if [[ -n "$GRAPHITE_INTERVAL" ]]
then
OPTS+=" --graphite-interval=$GRAPHITE_INTERVAL"
fi
if [[ -n "$LOG_FACILITY_CDR" ]] if [[ -n "$LOG_FACILITY_CDR" ]]
then then
OPTS+=" --log-facility-cdr=$LOG_FACILITY_CDR" OPTS+=" --log-facility-cdr=$LOG_FACILITY_CDR"

Loading…
Cancel
Save