]> arthur.barton.de Git - netdata.git/blob - src/proc_net_snmp.c
log: now is logging program name too; tc: huge optimizations; procfile: optimized...
[netdata.git] / src / proc_net_snmp.c
1 #include <inttypes.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5
6 #include "log.h"
7 #include "config.h"
8 #include "procfile.h"
9 #include "rrd.h"
10 #include "plugin_proc.h"
11
12 #define RRD_TYPE_NET_SNMP                       "ipv4"
13 #define RRD_TYPE_NET_SNMP_LEN           strlen(RRD_TYPE_NET_SNMP)
14
15 int do_proc_net_snmp(int update_every, unsigned long long dt) {
16         static procfile *ff = NULL;
17         static int do_ip_packets = -1, do_ip_fragsout = -1, do_ip_fragsin = -1, do_ip_errors = -1,
18                 do_tcp_sockets = -1, do_tcp_packets = -1, do_tcp_errors = -1, do_tcp_handshake = -1, 
19                 do_udp_packets = -1, do_udp_errors = -1;
20
21         if(do_ip_packets == -1)         do_ip_packets           = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 packets", 1);
22         if(do_ip_fragsout == -1)        do_ip_fragsout          = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 fragrments sent", 1);
23         if(do_ip_fragsin == -1)         do_ip_fragsin           = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 fragments assembly", 1);
24         if(do_ip_errors == -1)          do_ip_errors            = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 errors", 1);
25         if(do_tcp_sockets == -1)        do_tcp_sockets          = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 TCP connections", 1);
26         if(do_tcp_packets == -1)        do_tcp_packets          = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 TCP packets", 1);
27         if(do_tcp_errors == -1)         do_tcp_errors           = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 TCP errors", 1);
28         if(do_tcp_handshake == -1)      do_tcp_handshake        = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 TCP handshake issues", 1);
29         if(do_udp_packets == -1)        do_udp_packets          = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 UDP packets", 1);
30         if(do_udp_errors == -1)         do_udp_errors           = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 UDP errors", 1);
31
32         if(dt) {};
33
34         if(!ff) ff = procfile_open("/proc/net/snmp", " \t:", PROCFILE_FLAG_DEFAULT);
35         if(!ff) return 1;
36
37         ff = procfile_readall(ff);
38         if(!ff) return 0; // we return 0, so that we will retry to open it next time
39
40         uint32_t lines = procfile_lines(ff), l;
41         uint32_t words;
42
43         RRDSET *st;
44
45         for(l = 0; l < lines ;l++) {
46                 if(strcmp(procfile_lineword(ff, l, 0), "Ip") == 0) {
47                         l++;
48
49                         if(strcmp(procfile_lineword(ff, l, 0), "Ip") != 0) {
50                                 error("Cannot read Ip line from /proc/net/snmp.");
51                                 break;
52                         }
53
54                         words = procfile_linewords(ff, l);
55                         if(words < 20) {
56                                 error("Cannot read /proc/net/snmp Ip line. Expected 20 params, read %d.", words);
57                                 continue;
58                         }
59
60                         // see also http://net-snmp.sourceforge.net/docs/mibs/ip.html
61                         unsigned long long Forwarding, DefaultTTL, InReceives, InHdrErrors, InAddrErrors, ForwDatagrams, InUnknownProtos, InDiscards, InDelivers,
62                                 OutRequests, OutDiscards, OutNoRoutes, ReasmTimeout, ReasmReqds, ReasmOKs, ReasmFails, FragOKs, FragFails, FragCreates;
63
64                         Forwarding              = strtoull(procfile_lineword(ff, l, 1), NULL, 10);
65                         DefaultTTL              = strtoull(procfile_lineword(ff, l, 2), NULL, 10);
66                         InReceives              = strtoull(procfile_lineword(ff, l, 3), NULL, 10);
67                         InHdrErrors             = strtoull(procfile_lineword(ff, l, 4), NULL, 10);
68                         InAddrErrors    = strtoull(procfile_lineword(ff, l, 5), NULL, 10);
69                         ForwDatagrams   = strtoull(procfile_lineword(ff, l, 6), NULL, 10);
70                         InUnknownProtos = strtoull(procfile_lineword(ff, l, 7), NULL, 10);
71                         InDiscards              = strtoull(procfile_lineword(ff, l, 8), NULL, 10);
72                         InDelivers              = strtoull(procfile_lineword(ff, l, 9), NULL, 10);
73                         OutRequests             = strtoull(procfile_lineword(ff, l, 10), NULL, 10);
74                         OutDiscards             = strtoull(procfile_lineword(ff, l, 11), NULL, 10);
75                         OutNoRoutes             = strtoull(procfile_lineword(ff, l, 12), NULL, 10);
76                         ReasmTimeout    = strtoull(procfile_lineword(ff, l, 13), NULL, 10);
77                         ReasmReqds              = strtoull(procfile_lineword(ff, l, 14), NULL, 10);
78                         ReasmOKs                = strtoull(procfile_lineword(ff, l, 15), NULL, 10);
79                         ReasmFails              = strtoull(procfile_lineword(ff, l, 16), NULL, 10);
80                         FragOKs                 = strtoull(procfile_lineword(ff, l, 17), NULL, 10);
81                         FragFails               = strtoull(procfile_lineword(ff, l, 18), NULL, 10);
82                         FragCreates             = strtoull(procfile_lineword(ff, l, 19), NULL, 10);
83                         
84                         // these are not counters
85                         if(Forwarding) {};              // is forwarding enabled?
86                         if(DefaultTTL) {};              // the default ttl on packets
87                         if(ReasmTimeout) {};    // reassemply timeout
88
89                         // this counter is not used
90                         if(InDelivers) {};              // total number of packets delivered to IP user-protcols
91
92                         // --------------------------------------------------------------------
93
94                         if(do_ip_packets) {
95                                 st = rrdset_find(RRD_TYPE_NET_SNMP ".packets");
96                                 if(!st) {
97                                         st = rrdset_create(RRD_TYPE_NET_SNMP, "packets", NULL, RRD_TYPE_NET_SNMP, "IPv4 Packets", "packets/s", 3000, update_every, RRDSET_TYPE_LINE);
98
99                                         rrddim_add(st, "received", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
100                                         rrddim_add(st, "sent", NULL, -1, 1 * update_every, RRDDIM_INCREMENTAL);
101                                         rrddim_add(st, "forwarded", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
102                                 }
103                                 else rrdset_next(st);
104
105                                 rrddim_set(st, "sent", OutRequests);
106                                 rrddim_set(st, "received", InReceives);
107                                 rrddim_set(st, "forwarded", ForwDatagrams);
108                                 rrdset_done(st);
109                         }
110
111                         // --------------------------------------------------------------------
112
113                         if(do_ip_fragsout) {
114                                 st = rrdset_find(RRD_TYPE_NET_SNMP ".fragsout");
115                                 if(!st) {
116                                         st = rrdset_create(RRD_TYPE_NET_SNMP, "fragsout", NULL, RRD_TYPE_NET_SNMP, "IPv4 Fragments Sent", "packets/s", 3010, update_every, RRDSET_TYPE_LINE);
117                                         st->isdetail = 1;
118
119                                         rrddim_add(st, "ok", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
120                                         rrddim_add(st, "failed", NULL, -1, 1 * update_every, RRDDIM_INCREMENTAL);
121                                         rrddim_add(st, "all", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
122                                 }
123                                 else rrdset_next(st);
124
125                                 rrddim_set(st, "ok", FragOKs);
126                                 rrddim_set(st, "failed", FragFails);
127                                 rrddim_set(st, "all", FragCreates);
128                                 rrdset_done(st);
129                         }
130
131                         // --------------------------------------------------------------------
132
133                         if(do_ip_fragsin) {
134                                 st = rrdset_find(RRD_TYPE_NET_SNMP ".fragsin");
135                                 if(!st) {
136                                         st = rrdset_create(RRD_TYPE_NET_SNMP, "fragsin", NULL, RRD_TYPE_NET_SNMP, "IPv4 Fragments Reassembly", "packets/s", 3011, update_every, RRDSET_TYPE_LINE);
137                                         st->isdetail = 1;
138
139                                         rrddim_add(st, "ok", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
140                                         rrddim_add(st, "failed", NULL, -1, 1 * update_every, RRDDIM_INCREMENTAL);
141                                         rrddim_add(st, "all", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
142                                 }
143                                 else rrdset_next(st);
144
145                                 rrddim_set(st, "ok", ReasmOKs);
146                                 rrddim_set(st, "failed", ReasmFails);
147                                 rrddim_set(st, "all", ReasmReqds);
148                                 rrdset_done(st);
149                         }
150
151                         // --------------------------------------------------------------------
152
153                         if(do_ip_errors) {
154                                 st = rrdset_find(RRD_TYPE_NET_SNMP ".errors");
155                                 if(!st) {
156                                         st = rrdset_create(RRD_TYPE_NET_SNMP, "errors", NULL, RRD_TYPE_NET_SNMP, "IPv4 Errors", "packets/s", 3002, update_every, RRDSET_TYPE_LINE);
157                                         st->isdetail = 1;
158
159                                         rrddim_add(st, "InDiscards", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
160                                         rrddim_add(st, "OutDiscards", NULL, -1, 1 * update_every, RRDDIM_INCREMENTAL);
161
162                                         rrddim_add(st, "InHdrErrors", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
163                                         rrddim_add(st, "InAddrErrors", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
164                                         rrddim_add(st, "InUnknownProtos", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
165
166                                         rrddim_add(st, "OutNoRoutes", NULL, -1, 1 * update_every, RRDDIM_INCREMENTAL);
167                                 }
168                                 else rrdset_next(st);
169
170                                 rrddim_set(st, "InDiscards", InDiscards);
171                                 rrddim_set(st, "OutDiscards", OutDiscards);
172                                 rrddim_set(st, "InHdrErrors", InHdrErrors);
173                                 rrddim_set(st, "InAddrErrors", InAddrErrors);
174                                 rrddim_set(st, "InUnknownProtos", InUnknownProtos);
175                                 rrddim_set(st, "OutNoRoutes", OutNoRoutes);
176                                 rrdset_done(st);
177                         }
178                 }
179                 else if(strcmp(procfile_lineword(ff, l, 0), "Tcp") == 0) {
180                         l++;
181
182                         if(strcmp(procfile_lineword(ff, l, 0), "Tcp") != 0) {
183                                 error("Cannot read Tcp line from /proc/net/snmp.");
184                                 break;
185                         }
186
187                         words = procfile_linewords(ff, l);
188                         if(words < 15) {
189                                 error("Cannot read /proc/net/snmp Tcp line. Expected 15 params, read %d.", words);
190                                 continue;
191                         }
192
193                         unsigned long long RtoAlgorithm, RtoMin, RtoMax, MaxConn, ActiveOpens, PassiveOpens, AttemptFails, EstabResets,
194                                 CurrEstab, InSegs, OutSegs, RetransSegs, InErrs, OutRsts;
195
196                         RtoAlgorithm    = strtoull(procfile_lineword(ff, l, 1), NULL, 10);
197                         RtoMin                  = strtoull(procfile_lineword(ff, l, 2), NULL, 10);
198                         RtoMax                  = strtoull(procfile_lineword(ff, l, 3), NULL, 10);
199                         MaxConn                 = strtoull(procfile_lineword(ff, l, 4), NULL, 10);
200                         ActiveOpens             = strtoull(procfile_lineword(ff, l, 5), NULL, 10);
201                         PassiveOpens    = strtoull(procfile_lineword(ff, l, 6), NULL, 10);
202                         AttemptFails    = strtoull(procfile_lineword(ff, l, 7), NULL, 10);
203                         EstabResets             = strtoull(procfile_lineword(ff, l, 8), NULL, 10);
204                         CurrEstab               = strtoull(procfile_lineword(ff, l, 9), NULL, 10);
205                         InSegs                  = strtoull(procfile_lineword(ff, l, 10), NULL, 10);
206                         OutSegs                 = strtoull(procfile_lineword(ff, l, 11), NULL, 10);
207                         RetransSegs             = strtoull(procfile_lineword(ff, l, 12), NULL, 10);
208                         InErrs                  = strtoull(procfile_lineword(ff, l, 13), NULL, 10);
209                         OutRsts                 = strtoull(procfile_lineword(ff, l, 14), NULL, 10);
210
211                         // these are not counters
212                         if(RtoAlgorithm) {};
213                         if(RtoMin) {};
214                         if(RtoMax) {};
215                         if(MaxConn) {};
216
217                         // --------------------------------------------------------------------
218                         
219                         // see http://net-snmp.sourceforge.net/docs/mibs/tcp.html
220                         if(do_tcp_sockets) {
221                                 st = rrdset_find(RRD_TYPE_NET_SNMP ".tcpsock");
222                                 if(!st) {
223                                         st = rrdset_create(RRD_TYPE_NET_SNMP, "tcpsock", NULL, "tcp", "IPv4 TCP Connections", "active connections", 2500, update_every, RRDSET_TYPE_LINE);
224
225                                         rrddim_add(st, "connections", NULL, 1, 1, RRDDIM_ABSOLUTE);
226                                 }
227                                 else rrdset_next(st);
228
229                                 rrddim_set(st, "connections", CurrEstab);
230                                 rrdset_done(st);
231                         }
232
233                         // --------------------------------------------------------------------
234                         
235                         if(do_tcp_packets) {
236                                 st = rrdset_find(RRD_TYPE_NET_SNMP ".tcppackets");
237                                 if(!st) {
238                                         st = rrdset_create(RRD_TYPE_NET_SNMP, "tcppackets", NULL, "tcp", "IPv4 TCP Packets", "packets/s", 2600, update_every, RRDSET_TYPE_LINE);
239
240                                         rrddim_add(st, "received", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
241                                         rrddim_add(st, "sent", NULL, -1, 1 * update_every, RRDDIM_INCREMENTAL);
242                                 }
243                                 else rrdset_next(st);
244
245                                 rrddim_set(st, "received", InSegs);
246                                 rrddim_set(st, "sent", OutSegs);
247                                 rrdset_done(st);
248                         }
249
250                         // --------------------------------------------------------------------
251                         
252                         if(do_tcp_errors) {
253                                 st = rrdset_find(RRD_TYPE_NET_SNMP ".tcperrors");
254                                 if(!st) {
255                                         st = rrdset_create(RRD_TYPE_NET_SNMP, "tcperrors", NULL, "tcp", "IPv4 TCP Errors", "packets/s", 2700, update_every, RRDSET_TYPE_LINE);
256                                         st->isdetail = 1;
257
258                                         rrddim_add(st, "InErrs", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
259                                         rrddim_add(st, "RetransSegs", NULL, -1, 1 * update_every, RRDDIM_INCREMENTAL);
260                                 }
261                                 else rrdset_next(st);
262
263                                 rrddim_set(st, "InErrs", InErrs);
264                                 rrddim_set(st, "RetransSegs", RetransSegs);
265                                 rrdset_done(st);
266                         }
267
268                         // --------------------------------------------------------------------
269                         
270                         if(do_tcp_handshake) {
271                                 st = rrdset_find(RRD_TYPE_NET_SNMP ".tcphandshake");
272                                 if(!st) {
273                                         st = rrdset_create(RRD_TYPE_NET_SNMP, "tcphandshake", NULL, "tcp", "IPv4 TCP Handshake Issues", "events/s", 2900, update_every, RRDSET_TYPE_LINE);
274                                         st->isdetail = 1;
275
276                                         rrddim_add(st, "EstabResets", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
277                                         rrddim_add(st, "OutRsts", NULL, -1, 1 * update_every, RRDDIM_INCREMENTAL);
278                                         rrddim_add(st, "ActiveOpens", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
279                                         rrddim_add(st, "PassiveOpens", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
280                                         rrddim_add(st, "AttemptFails", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
281                                 }
282                                 else rrdset_next(st);
283
284                                 rrddim_set(st, "EstabResets", EstabResets);
285                                 rrddim_set(st, "OutRsts", OutRsts);
286                                 rrddim_set(st, "ActiveOpens", ActiveOpens);
287                                 rrddim_set(st, "PassiveOpens", PassiveOpens);
288                                 rrddim_set(st, "AttemptFails", AttemptFails);
289                                 rrdset_done(st);
290                         }
291                 }
292                 else if(strcmp(procfile_lineword(ff, l, 0), "Udp") == 0) {
293                         l++;
294
295                         if(strcmp(procfile_lineword(ff, l, 0), "Udp") != 0) {
296                                 error("Cannot read Udp line from /proc/net/snmp.");
297                                 break;
298                         }
299
300                         words = procfile_linewords(ff, l);
301                         if(words < 7) {
302                                 error("Cannot read /proc/net/snmp Udp line. Expected 7 params, read %d.", words);
303                                 continue;
304                         }
305
306                         unsigned long long InDatagrams, NoPorts, InErrors, OutDatagrams, RcvbufErrors, SndbufErrors;
307
308                         InDatagrams             = strtoull(procfile_lineword(ff, l, 1), NULL, 10);
309                         NoPorts                 = strtoull(procfile_lineword(ff, l, 2), NULL, 10);
310                         InErrors                = strtoull(procfile_lineword(ff, l, 3), NULL, 10);
311                         OutDatagrams    = strtoull(procfile_lineword(ff, l, 4), NULL, 10);
312                         RcvbufErrors    = strtoull(procfile_lineword(ff, l, 5), NULL, 10);
313                         SndbufErrors    = strtoull(procfile_lineword(ff, l, 6), NULL, 10);
314
315                         // --------------------------------------------------------------------
316                         
317                         // see http://net-snmp.sourceforge.net/docs/mibs/udp.html
318                         if(do_udp_packets) {
319                                 st = rrdset_find(RRD_TYPE_NET_SNMP ".udppackets");
320                                 if(!st) {
321                                         st = rrdset_create(RRD_TYPE_NET_SNMP, "udppackets", NULL, "udp", "IPv4 UDP Packets", "packets/s", 2601, update_every, RRDSET_TYPE_LINE);
322
323                                         rrddim_add(st, "received", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
324                                         rrddim_add(st, "sent", NULL, -1, 1 * update_every, RRDDIM_INCREMENTAL);
325                                 }
326                                 else rrdset_next(st);
327
328                                 rrddim_set(st, "received", InDatagrams);
329                                 rrddim_set(st, "sent", OutDatagrams);
330                                 rrdset_done(st);
331                         }
332
333                         // --------------------------------------------------------------------
334                         
335                         if(do_udp_errors) {
336                                 st = rrdset_find(RRD_TYPE_NET_SNMP ".udperrors");
337                                 if(!st) {
338                                         st = rrdset_create(RRD_TYPE_NET_SNMP, "udperrors", NULL, "udp", "IPv4 UDP Errors", "events/s", 2701, update_every, RRDSET_TYPE_LINE);
339                                         st->isdetail = 1;
340
341                                         rrddim_add(st, "RcvbufErrors", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
342                                         rrddim_add(st, "SndbufErrors", NULL, -1, 1 * update_every, RRDDIM_INCREMENTAL);
343                                         rrddim_add(st, "InErrors", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
344                                         rrddim_add(st, "NoPorts", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
345                                 }
346                                 else rrdset_next(st);
347
348                                 rrddim_set(st, "InErrors", InErrors);
349                                 rrddim_set(st, "NoPorts", NoPorts);
350                                 rrddim_set(st, "RcvbufErrors", RcvbufErrors);
351                                 rrddim_set(st, "SndbufErrors", SndbufErrors);
352                                 rrdset_done(st);
353                         }
354                 }
355         }
356         
357         return 0;
358 }
359