Browse code

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
}

Andrei Pelinescu-Onciul authored on 08/08/2010 22:16:54
Showing 2 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,65 @@
0
+/* 
1
+ * $Id$
2
+ * 
3
+ * Copyright (C) 2010 iptelorg GmbH
4
+ *
5
+ * Permission to use, copy, modify, and distribute this software for any
6
+ * purpose with or without fee is hereby granted, provided that the above
7
+ * copyright notice and this permission notice appear in all copies.
8
+ *
9
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
+ */
17
+/** tcp statistics.
18
+ * @file tcp_stats.c
19
+ * @ingroup:  core
20
+ */
21
+/*
22
+ * History:
23
+ * --------
24
+ *  2010-08-08  initial version (andrei)
25
+*/
26
+
27
+#include "tcp_stats.h"
28
+#include "counters.h"
29
+
30
+struct tcp_counters_h tcp_cnts_h;
31
+
32
+/** intialize tcp statistics.
33
+ *  Must be called before forking.
34
+ * @return < 0 on errror, 0 on success.
35
+ */
36
+int tcp_stats_init()
37
+{
38
+#define TCP_REG_COUNTER(name) \
39
+	if (counter_register(&tcp_cnts_h.name, "tcp", # name, 0, 0, 0, 0) < 0) \
40
+		goto error;
41
+
42
+	TCP_REG_COUNTER(established);
43
+	TCP_REG_COUNTER(passive_open);
44
+	TCP_REG_COUNTER(connect_success);
45
+	TCP_REG_COUNTER(connect_failed);
46
+	TCP_REG_COUNTER(local_reject);
47
+	TCP_REG_COUNTER(con_timeout);
48
+	TCP_REG_COUNTER(con_reset);
49
+	TCP_REG_COUNTER(send_timeout);
50
+	TCP_REG_COUNTER(sendq_full);
51
+	return 0;
52
+error:
53
+	return -1;
54
+}
55
+
56
+
57
+void tcp_stats_destroy()
58
+{
59
+	/* do nothing */
60
+}
61
+
62
+
63
+
64
+/* vi: set ts=4 sw=4 tw=79:ai:cindent: */
... ...
@@ -27,6 +27,11 @@
27 27
 #ifndef __tcp_stats_h
28 28
 #define __tcp_stats_h
29 29
 
30
+/* enable tcp stats by default */
31
+#ifndef NO_TCP_STATS
32
+#define USE_TCP_STATS
33
+#endif
34
+
30 35
 #ifndef USE_TCP_STATS
31 36
 
32 37
 #define INIT_TCP_STATS() 0 /* success */
... ...
@@ -42,9 +47,28 @@
42 42
 
43 43
 #else /* USE_TCP_STATS */
44 44
 
45
-#define INIT_TCP_STATS() 0 /* success */
45
+#include "counters.h"
46 46
 
47
-#define DESTROY_TCP_STATS()
47
+struct tcp_counters_h {
48
+	counter_handle_t established;
49
+	counter_handle_t passive_open;
50
+	counter_handle_t connect_success;
51
+	counter_handle_t connect_failed;
52
+	counter_handle_t local_reject;
53
+	counter_handle_t con_timeout;
54
+	counter_handle_t con_reset;
55
+	counter_handle_t send_timeout;
56
+	counter_handle_t sendq_full;
57
+};
58
+
59
+extern struct tcp_counters_h tcp_cnts_h;
60
+
61
+int tcp_stats_init();
62
+void tcp_stats_destroy();
63
+
64
+#define INIT_TCP_STATS() tcp_stats_init()
65
+
66
+#define DESTROY_TCP_STATS() tcp_stats_destroy()
48 67
 
49 68
 
50 69
 /** called each time a new tcp connection is established.
... ...
@@ -54,36 +78,49 @@
54 54
  *   sent on the new connection and not immediately after accept() or 
55 55
  *   connect()
56 56
  */
57
-#define TCP_STATS_ESTABLISHED(state)
57
+#define TCP_STATS_ESTABLISHED(state) \
58
+	do { \
59
+		counter_inc(tcp_cnts_h.established); \
60
+		if (state == S_CONN_ACCEPT) \
61
+			counter_inc(tcp_cnts_h.passive_open); \
62
+		else \
63
+			counter_inc(tcp_cnts_h.connect_success); \
64
+	}while(0)
58 65
 
59 66
 /** called each time a new outgoing connection fails.  */
60
-#define TCP_STATS_CONNECT_FAILED()
67
+#define TCP_STATS_CONNECT_FAILED() \
68
+	counter_inc(tcp_cnts_h.connect_failed)
61 69
 
62 70
 /** called each time a new incoming connection is rejected.
63 71
  * (accept() denied due to maximum number of TCP connections being exceeded)
64 72
  */
65
-#define TCP_STATS_LOCAL_REJECT()
73
+#define TCP_STATS_LOCAL_REJECT() \
74
+	counter_inc(tcp_cnts_h.local_reject)
66 75
 
67 76
 
68 77
 /** called each time a connection lifetime expires.
69 78
   * (the connection is closed for being idle for too long)
70 79
   */
71
-#define TCP_STATS_CON_TIMEOUT()
80
+#define TCP_STATS_CON_TIMEOUT() \
81
+	counter_inc(tcp_cnts_h.con_timeout)
72 82
 
73 83
 
74 84
 /** called each time a TCP RST is received on an established connection.  */
75
-#define TCP_STATS_CON_RESET()
85
+#define TCP_STATS_CON_RESET() \
86
+	counter_inc(tcp_cnts_h.con_reset)
76 87
 
77 88
 /** called each time a send operation fails due to a timeout.
78 89
   * FIXME: it works only in async mode (in sync. mode a send might timeout
79 90
   *  but the stats won't be increased).
80 91
   */
81
-#define TCP_STATS_SEND_TIMEOUT()
92
+#define TCP_STATS_SEND_TIMEOUT() \
93
+	counter_inc(tcp_cnts_h.send_timeout)
82 94
 
83 95
 /** called each time a send fails due to the buffering capacity being exceeded.
84 96
   * (used only in tcp async mode)
85 97
   */
86
-#define TCP_STATS_SENDQ_FULL()
98
+#define TCP_STATS_SENDQ_FULL() \
99
+	counter_inc(tcp_cnts_h.sendq_full)
87 100
 
88 101
 #endif /* USE_TCP_STATS */
89 102