@cryptotaxi247 / netdata-1 / commits / 8a870a65d

update nfacct plugin to match current netdata development

Costa Tsaousis (ktsaou) committed Mar 17, 2017 at 00:03 UTC 8a870a65d0afc49455b4b5ff2b0ce585e0bd8339
3 files changed +116 -54
configure.ac
+2 -2
@@ -51,11 +51,11 @@ AC_ARG_ENABLE(
51 [plugin-nfacct],
52 [AS_HELP_STRING([--enable-plugin-nfacct], [enable nfacct plugin, requires root])],
53 ,
54 - [enable_plugin_nfacct="no"]
54 + [enable_plugin_nfacct="detect"]
55 )
56 AC_ARG_ENABLE(
57 [plugin-freeipmi],
58 - [AS_HELP_STRING([--enable-plugin-freeipmi], [freeipmi plugin, requires root])],
58 + [AS_HELP_STRING([--enable-plugin-freeipmi], [enable freeipmi plugin])],
59 ,
60 [enable_plugin_freeipmi="detect"]
61 )
netdata-installer.sh
+14
@@ -104,6 +104,12 @@ Valid <installer options> are:
104 Enable/disable the FreeIPMI plugin.
105 Default: enable it when libipmimonitoring is available.
106
107 + --enable-plugin-nfacct
108 + --disable-plugin-nfacct
109 +
110 + Enable/disable the nfacct plugin.
111 + Default: enable it when libmnl and libnetfilter_acct are available.
112 +
113 --enable-lto
114 --disable-lto
115
@@ -205,6 +211,14 @@ do
211 then
212 NETDATA_CONFIGURE_OPTIONS="${NETDATA_CONFIGURE_OPTIONS} --disable-plugin-freeipmi"
213 shift 1
214 + elif [ "$1" = "--enable-plugin-nfacct" ]
215 + then
216 + NETDATA_CONFIGURE_OPTIONS="${NETDATA_CONFIGURE_OPTIONS} --enable-plugin-nfacct"
217 + shift 1
218 + elif [ "$1" = "--disable-plugin-nfacct" ]
219 + then
220 + NETDATA_CONFIGURE_OPTIONS="${NETDATA_CONFIGURE_OPTIONS} --disable-plugin-nfacct"
221 + shift 1
222 elif [ "$1" = "--enable-lto" ]
223 then
224 NETDATA_CONFIGURE_OPTIONS="${NETDATA_CONFIGURE_OPTIONS} --enable-lto"
src/plugin_nfacct.c
+100 -52
@@ -8,6 +8,12 @@ struct mynfacct {
8 const char *name;
9 uint64_t pkts;
10 uint64_t bytes;
11 +
12 + RRDDIM *rd_bytes;
13 + RRDDIM *rd_packets;
14 +
15 + int updated;
16 +
17 struct nfacct *nfacct;
18 };
19
@@ -18,7 +24,7 @@ struct nfacct_list {
24 } *nfacct_list = NULL;
25
26 static int nfacct_callback(const struct nlmsghdr *nlh, void *data) {
21 - if(data) {};
27 + (void)data;
28
29 if(!nfacct_list || nfacct_list->len == nfacct_list->size) {
30 int size = (nfacct_list) ? nfacct_list->size : 0;
@@ -30,13 +36,17 @@ static int nfacct_callback(const struct nlmsghdr *nlh, void *data) {
36 nfacct_list = reallocz(nfacct_list, sizeof(struct nfacct_list) + (sizeof(struct mynfacct) * size));
37
38 nfacct_list->data[len].nfacct = nfacct_alloc();
33 - if(!nfacct_list->data[size - 1].nfacct) {
39 + if(!nfacct_list->data[len].nfacct) {
40 error("nfacct.plugin: nfacct_alloc() failed.");
41 free(nfacct_list);
42 nfacct_list = NULL;
43 return MNL_CB_OK;
44 }
45
46 + nfacct_list->data[len].rd_bytes = NULL;
47 + nfacct_list->data[len].rd_packets = NULL;
48 + nfacct_list->data[len].updated = 0;
49 +
50 nfacct_list->size = size;
51 nfacct_list->len = len;
52 }
@@ -49,6 +59,7 @@ static int nfacct_callback(const struct nlmsghdr *nlh, void *data) {
59 nfacct_list->data[nfacct_list->len].name = nfacct_attr_get_str(nfacct_list->data[nfacct_list->len].nfacct, NFACCT_ATTR_NAME);
60 nfacct_list->data[nfacct_list->len].pkts = nfacct_attr_get_u64(nfacct_list->data[nfacct_list->len].nfacct, NFACCT_ATTR_PKTS);
61 nfacct_list->data[nfacct_list->len].bytes = nfacct_attr_get_u64(nfacct_list->data[nfacct_list->len].nfacct, NFACCT_ATTR_BYTES);
62 + nfacct_list->data[nfacct_list->len].updated = 1;
63
64 nfacct_list->len++;
65 return MNL_CB_OK;
@@ -70,7 +81,7 @@ void *nfacct_main(void *ptr) {
81 struct nlmsghdr *nlh = NULL;
82 unsigned int seq = 0, portid = 0;
83
73 - seq = now_realtime_sec() - 1;
84 + seq = (unsigned int)now_realtime_sec() - 1;
85
86 nl = mnl_socket_open(NETLINK_NETFILTER);
87 if(!nl) {
@@ -86,20 +97,26 @@ void *nfacct_main(void *ptr) {
97
98 // ------------------------------------------------------------------------
99
89 - struct timeval last, now;
90 - usec_t usec = 0, susec = 0;
91 - RRDSET *st = NULL;
92 -
93 - now_realtime_timeval(&last);
100 + RRDSET *st_bytes = NULL, *st_packets = NULL;
101
102 // ------------------------------------------------------------------------
103
97 - while(1) {
104 + int update_every = (int)config_get_number("plugin:nfacct", "update every", localhost->rrd_update_every);
105 + if(update_every < localhost->rrd_update_every)
106 + update_every = localhost->rrd_update_every;
107 +
108 + usec_t step = update_every * USEC_PER_SEC;
109 + heartbeat_t hb;
110 + heartbeat_init(&hb);
111 + for(;;) {
112 + heartbeat_dt_usec(&hb);
113 + heartbeat_next(&hb, step);
114 +
115 if(unlikely(netdata_exit)) break;
116
117 seq++;
118
102 - nlh = nfacct_nlmsg_build_hdr(buf, NFNL_MSG_ACCT_GET, NLM_F_DUMP, seq);
119 + nlh = nfacct_nlmsg_build_hdr(buf, NFNL_MSG_ACCT_GET, NLM_F_DUMP, (uint32_t)seq);
120 if(!nlh) {
121 error("nfacct.plugin: nfacct_nlmsg_build_hdr() failed");
122 goto cleanup;
@@ -112,76 +129,107 @@ void *nfacct_main(void *ptr) {
129
130 if(nfacct_list) nfacct_list->len = 0;
131
115 - int ret;
132 + ssize_t ret;
133 while((ret = mnl_socket_recvfrom(nl, buf, sizeof(buf))) > 0) {
117 - if((ret = mnl_cb_run(buf, ret, seq, portid, nfacct_callback, NULL)) <= 0) break;
134 + if((ret = mnl_cb_run(buf, (size_t)ret, seq, portid, nfacct_callback, NULL)) <= 0) break;
135 }
136
137 if (ret == -1) {
121 - error("nfacct.plugin: error communicating with kernel.");
138 + error("nfacct.plugin: error communicating with kernel. NFACCT plugin can only work when netdata runs as root.");
139 goto cleanup;
140 }
141
125 - // --------------------------------------------------------------------
126 -
127 - now_realtime_timeval(&now);
128 - usec = dt_usec(&now, &last) - susec;
129 - debug(D_NFACCT_LOOP, "nfacct.plugin: last loop took %llu usec (worked for %llu, sleeped for %llu).", usec + susec, usec, susec);
130 -
131 - if(usec < (default_rrd_update_every * 1000000ULL / 2ULL)) susec = (default_rrd_update_every * 1000000ULL) - usec;
132 - else susec = default_rrd_update_every * 1000000ULL / 2ULL;
133 -
134 -
142 // --------------------------------------------------------------------
143
144 if(nfacct_list && nfacct_list->len) {
145 int i;
146
140 - st = rrdset_find_bytype("netfilter", "nfacct_packets");
141 - if(!st) {
142 - st = rrdset_create("netfilter", "nfacct_packets", NULL, "nfacct", NULL, "Netfilter Accounting Packets", "packets/s", 3206, default_rrd_update_every, RRDSET_TYPE_STACKED);
143 -
144 - for(i = 0; i < nfacct_list->len ; i++)
145 - rrddim_add(st, nfacct_list->data[i].name, NULL, 1, default_rrd_update_every, RRD_ALGORITHM_INCREMENTAL);
147 + if(!st_packets) {
148 + st_packets = rrdset_create_localhost(
149 + "netfilter"
150 + , "nfacct_packets"
151 + , NULL
152 + , "nfacct"
153 + , NULL
154 + , "Netfilter Accounting Packets"
155 + , "packets/s"
156 + , 3206
157 + , update_every
158 + , RRDSET_TYPE_STACKED
159 + );
160 }
147 - else rrdset_next(st);
161 + else rrdset_next(st_packets);
162
163 for(i = 0; i < nfacct_list->len ; i++) {
150 - RRDDIM *rd = rrddim_find(st, nfacct_list->data[i].name);
151 -
152 - if(!rd) rd = rrddim_add(st, nfacct_list->data[i].name, NULL, 1, default_rrd_update_every, RRD_ALGORITHM_INCREMENTAL);
153 - if(rd) rrddim_set_by_pointer(st, rd, nfacct_list->data[i].pkts);
164 + if(nfacct_list->data[i].updated) {
165 + if(unlikely(!nfacct_list->data[i].rd_packets))
166 + nfacct_list->data[i].rd_packets = rrddim_add(
167 + st_packets
168 + , nfacct_list->data[i].name
169 + , NULL
170 + , 1
171 + , update_every
172 + , RRD_ALGORITHM_INCREMENTAL
173 + );
174 +
175 + rrddim_set_by_pointer(
176 + st_packets
177 + , nfacct_list->data[i].rd_packets
178 + , (collected_number)nfacct_list->data[i].pkts
179 + );
180 + }
181 }
182
156 - rrdset_done(st);
183 + rrdset_done(st_packets);
184
185 // ----------------------------------------------------------------
186
160 - st = rrdset_find_bytype("netfilter", "nfacct_bytes");
161 - if(!st) {
162 - st = rrdset_create("netfilter", "nfacct_bytes", NULL, "nfacct", NULL, "Netfilter Accounting Bandwidth", "kilobytes/s", 3207, default_rrd_update_every, RRDSET_TYPE_STACKED);
163 -
164 - for(i = 0; i < nfacct_list->len ; i++)
165 - rrddim_add(st, nfacct_list->data[i].name, NULL, 1, 1000 * default_rrd_update_every, RRD_ALGORITHM_INCREMENTAL);
187 + st_bytes = rrdset_find_bytype_localhost("netfilter", "nfacct_bytes");
188 + if(!st_bytes) {
189 + st_bytes = rrdset_create_localhost(
190 + "netfilter"
191 + , "nfacct_bytes"
192 + , NULL
193 + , "nfacct"
194 + , NULL
195 + , "Netfilter Accounting Bandwidth"
196 + , "kilobytes/s"
197 + , 3207
198 + , update_every
199 + , RRDSET_TYPE_STACKED
200 + );
201 }
167 - else rrdset_next(st);
202 + else rrdset_next(st_bytes);
203
204 for(i = 0; i < nfacct_list->len ; i++) {
170 - RRDDIM *rd = rrddim_find(st, nfacct_list->data[i].name);
171 -
172 - if(!rd) rd = rrddim_add(st, nfacct_list->data[i].name, NULL, 1, 1000 * default_rrd_update_every, RRD_ALGORITHM_INCREMENTAL);
173 - if(rd) rrddim_set_by_pointer(st, rd, nfacct_list->data[i].bytes);
205 + if(nfacct_list->data[i].updated) {
206 + if(unlikely(!nfacct_list->data[i].rd_bytes))
207 + nfacct_list->data[i].rd_bytes = rrddim_add(
208 + st_bytes
209 + , nfacct_list->data[i].name
210 + , NULL
211 + , 1
212 + , 1000 * update_every
213 + , RRD_ALGORITHM_INCREMENTAL
214 + );
215 +
216 + rrddim_set_by_pointer(
217 + st_bytes
218 + , nfacct_list->data[i].rd_bytes
219 + , (collected_number)nfacct_list->data[i].bytes
220 + );
221 + }
222 }
223
176 - rrdset_done(st);
177 - }
224 + rrdset_done(st_bytes);
225
179 - // --------------------------------------------------------------------
226
181 - usleep(susec);
227 + // ----------------------------------------------------------------
228 + // prepare for the next loop
229
183 - // copy current to last
184 - memmove(&last, &now, sizeof(struct timeval));
230 + for(i = 0; i < nfacct_list->len ; i++)
231 + nfacct_list->data[i].updated = 0;
232 + }
233 }
234
235 cleanup: