Module: sip-router Branch: andrei/counters Commit: 1aca6a526b718c95eecdb86e17f7f0eeb7abf0bc URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=1aca6a52...
Author: Andrei Pelinescu-Onciul andrei@iptel.org Committer: Andrei Pelinescu-Onciul andrei@iptel.org Date: Mon Aug 9 00:16:54 2010 +0200
tcp: enable tcp statistics
tcp statistics implemented using the counters api. Enabled by default (unless compiles with -DNO_TCP_STATS). E.g.: $ sercmd cnt.grp_get_all tcp { con_reset: 4 con_timeout: 0 connect_failed: 6 connect_success: 1 established: 12 local_reject: 0 passive_open: 11 send_timeout: 0 sendq_full: 0 }
---
tcp_stats.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tcp_stats.h | 55 +++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 111 insertions(+), 9 deletions(-)
diff --git a/tcp_stats.c b/tcp_stats.c new file mode 100644 index 0000000..e0a8fc0 --- /dev/null +++ b/tcp_stats.c @@ -0,0 +1,65 @@ +/* + * $Id$ + * + * Copyright (C) 2010 iptelorg GmbH + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/** tcp statistics. + * @file tcp_stats.c + * @ingroup: core + */ +/* + * History: + * -------- + * 2010-08-08 initial version (andrei) +*/ + +#include "tcp_stats.h" +#include "counters.h" + +struct tcp_counters_h tcp_cnts_h; + +/** intialize tcp statistics. + * Must be called before forking. + * @return < 0 on errror, 0 on success. + */ +int tcp_stats_init() +{ +#define TCP_REG_COUNTER(name) \ + if (counter_register(&tcp_cnts_h.name, "tcp", # name, 0, 0, 0, 0) < 0) \ + goto error; + + TCP_REG_COUNTER(established); + TCP_REG_COUNTER(passive_open); + TCP_REG_COUNTER(connect_success); + TCP_REG_COUNTER(connect_failed); + TCP_REG_COUNTER(local_reject); + TCP_REG_COUNTER(con_timeout); + TCP_REG_COUNTER(con_reset); + TCP_REG_COUNTER(send_timeout); + TCP_REG_COUNTER(sendq_full); + return 0; +error: + return -1; +} + + +void tcp_stats_destroy() +{ + /* do nothing */ +} + + + +/* vi: set ts=4 sw=4 tw=79:ai:cindent: */ diff --git a/tcp_stats.h b/tcp_stats.h index 67c1ddc..f39e2ec 100644 --- a/tcp_stats.h +++ b/tcp_stats.h @@ -27,6 +27,11 @@ #ifndef __tcp_stats_h #define __tcp_stats_h
+/* enable tcp stats by default */ +#ifndef NO_TCP_STATS +#define USE_TCP_STATS +#endif + #ifndef USE_TCP_STATS
#define INIT_TCP_STATS() 0 /* success */ @@ -42,9 +47,28 @@
#else /* USE_TCP_STATS */
-#define INIT_TCP_STATS() 0 /* success */ +#include "counters.h"
-#define DESTROY_TCP_STATS() +struct tcp_counters_h { + counter_handle_t established; + counter_handle_t passive_open; + counter_handle_t connect_success; + counter_handle_t connect_failed; + counter_handle_t local_reject; + counter_handle_t con_timeout; + counter_handle_t con_reset; + counter_handle_t send_timeout; + counter_handle_t sendq_full; +}; + +extern struct tcp_counters_h tcp_cnts_h; + +int tcp_stats_init(); +void tcp_stats_destroy(); + +#define INIT_TCP_STATS() tcp_stats_init() + +#define DESTROY_TCP_STATS() tcp_stats_destroy()
/** called each time a new tcp connection is established. @@ -54,36 +78,49 @@ * sent on the new connection and not immediately after accept() or * connect() */ -#define TCP_STATS_ESTABLISHED(state) +#define TCP_STATS_ESTABLISHED(state) \ + do { \ + counter_inc(tcp_cnts_h.established); \ + if (state == S_CONN_ACCEPT) \ + counter_inc(tcp_cnts_h.passive_open); \ + else \ + counter_inc(tcp_cnts_h.connect_success); \ + }while(0)
/** called each time a new outgoing connection fails. */ -#define TCP_STATS_CONNECT_FAILED() +#define TCP_STATS_CONNECT_FAILED() \ + counter_inc(tcp_cnts_h.connect_failed)
/** called each time a new incoming connection is rejected. * (accept() denied due to maximum number of TCP connections being exceeded) */ -#define TCP_STATS_LOCAL_REJECT() +#define TCP_STATS_LOCAL_REJECT() \ + counter_inc(tcp_cnts_h.local_reject)
/** called each time a connection lifetime expires. * (the connection is closed for being idle for too long) */ -#define TCP_STATS_CON_TIMEOUT() +#define TCP_STATS_CON_TIMEOUT() \ + counter_inc(tcp_cnts_h.con_timeout)
/** called each time a TCP RST is received on an established connection. */ -#define TCP_STATS_CON_RESET() +#define TCP_STATS_CON_RESET() \ + counter_inc(tcp_cnts_h.con_reset)
/** called each time a send operation fails due to a timeout. * FIXME: it works only in async mode (in sync. mode a send might timeout * but the stats won't be increased). */ -#define TCP_STATS_SEND_TIMEOUT() +#define TCP_STATS_SEND_TIMEOUT() \ + counter_inc(tcp_cnts_h.send_timeout)
/** called each time a send fails due to the buffering capacity being exceeded. * (used only in tcp async mode) */ -#define TCP_STATS_SENDQ_FULL() +#define TCP_STATS_SENDQ_FULL() \ + counter_inc(tcp_cnts_h.sendq_full)
#endif /* USE_TCP_STATS */