Add IPv4 TCP charts to macOS plugin
Vladimir Kobal committed
Jan 9, 2017 at 13:51 UTC
5ae05859a22d41489355ee65b2e4f815b7c73240
1 file changed
+183
-1
src/macos_sysctl.c
+183
-1
@@ -2,6 +2,10 @@
2
#include <sys/sysctl.h>
3
// NEEDED BY: do_bandwidth
4
#include <net/route.h>
5
+// NEEDED BY do_tcp...
6
+#include <sys/socketvar.h>
7
+#include <netinet/tcp_var.h>
8
+#include <netinet/tcp_fsm.h>
9
10
#define GETSYSCTL(name, var) getsysctl(name, &(var), sizeof(var))
11
@@ -13,12 +17,22 @@ int getsysctl(const char *name, void *ptr, size_t len);
17
int do_macos_sysctl(int update_every, usec_t dt) {
18
(void)dt;
19
16
- static int do_loadavg = -1, do_swap = -1, do_bandwidth = -1;
20
+ static int do_loadavg = -1, do_swap = -1, do_bandwidth = -1,
21
+ do_tcp_packets = -1, do_tcp_errors = -1, do_tcp_handshake = -1, do_ecn = -1,
22
+ do_tcpext_syscookies = -1, do_tcpext_ofo = -1, do_tcpext_connaborts = -1;
23
+
24
25
if (unlikely(do_loadavg == -1)) {
26
do_loadavg = config_get_boolean("plugin:macos:sysctl", "enable load average", 1);
27
do_swap = config_get_boolean("plugin:macos:sysctl", "system swap", 1);
28
do_bandwidth = config_get_boolean("plugin:macos:sysctl", "bandwidth", 1);
29
+ do_tcp_packets = config_get_boolean("plugin:macos:sysctl", "ipv4 TCP packets", 1);
30
+ do_tcp_errors = config_get_boolean("plugin:macos:sysctl", "ipv4 TCP errors", 1);
31
+ do_tcp_handshake = config_get_boolean("plugin:macos:sysctl", "ipv4 TCP handshake issues", 1);
32
+ do_ecn = config_get_boolean_ondemand("plugin:macos:sysctl", "ECN packets", CONFIG_ONDEMAND_ONDEMAND);
33
+ do_tcpext_syscookies = config_get_boolean_ondemand("plugin:macos:sysctl", "TCP SYN cookies", CONFIG_ONDEMAND_ONDEMAND);
34
+ do_tcpext_ofo = config_get_boolean_ondemand("plugin:macos:sysctl", "TCP out-of-order queue", CONFIG_ONDEMAND_ONDEMAND);
35
+ do_tcpext_connaborts = config_get_boolean_ondemand("plugin:macos:sysctl", "TCP connection aborts", CONFIG_ONDEMAND_ONDEMAND);
36
}
37
38
RRDSET *st;
@@ -45,6 +59,10 @@ int do_macos_sysctl(int update_every, usec_t dt) {
59
u_long ift_obytes;
60
} iftot = {0, 0};
61
62
+ // NEEDED BY: do_tcp...
63
+ struct tcpstat tcpstat;
64
+ uint64_t tcps_states[TCP_NSTATES];
65
+
66
if (last_loadavg_usec <= dt) {
67
if (likely(do_loadavg)) {
68
if (unlikely(GETSYSCTL("vm.loadavg", sysload))) {
@@ -142,6 +160,170 @@ int do_macos_sysctl(int update_every, usec_t dt) {
160
}
161
}
162
163
+ // --------------------------------------------------------------------
164
+
165
+ // see http://net-snmp.sourceforge.net/docs/mibs/tcp.html
166
+ if (likely(do_tcp_packets || do_tcp_errors || do_tcp_handshake || do_tcpext_connaborts || do_tcpext_ofo || do_tcpext_syscookies || do_ecn)) {
167
+ if (unlikely(GETSYSCTL("net.inet.tcp.stats", tcpstat))){
168
+ do_tcp_packets = 0;
169
+ error("DISABLED: ipv4.tcppackets");
170
+ do_tcp_errors = 0;
171
+ error("DISABLED: ipv4.tcperrors");
172
+ do_tcp_handshake = 0;
173
+ error("DISABLED: ipv4.tcphandshake");
174
+ do_tcpext_connaborts = 0;
175
+ error("DISABLED: ipv4.tcpconnaborts");
176
+ do_tcpext_ofo = 0;
177
+ error("DISABLED: ipv4.tcpofo");
178
+ do_tcpext_syscookies = 0;
179
+ error("DISABLED: ipv4.tcpsyncookies");
180
+ do_ecn = 0;
181
+ error("DISABLED: ipv4.ecnpkts");
182
+ } else {
183
+ if (likely(do_tcp_packets)) {
184
+ st = rrdset_find("ipv4.tcppackets");
185
+ if (unlikely(!st)) {
186
+ st = rrdset_create("ipv4", "tcppackets", NULL, "tcp", NULL, "IPv4 TCP Packets",
187
+ "packets/s",
188
+ 2600, update_every, RRDSET_TYPE_LINE);
189
+
190
+ rrddim_add(st, "InSegs", "received", 1, 1, RRDDIM_INCREMENTAL);
191
+ rrddim_add(st, "OutSegs", "sent", -1, 1, RRDDIM_INCREMENTAL);
192
+ } else
193
+ rrdset_next(st);
194
+
195
+ rrddim_set(st, "InSegs", tcpstat.tcps_rcvtotal);
196
+ rrddim_set(st, "OutSegs", tcpstat.tcps_sndtotal);
197
+ rrdset_done(st);
198
+ }
199
+
200
+ // --------------------------------------------------------------------
201
+
202
+ if (likely(do_tcp_errors)) {
203
+ st = rrdset_find("ipv4.tcperrors");
204
+ if (unlikely(!st)) {
205
+ st = rrdset_create("ipv4", "tcperrors", NULL, "tcp", NULL, "IPv4 TCP Errors",
206
+ "packets/s",
207
+ 2700, update_every, RRDSET_TYPE_LINE);
208
+ st->isdetail = 1;
209
+
210
+ rrddim_add(st, "InErrs", NULL, 1, 1, RRDDIM_INCREMENTAL);
211
+ rrddim_add(st, "InCsumErrors", NULL, 1, 1, RRDDIM_INCREMENTAL);
212
+ rrddim_add(st, "RetransSegs", NULL, -1, 1, RRDDIM_INCREMENTAL);
213
+ } else
214
+ rrdset_next(st);
215
+
216
+ rrddim_set(st, "InErrs", tcpstat.tcps_rcvbadoff + tcpstat.tcps_rcvshort);
217
+ rrddim_set(st, "InCsumErrors", tcpstat.tcps_rcvbadsum);
218
+ rrddim_set(st, "RetransSegs", tcpstat.tcps_sndrexmitpack);
219
+ rrdset_done(st);
220
+ }
221
+
222
+ // --------------------------------------------------------------------
223
+
224
+ if (likely(do_tcp_handshake)) {
225
+ st = rrdset_find("ipv4.tcphandshake");
226
+ if (unlikely(!st)) {
227
+ st = rrdset_create("ipv4", "tcphandshake", NULL, "tcp", NULL,
228
+ "IPv4 TCP Handshake Issues",
229
+ "events/s", 2900, update_every, RRDSET_TYPE_LINE);
230
+ st->isdetail = 1;
231
+
232
+ rrddim_add(st, "EstabResets", NULL, 1, 1, RRDDIM_INCREMENTAL);
233
+ rrddim_add(st, "ActiveOpens", NULL, 1, 1, RRDDIM_INCREMENTAL);
234
+ rrddim_add(st, "PassiveOpens", NULL, 1, 1, RRDDIM_INCREMENTAL);
235
+ rrddim_add(st, "AttemptFails", NULL, 1, 1, RRDDIM_INCREMENTAL);
236
+ } else
237
+ rrdset_next(st);
238
+
239
+ rrddim_set(st, "EstabResets", tcpstat.tcps_drops);
240
+ rrddim_set(st, "ActiveOpens", tcpstat.tcps_connattempt);
241
+ rrddim_set(st, "PassiveOpens", tcpstat.tcps_accepts);
242
+ rrddim_set(st, "AttemptFails", tcpstat.tcps_conndrops);
243
+ rrdset_done(st);
244
+ }
245
+
246
+ // --------------------------------------------------------------------
247
+
248
+ if (do_tcpext_connaborts == CONFIG_ONDEMAND_YES || (do_tcpext_connaborts == CONFIG_ONDEMAND_ONDEMAND && (tcpstat.tcps_rcvpackafterwin || tcpstat.tcps_rcvafterclose || tcpstat.tcps_rcvmemdrop || tcpstat.tcps_persistdrop))) {
249
+ do_tcpext_connaborts = CONFIG_ONDEMAND_YES;
250
+ st = rrdset_find("ipv4.tcpconnaborts");
251
+ if (unlikely(!st)) {
252
+ st = rrdset_create("ipv4", "tcpconnaborts", NULL, "tcp", NULL, "TCP Connection Aborts", "connections/s", 3010, update_every, RRDSET_TYPE_LINE);
253
+
254
+ rrddim_add(st, "TCPAbortOnData", "baddata", 1, 1, RRDDIM_INCREMENTAL);
255
+ rrddim_add(st, "TCPAbortOnClose", "userclosed", 1, 1, RRDDIM_INCREMENTAL);
256
+ rrddim_add(st, "TCPAbortOnMemory", "nomemory", 1, 1, RRDDIM_INCREMENTAL);
257
+ rrddim_add(st, "TCPAbortOnTimeout", "timeout", 1, 1, RRDDIM_INCREMENTAL);
258
+ }
259
+ else rrdset_next(st);
260
+
261
+ rrddim_set(st, "TCPAbortOnData", tcpstat.tcps_rcvpackafterwin);
262
+ rrddim_set(st, "TCPAbortOnClose", tcpstat.tcps_rcvafterclose);
263
+ rrddim_set(st, "TCPAbortOnMemory", tcpstat.tcps_rcvmemdrop);
264
+ rrddim_set(st, "TCPAbortOnTimeout", tcpstat.tcps_persistdrop);
265
+ rrdset_done(st);
266
+ }
267
+
268
+ // --------------------------------------------------------------------
269
+
270
+ if (do_tcpext_ofo == CONFIG_ONDEMAND_YES || (do_tcpext_ofo == CONFIG_ONDEMAND_ONDEMAND && tcpstat.tcps_rcvoopack)) {
271
+ do_tcpext_ofo = CONFIG_ONDEMAND_YES;
272
+ st = rrdset_find("ipv4.tcpofo");
273
+ if (unlikely(!st)) {
274
+ st = rrdset_create("ipv4", "tcpofo", NULL, "tcp", NULL, "TCP Out-Of-Order Queue", "packets/s", 3050, update_every, RRDSET_TYPE_LINE);
275
+
276
+ rrddim_add(st, "TCPOFOQueue", "inqueue", 1, 1, RRDDIM_INCREMENTAL);
277
+ }
278
+ else rrdset_next(st);
279
+
280
+ rrddim_set(st, "TCPOFOQueue", tcpstat.tcps_rcvoopack);
281
+ rrdset_done(st);
282
+ }
283
+
284
+ // --------------------------------------------------------------------
285
+
286
+ if (do_tcpext_syscookies == CONFIG_ONDEMAND_YES || (do_tcpext_syscookies == CONFIG_ONDEMAND_ONDEMAND && (tcpstat.tcps_sc_sendcookie || tcpstat.tcps_sc_recvcookie || tcpstat.tcps_sc_zonefail))) {
287
+ do_tcpext_syscookies = CONFIG_ONDEMAND_YES;
288
+
289
+ st = rrdset_find("ipv4.tcpsyncookies");
290
+ if (unlikely(!st)) {
291
+ st = rrdset_create("ipv4", "tcpsyncookies", NULL, "tcp", NULL, "TCP SYN Cookies", "packets/s", 3100, update_every, RRDSET_TYPE_LINE);
292
+
293
+ rrddim_add(st, "SyncookiesRecv", "received", 1, 1, RRDDIM_INCREMENTAL);
294
+ rrddim_add(st, "SyncookiesSent", "sent", -1, 1, RRDDIM_INCREMENTAL);
295
+ rrddim_add(st, "SyncookiesFailed", "failed", -1, 1, RRDDIM_INCREMENTAL);
296
+ }
297
+ else rrdset_next(st);
298
+
299
+ rrddim_set(st, "SyncookiesRecv", tcpstat.tcps_sc_recvcookie);
300
+ rrddim_set(st, "SyncookiesSent", tcpstat.tcps_sc_sendcookie);
301
+ rrddim_set(st, "SyncookiesFailed", tcpstat.tcps_sc_zonefail);
302
+ rrdset_done(st);
303
+ }
304
+
305
+ // --------------------------------------------------------------------
306
+
307
+ if (do_ecn == CONFIG_ONDEMAND_YES || (do_ecn == CONFIG_ONDEMAND_ONDEMAND && (tcpstat.tcps_ecn_recv_ce || tcpstat.tcps_ecn_not_supported))) {
308
+ do_ecn = CONFIG_ONDEMAND_YES;
309
+ st = rrdset_find("ipv4.ecnpkts");
310
+ if (unlikely(!st)) {
311
+ st = rrdset_create("ipv4", "ecnpkts", NULL, "ecn", NULL, "IPv4 ECN Statistics", "packets/s", 8700, update_every, RRDSET_TYPE_LINE);
312
+ st->isdetail = 1;
313
+
314
+ rrddim_add(st, "InCEPkts", "CEP", 1, 1, RRDDIM_INCREMENTAL);
315
+ rrddim_add(st, "InNoECTPkts", "NoECTP", -1, 1, RRDDIM_INCREMENTAL);
316
+ }
317
+ else rrdset_next(st);
318
+
319
+ rrddim_set(st, "InCEPkts", tcpstat.tcps_ecn_recv_ce);
320
+ rrddim_set(st, "InNoECTPkts", tcpstat.tcps_ecn_not_supported);
321
+ rrdset_done(st);
322
+ }
323
+
324
+ }
325
+ }
326
+
327
return 0;
328
}
329