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