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: