Module: sip-router
Branch: andrei/counters
Commit: 1aca6a526b718c95eecdb86e17f7f0eeb7abf0bc
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=1aca6a5…
Author: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei(a)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 */