@cryptotaxi247 / netdata-1 / commits / ea0e0f8f5

Split nfacct plugin into separate process (#5361)

* Prepare build configuration * Prepare plugin for separating * Add command line options * Add debug messages * Use text API * Minor fixes * Update the documentation * Minor documentation formatting * Fix LGTM alerts * Fix building with CMake * Add nfacct and cups plugins to apps.plugin groups

Vladimir Kobal committed Feb 13, 2019 at 11:34 UTC ea0e0f8f5ea44c0f5f5b4aadffede1c1b43b7d1e
15 files changed +490 -383
.gitignore
+3
@@ -50,6 +50,9 @@ freeipmi.plugin
50 cups.plugin
51 !cups.plugin/
52
53 +nfacct.plugin
54 +!nfacct.plugin/
55 +
56 cgroup-network
57 !cgroup-network/
58
CMakeLists.txt
+27 -25
@@ -248,7 +248,6 @@ set(FREEIPMI_PLUGIN_FILES
248
249 set(NFACCT_PLUGIN_FILES
250 collectors/nfacct.plugin/plugin_nfacct.c
251 - collectors/nfacct.plugin/plugin_nfacct.h
251 )
252
253 set(PROC_PLUGIN_FILES
@@ -458,13 +457,6 @@ set(NETDATA_FILES
457 ${WEB_PLUGIN_FILES}
458 )
459
461 -IF(LINUX AND MNL_LIBRARIES AND NFACCT_LIBRARIES)
462 - message(STATUS "nfacct.plugin: enabled (will work only if netdata runs as root)")
463 - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DINTERNAL_PLUGIN_NFACCT=1")
464 -ELSE()
465 - message(STATUS "nfacct.plugin: disabled (requires libmnl and libnetfilter_acct)")
466 -ENDIF()
467 -
460 include_directories(AFTER .)
461
462 add_definitions(
@@ -488,22 +480,12 @@ IF(LINUX)
480 add_executable(netdata config.h ${NETDATA_FILES}
481 ${CGROUPS_PLUGIN_FILES}
482 ${DISKSPACE_PLUGIN_FILES}
491 - ${NFACCT_PLUGIN_FILES}
483 ${PROC_PLUGIN_FILES}
484 ${TC_PLUGIN_FILES}
485 )
495 - target_link_libraries (netdata libnetdata ${NETDATA_COMMON_LIBRARIES}
496 - ${MNL_LIBRARIES}
497 - ${NFACCT_LIBRARIES}
498 - )
499 - target_include_directories(netdata PUBLIC ${NETDATA_COMMON_INCLUDE_DIRS}
500 - ${MNL_INCLUDE_DIRS}
501 - ${NFACCT_INCLUDE_DIRS}
502 - )
503 - target_compile_options(netdata PUBLIC ${NETDATA_COMMON_CFLAGS}
504 - ${MNL_CFLAGS_OTHER}
505 - ${NFACCT_CFLAGS_OTHER}
506 - )
486 + target_link_libraries (netdata libnetdata ${NETDATA_COMMON_LIBRARIES})
487 + target_include_directories(netdata PUBLIC ${NETDATA_COMMON_INCLUDE_DIRS})
488 + target_compile_options(netdata PUBLIC ${NETDATA_COMMON_CFLAGS})
489
490 SET(ENABLE_PLUGIN_CGROUP_NETWORK True)
491 SET(ENABLE_PLUGIN_APPS True)
@@ -532,6 +514,12 @@ ELSE()
514 SET(ENABLE_PLUGIN_FREEIPMI False)
515 ENDIF()
516
517 +IF(LINUX AND MNL_LIBRARIES AND NFACCT_LIBRARIES)
518 + SET(ENABLE_PLUGIN_NFACCT True)
519 +ELSE()
520 + SET(ENABLE_PLUGIN_NFACCT False)
521 +ENDIF()
522 +
523
524 # -----------------------------------------------------------------------------
525 # apps.plugin
@@ -554,13 +542,27 @@ IF(ENABLE_PLUGIN_FREEIPMI)
542 message(STATUS "freeipmi.plugin: enabled")
543 add_executable(freeipmi.plugin config.h ${FREEIPMI_PLUGIN_FILES})
544 target_link_libraries (freeipmi.plugin libnetdata ${NETDATA_COMMON_LIBRARIES} ${IPMI_LIBRARIES})
557 - target_include_directories(apps.plugin PUBLIC ${NETDATA_COMMON_INCLUDE_DIRS} ${IPMI_INCLUDE_DIRS})
558 - target_compile_options(apps.plugin PUBLIC ${NETDATA_COMMON_CFLAGS} ${IPMI_CFLAGS_OTHER})
545 + target_include_directories(freeipmi.plugin PUBLIC ${NETDATA_COMMON_INCLUDE_DIRS} ${IPMI_INCLUDE_DIRS})
546 + target_compile_options(freeipmi.plugin PUBLIC ${NETDATA_COMMON_CFLAGS} ${IPMI_CFLAGS_OTHER})
547 ELSE()
548 message(STATUS "freeipmi.plugin: disabled (depends on libipmimonitoring)")
549 ENDIF()
550
551
552 +# -----------------------------------------------------------------------------
553 +# nfacct.plugin
554 +
555 +IF(ENABLE_PLUGIN_NFACCT)
556 + message(STATUS "nfacct.plugin: enabled")
557 + add_executable(nfacct.plugin config.h ${NFACCT_PLUGIN_FILES})
558 + target_link_libraries (nfacct.plugin libnetdata ${NETDATA_COMMON_LIBRARIES} ${MNL_LIBRARIES} ${NFACCT_LIBRARIES})
559 + target_include_directories(nfacct.plugin PUBLIC ${NETDATA_COMMON_INCLUDE_DIRS} ${MNL_INCLUDE_DIRS} ${NFACCT_INCLUDE_DIRS})
560 + target_compile_options(nfacct.plugin PUBLIC ${NETDATA_COMMON_CFLAGS} ${MNL_CFLAGS_OTHER} ${NFACCT_CFLAGS_OTHER})
561 +ELSE()
562 + message(STATUS "nfacct.plugin: disabled (requires libmnl and libnetfilter_acct)")
563 +ENDIF()
564 +
565 +
566 # -----------------------------------------------------------------------------
567 # cgroup-network
568
@@ -568,8 +570,8 @@ IF(ENABLE_PLUGIN_CGROUP_NETWORK)
570 message(STATUS "cgroup-network: enabled")
571 add_executable(cgroup-network config.h ${CGROUP_NETWORK_FILES})
572 target_link_libraries (cgroup-network libnetdata ${NETDATA_COMMON_LIBRARIES})
571 - target_include_directories(apps.plugin PUBLIC ${NETDATA_COMMON_INCLUDE_DIRS})
572 - target_compile_options(apps.plugin PUBLIC ${NETDATA_COMMON_CFLAGS})
573 + target_include_directories(cgroup-network PUBLIC ${NETDATA_COMMON_INCLUDE_DIRS})
574 + target_compile_options(cgroup-network PUBLIC ${NETDATA_COMMON_CFLAGS})
575 ELSE()
576 message(STATUS "cgroup-network: disabled (requires Linux)")
577 ENDIF()
Makefile.am
+10 -3
@@ -221,7 +221,7 @@ CUPS_PLUGIN_FILES = \
221
222 NFACCT_PLUGIN_FILES = \
223 collectors/nfacct.plugin/plugin_nfacct.c \
224 - collectors/nfacct.plugin/plugin_nfacct.h \
224 + $(LIBNETDATA_FILES) \
225 $(NULL)
226
227 PROC_PLUGIN_FILES = \
@@ -449,7 +449,6 @@ if LINUX
449 NETDATA_FILES += \
450 $(CGROUPS_PLUGIN_FILES) \
451 $(DISKSPACE_PLUGIN_FILES) \
452 - $(NFACCT_PLUGIN_FILES) \
452 $(PROC_PLUGIN_FILES) \
453 $(TC_PLUGIN_FILES) \
454 $(NULL)
@@ -467,7 +466,6 @@ sbin_PROGRAMS += netdata
466 netdata_SOURCES = $(NETDATA_FILES)
467 netdata_LDADD = \
468 $(NETDATA_COMMON_LIBS) \
470 - $(OPTIONAL_NFACCT_LIBS) \
469 $(NULL)
470
471 if ENABLE_PLUGIN_APPS
@@ -504,3 +502,12 @@ if ENABLE_PLUGIN_CUPS
502 $(OPTIONAL_CUPS_LIBS) \
503 $(NULL)
504 endif
505 +
506 +if ENABLE_PLUGIN_NFACCT
507 + plugins_PROGRAMS += nfacct.plugin
508 + nfacct_plugin_SOURCES = $(NFACCT_PLUGIN_FILES)
509 + nfacct_plugin_LDADD = \
510 + $(NETDATA_COMMON_LIBS) \
511 + $(OPTIONAL_NFACCT_LIBS) \
512 + $(NULL)
513 +endif
collectors/README.md
+9 -9
@@ -13,7 +13,7 @@ To minimize the number of processes spawn for data collection, netdata also supp
13 Instead they support data collection **modules** written in the language of the orchestrator.
14 Usually the orchestrator provides a higher level abstraction, making it ideal for writing new
15 data collection modules with the minimum of code.
16 -
16 +
17 Currently netdata provides plugin orchestrators
18 BASH v4+ [charts.d.plugin](charts.d.plugin/),
19 node.js [node.d.plugin](node.d.plugin/) and
@@ -34,7 +34,7 @@ plugin|lang|O/S|runs as|modular|description
34 [freeipmi.plugin](freeipmi.plugin/)|`C`|linux, freebsd|external|-|collects metrics from enterprise hardware sensors, on Linux and FreeBSD servers.
35 [idlejitter.plugin](idlejitter.plugin/)|`C`|any|internal|-|measures CPU latency and jitter on all operating systems
36 [macos.plugin](macos.plugin/)|`C`|macos|internal|yes|collects resource usage and performance data on MacOS systems
37 -[nfacct.plugin](nfacct.plugin/)|`C`|linux|internal|-|collects netfilter firewall, connection tracker and accounting metrics using `libmnl` and `libnetfilter_acct`
37 +[nfacct.plugin](nfacct.plugin/)|`C`|linux|external|-|collects netfilter firewall, connection tracker and accounting metrics using `libmnl` and `libnetfilter_acct`
38 [node.d.plugin](node.d.plugin/)|`node.js`|any|external|yes|a **plugin orchestrator** for data collection modules written in `node.js`.
39 [plugins.d](plugins.d/)|`C`|any|internal|-|implements the **external plugins** API and serves external plugins
40 [proc.plugin](proc.plugin/)|`C`|linux|internal|yes|collects resource usage and performance data on Linux systems
@@ -46,7 +46,7 @@ plugin|lang|O/S|runs as|modular|description
46
47 Each plugin can be enabled or disabled via `netdata.conf`, section `[plugins]`.
48
49 -At this section there a list of all the plugins with a boolean setting to enable them or disable them.
49 +At this section there a list of all the plugins with a boolean setting to enable them or disable them.
50
51 The exception is `statsd.plugin` that has its own `[statsd]` section.
52
@@ -66,14 +66,14 @@ The internal data collection API consists of the following calls:
66 ```c
67 collect_data() {
68 // collect data here (one iteration)
69 -
69 +
70 collected_number collected_value = collect_a_value();
71 -
71 +
72 // give the metrics to netdata
73 -
73 +
74 static RRDSET *st = NULL; // the chart
75 static RRDDIM *rd = NULL; // a dimension attached to this chart
76 -
76 +
77 if(unlikely(!st)) {
78 // we haven't created this chart before
79 // create it now
@@ -100,10 +100,10 @@ collect_data() {
100 // let netdata know we start a new iteration on it
101 rrdset_next(st);
102 }
103 -
103 +
104 // give the collected value(s) to the chart
105 rrddim_set_by_pointer(st, rd, collected_value);
106 -
106 +
107 // signal netdata we are done with this iteration
108 rrdset_done(st);
109 }
collectors/all.h
-4
@@ -12,7 +12,6 @@
12 #include "idlejitter.plugin/plugin_idlejitter.h"
13 #include "cgroups.plugin/sys_fs_cgroup.h"
14 #include "diskspace.plugin/plugin_diskspace.h"
15 -#include "nfacct.plugin/plugin_nfacct.h"
15 #include "proc.plugin/plugin_proc.h"
16 #include "tc.plugin/plugin_tc.h"
17 #include "macos.plugin/plugin_macos.h"
@@ -288,9 +287,6 @@
287 #define NETDATA_CHART_PRIO_NETFILTER_ERRORS 8705
288 #define NETDATA_CHART_PRIO_NETFILTER_SEARCH 8710
289
291 -#define NETDATA_CHART_PRIO_NETFILTER_PACKETS 8906
292 -#define NETDATA_CHART_PRIO_NETFILTER_BYTES 8907
293 -
290 // SYNPROXY
291
292 #define NETDATA_CHART_PRIO_SYNPROXY_SYN_RECEIVED 8751
collectors/apps.plugin/apps_groups.conf
+2
@@ -74,6 +74,8 @@ netdata: netdata
74 # plugins not defined here will be accumulated in netdata, above
75 apps.plugin: apps.plugin
76 freeipmi.plugin: freeipmi.plugin
77 +nfacct.plugin: nfacct.plugin
78 +cups.plugin: cups.plugin
79 charts.d.plugin: *charts.d.plugin*
80 node.d.plugin: *node.d.plugin*
81 python.d.plugin: *python.d.plugin*
collectors/nfacct.plugin/README.md
+41 -6
@@ -1,12 +1,47 @@
1 # nfacct.plugin
2
3 -This plugin that collects NFACCT statistics.
3 +`nfacct.plugin` collects Netfilter statistics.
4
5 -It is currently disabled by default, because it requires root access.
6 -We have to move the code to an external plugin to setuid just the plugin not the whole netdata server.
5 +## Prerequisites
6
8 -You can build netdata with it to test it though.
9 -Just run `./configure` (or `netdata-installer.sh`) with the option `--enable-plugin-nfacct` (and any other options you may need).
10 -Remember, you have to tell netdata you want it to run as `root` for this plugin to work.
7 +1. install `libmnl-dev` and `libnetfilter_acct-dev` using the package manager of your system.
8 +
9 +2. re-install netdata from source. The installer will detect that the required libraries are now available and will also build netdata.plugin.
10 +
11 +Keep in mind that NFACCT requires root access, so the plugin is setuid to root.
12 +
13 +## Charts
14 +
15 +The plugin provides Netfilter connection tracker statistics and nfacct packet and bandwidth accounting:
16 +
17 +Connection tracker:
18 +1. Connections.
19 +2. Changes.
20 +3. Expectations.
21 +4. Errors.
22 +5. Searches.
23 +
24 +Netfilter accounting:
25 +1. Packets.
26 +2. Bandwidth.
27 +
28 +## Configuration
29 +
30 +If you need to disable NFACCT for netdata, edit /etc/netdata/netdata.conf and set:
31 +
32 +```
33 +[plugins]
34 + nfacct = no
35 +```
36 +
37 +## Debugging
38 +
39 +You can run the plugin by hand:
40 +
41 +```
42 +sudo /usr/libexec/netdata/plugins.d/nfacct.plugin 1 debug
43 +```
44 +
45 +You will get verbose output on what the plugin does.
46
47 [![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fnfacct.plugin%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)]()
collectors/nfacct.plugin/plugin_nfacct.c
+382 -295
@@ -1,11 +1,18 @@
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 -#include "plugin_nfacct.h"
4 -
5 -#if defined(INTERNAL_PLUGIN_NFACCT)
3 +#include "../../libnetdata/libnetdata.h"
4
5 #define PLUGIN_NFACCT_NAME "nfacct.plugin"
6
7 +#define NETDATA_CHART_PRIO_NETFILTER_NEW 8701
8 +#define NETDATA_CHART_PRIO_NETFILTER_CHANGES 8702
9 +#define NETDATA_CHART_PRIO_NETFILTER_EXPECT 8703
10 +#define NETDATA_CHART_PRIO_NETFILTER_ERRORS 8705
11 +#define NETDATA_CHART_PRIO_NETFILTER_SEARCH 8710
12 +
13 +#define NETDATA_CHART_PRIO_NETFILTER_PACKETS 8906
14 +#define NETDATA_CHART_PRIO_NETFILTER_BYTES 8907
15 +
16 #ifdef HAVE_LIBMNL
17 #include <libmnl/libmnl.h>
18
@@ -15,6 +22,41 @@ static inline size_t mnl_buffer_size() {
22 return (size_t)s;
23 }
24
25 +// callback required by fatal()
26 +void netdata_cleanup_and_exit(int ret) {
27 + exit(ret);
28 +}
29 +
30 +void send_statistics( const char *action, const char *action_result, const char *action_data) {
31 + (void) action;
32 + (void) action_result;
33 + (void) action_data;
34 + return;
35 +}
36 +
37 +// callbacks required by popen()
38 +void signals_block(void) {};
39 +void signals_unblock(void) {};
40 +void signals_reset(void) {};
41 +
42 +// callback required by eval()
43 +int health_variable_lookup(const char *variable, uint32_t hash, struct rrdcalc *rc, calculated_number *result) {
44 + (void)variable;
45 + (void)hash;
46 + (void)rc;
47 + (void)result;
48 + return 0;
49 +};
50 +
51 +// required by get_system_cpus()
52 +char *netdata_configured_host_prefix = "";
53 +
54 +// Variables
55 +
56 +static int debug = 0;
57 +
58 +static int netdata_update_every = 1;
59 +
60 // ----------------------------------------------------------------------------
61 // DO_NFSTAT - collect netfilter connection tracker statistics via netlink
62 // example: https://github.com/formorer/pkg-conntrack-tools/blob/master/src/conntrack.c
@@ -103,17 +145,6 @@ static int nfstat_init(int update_every) {
145 return 0;
146 }
147
106 -static void nfstat_cleanup() {
107 - if(nfstat_root.mnl) {
108 - mnl_socket_close(nfstat_root.mnl);
109 - nfstat_root.mnl = NULL;
110 - }
111 -
112 - freez(nfstat_root.buf);
113 - nfstat_root.buf = NULL;
114 - nfstat_root.buf_size = 0;
115 -}
116 -
148 static struct nlmsghdr * nfct_mnl_nlmsghdr_put(char *buf, uint16_t subsys, uint16_t type, uint8_t family, uint32_t seq) {
149 struct nlmsghdr *nlh;
150 struct nfgenmsg *nfh;
@@ -292,191 +323,211 @@ static int nfstat_collect() {
323 }
324
325 static void nfstat_send_metrics() {
295 -
296 - {
297 - static RRDSET *st_new = NULL;
298 - static RRDDIM *rd_new = NULL, *rd_ignore = NULL, *rd_invalid = NULL;
299 -
300 - if(!st_new) {
301 - st_new = rrdset_create_localhost(
302 - RRD_TYPE_NET_STAT_NETFILTER
303 - , RRD_TYPE_NET_STAT_CONNTRACK "_new"
304 - , NULL
305 - , RRD_TYPE_NET_STAT_CONNTRACK
306 - , NULL
307 - , "Connection Tracker New Connections"
308 - , "connections/s"
309 - , PLUGIN_NFACCT_NAME
310 - , NULL
311 - , NETDATA_CHART_PRIO_NETFILTER_NEW
312 - , nfstat_root.update_every
313 - , RRDSET_TYPE_LINE
314 - );
315 -
316 - rd_new = rrddim_add(st_new, nfstat_root.attr2name[CTA_STATS_NEW], NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
317 - rd_ignore = rrddim_add(st_new, nfstat_root.attr2name[CTA_STATS_IGNORE], NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
318 - rd_invalid = rrddim_add(st_new, nfstat_root.attr2name[CTA_STATS_INVALID], NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
319 - }
320 - else
321 - rrdset_next(st_new);
322 -
323 - rrddim_set_by_pointer(st_new, rd_new, (collected_number) nfstat_root.metrics[CTA_STATS_NEW]);
324 - rrddim_set_by_pointer(st_new, rd_ignore, (collected_number) nfstat_root.metrics[CTA_STATS_IGNORE]);
325 - rrddim_set_by_pointer(st_new, rd_invalid, (collected_number) nfstat_root.metrics[CTA_STATS_INVALID]);
326 -
327 - rrdset_done(st_new);
328 - }
326 + static int new_chart_generated = 0, changes_chart_generated = 0, search_chart_generated = 0, errors_chart_generated = 0, expect_chart_generated = 0;
327 +
328 + if(!new_chart_generated) {
329 + new_chart_generated = 1;
330 +
331 + printf("CHART %s.%s '' 'Connection Tracker New Connections' 'connections/s' %s '' line %d %d %s\n"
332 + , RRD_TYPE_NET_STAT_NETFILTER
333 + , RRD_TYPE_NET_STAT_CONNTRACK "_new"
334 + , RRD_TYPE_NET_STAT_CONNTRACK
335 + , NETDATA_CHART_PRIO_NETFILTER_NEW
336 + , nfstat_root.update_every
337 + , PLUGIN_NFACCT_NAME
338 + );
339 + printf("DIMENSION %s '' incremental 1 1\n", nfstat_root.attr2name[CTA_STATS_NEW]);
340 + printf("DIMENSION %s '' incremental -1 1\n", nfstat_root.attr2name[CTA_STATS_IGNORE]);
341 + printf("DIMENSION %s '' incremental -1 1\n", nfstat_root.attr2name[CTA_STATS_INVALID]);
342 + }
343 +
344 + printf(
345 + "BEGIN %s.%s\n"
346 + , RRD_TYPE_NET_STAT_NETFILTER
347 + , RRD_TYPE_NET_STAT_CONNTRACK "_new"
348 + );
349 + printf(
350 + "SET %s = %lld\n"
351 + , nfstat_root.attr2name[CTA_STATS_NEW]
352 + , (collected_number) nfstat_root.metrics[CTA_STATS_NEW]
353 + );
354 + printf(
355 + "SET %s = %lld\n"
356 + , nfstat_root.attr2name[CTA_STATS_IGNORE]
357 + , (collected_number) nfstat_root.metrics[CTA_STATS_IGNORE]
358 + );
359 + printf(
360 + "SET %s = %lld\n"
361 + , nfstat_root.attr2name[CTA_STATS_INVALID]
362 + , (collected_number) nfstat_root.metrics[CTA_STATS_INVALID]
363 + );
364 + printf("END\n");
365
366 // ----------------------------------------------------------------
367
332 - {
333 - static RRDSET *st_changes = NULL;
334 - static RRDDIM *rd_inserted = NULL, *rd_deleted = NULL, *rd_delete_list = NULL;
335 -
336 - if(!st_changes) {
337 - st_changes = rrdset_create_localhost(
338 - RRD_TYPE_NET_STAT_NETFILTER
339 - , RRD_TYPE_NET_STAT_CONNTRACK "_changes"
340 - , NULL
341 - , RRD_TYPE_NET_STAT_CONNTRACK
342 - , NULL
343 - , "Connection Tracker Changes"
344 - , "changes/s"
345 - , PLUGIN_NFACCT_NAME
346 - , NULL
347 - , NETDATA_CHART_PRIO_NETFILTER_CHANGES
348 - , nfstat_root.update_every
349 - , RRDSET_TYPE_LINE
350 - );
351 - rrdset_flag_set(st_changes, RRDSET_FLAG_DETAIL);
352 -
353 - rd_inserted = rrddim_add(st_changes, nfstat_root.attr2name[CTA_STATS_INSERT], NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
354 - rd_deleted = rrddim_add(st_changes, nfstat_root.attr2name[CTA_STATS_DELETE], NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
355 - rd_delete_list = rrddim_add(st_changes, nfstat_root.attr2name[CTA_STATS_DELETE_LIST], NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
356 - }
357 - else
358 - rrdset_next(st_changes);
359 -
360 - rrddim_set_by_pointer(st_changes, rd_inserted, (collected_number) nfstat_root.metrics[CTA_STATS_INSERT]);
361 - rrddim_set_by_pointer(st_changes, rd_deleted, (collected_number) nfstat_root.metrics[CTA_STATS_DELETE]);
362 - rrddim_set_by_pointer(st_changes, rd_delete_list, (collected_number) nfstat_root.metrics[CTA_STATS_DELETE_LIST]);
368 + if(!changes_chart_generated) {
369 + changes_chart_generated = 1;
370
364 - rrdset_done(st_changes);
365 - }
371 + printf("CHART %s.%s '' 'Connection Tracker Changes' 'changes/s' %s '' line %d %d detail %s\n"
372 + , RRD_TYPE_NET_STAT_NETFILTER
373 + , RRD_TYPE_NET_STAT_CONNTRACK "_changes"
374 + , RRD_TYPE_NET_STAT_CONNTRACK
375 + , NETDATA_CHART_PRIO_NETFILTER_CHANGES
376 + , nfstat_root.update_every
377 + , PLUGIN_NFACCT_NAME
378 + );
379 + printf("DIMENSION %s '' incremental 1 1\n", nfstat_root.attr2name[CTA_STATS_INSERT]);
380 + printf("DIMENSION %s '' incremental -1 1\n", nfstat_root.attr2name[CTA_STATS_DELETE]);
381 + printf("DIMENSION %s '' incremental -1 1\n", nfstat_root.attr2name[CTA_STATS_DELETE_LIST]);
382 + }
383 +
384 + printf(
385 + "BEGIN %s.%s\n"
386 + , RRD_TYPE_NET_STAT_NETFILTER
387 + , RRD_TYPE_NET_STAT_CONNTRACK "_changes"
388 + );
389 + printf(
390 + "SET %s = %lld\n"
391 + , nfstat_root.attr2name[CTA_STATS_INSERT]
392 + , (collected_number) nfstat_root.metrics[CTA_STATS_INSERT]
393 + );
394 + printf(
395 + "SET %s = %lld\n"
396 + , nfstat_root.attr2name[CTA_STATS_DELETE]
397 + , (collected_number) nfstat_root.metrics[CTA_STATS_DELETE]
398 + );
399 + printf(
400 + "SET %s = %lld\n"
401 + , nfstat_root.attr2name[CTA_STATS_DELETE_LIST]
402 + , (collected_number) nfstat_root.metrics[CTA_STATS_DELETE_LIST]
403 + );
404 + printf("END\n");
405
406 // ----------------------------------------------------------------
407
369 - {
370 - static RRDSET *st_search = NULL;
371 - static RRDDIM *rd_searched = NULL, *rd_restarted = NULL, *rd_found = NULL;
372 -
373 - if(!st_search) {
374 - st_search = rrdset_create_localhost(
375 - RRD_TYPE_NET_STAT_NETFILTER
376 - , RRD_TYPE_NET_STAT_CONNTRACK "_search"
377 - , NULL
378 - , RRD_TYPE_NET_STAT_CONNTRACK
379 - , NULL
380 - , "Connection Tracker Searches"
381 - , "searches/s"
382 - , PLUGIN_NFACCT_NAME
383 - , NULL
384 - , NETDATA_CHART_PRIO_NETFILTER_SEARCH
385 - , nfstat_root.update_every
386 - , RRDSET_TYPE_LINE
387 - );
388 - rrdset_flag_set(st_search, RRDSET_FLAG_DETAIL);
389 -
390 - rd_searched = rrddim_add(st_search, nfstat_root.attr2name[CTA_STATS_SEARCHED], NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
391 - rd_restarted = rrddim_add(st_search, nfstat_root.attr2name[CTA_STATS_SEARCH_RESTART], NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
392 - rd_found = rrddim_add(st_search, nfstat_root.attr2name[CTA_STATS_FOUND], NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
393 - }
394 - else
395 - rrdset_next(st_search);
408 + if(!search_chart_generated) {
409 + search_chart_generated = 1;
410
397 - rrddim_set_by_pointer(st_search, rd_searched, (collected_number) nfstat_root.metrics[CTA_STATS_SEARCHED]);
398 - rrddim_set_by_pointer(st_search, rd_restarted, (collected_number) nfstat_root.metrics[CTA_STATS_SEARCH_RESTART]);
399 - rrddim_set_by_pointer(st_search, rd_found, (collected_number) nfstat_root.metrics[CTA_STATS_FOUND]);
400 -
401 - rrdset_done(st_search);
402 - }
411 + printf("CHART %s.%s '' 'Connection Tracker Searches' 'searches/s' %s '' line %d %d detail %s\n"
412 + , RRD_TYPE_NET_STAT_NETFILTER
413 + , RRD_TYPE_NET_STAT_CONNTRACK "_search"
414 + , RRD_TYPE_NET_STAT_CONNTRACK
415 + , NETDATA_CHART_PRIO_NETFILTER_SEARCH
416 + , nfstat_root.update_every
417 + , PLUGIN_NFACCT_NAME
418 + );
419 + printf("DIMENSION %s '' incremental 1 1\n", nfstat_root.attr2name[CTA_STATS_SEARCHED]);
420 + printf("DIMENSION %s '' incremental -1 1\n", nfstat_root.attr2name[CTA_STATS_SEARCH_RESTART]);
421 + printf("DIMENSION %s '' incremental 1 1\n", nfstat_root.attr2name[CTA_STATS_FOUND]);
422 + }
423 +
424 + printf(
425 + "BEGIN %s.%s\n"
426 + , RRD_TYPE_NET_STAT_NETFILTER
427 + , RRD_TYPE_NET_STAT_CONNTRACK "_search"
428 + );
429 + printf(
430 + "SET %s = %lld\n"
431 + , nfstat_root.attr2name[CTA_STATS_SEARCHED]
432 + , (collected_number) nfstat_root.metrics[CTA_STATS_SEARCHED]
433 + );
434 + printf(
435 + "SET %s = %lld\n"
436 + , nfstat_root.attr2name[CTA_STATS_SEARCH_RESTART]
437 + , (collected_number) nfstat_root.metrics[CTA_STATS_SEARCH_RESTART]
438 + );
439 + printf(
440 + "SET %s = %lld\n"
441 + , nfstat_root.attr2name[CTA_STATS_FOUND]
442 + , (collected_number) nfstat_root.metrics[CTA_STATS_FOUND]
443 + );
444 + printf("END\n");
445
446 // ----------------------------------------------------------------
447
406 - {
407 - static RRDSET *st_errors = NULL;
408 - static RRDDIM *rd_error = NULL, *rd_insert_failed = NULL, *rd_drop = NULL, *rd_early_drop = NULL;
409 -
410 - if(!st_errors) {
411 - st_errors = rrdset_create_localhost(
412 - RRD_TYPE_NET_STAT_NETFILTER
413 - , RRD_TYPE_NET_STAT_CONNTRACK "_errors"
414 - , NULL
415 - , RRD_TYPE_NET_STAT_CONNTRACK
416 - , NULL
417 - , "Connection Tracker Errors"
418 - , "events/s"
419 - , PLUGIN_NFACCT_NAME
420 - , NULL
421 - , NETDATA_CHART_PRIO_NETFILTER_ERRORS
422 - , nfstat_root.update_every
423 - , RRDSET_TYPE_LINE
424 - );
425 - rrdset_flag_set(st_errors, RRDSET_FLAG_DETAIL);
426 -
427 - rd_error = rrddim_add(st_errors, nfstat_root.attr2name[CTA_STATS_ERROR], NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
428 - rd_insert_failed = rrddim_add(st_errors, nfstat_root.attr2name[CTA_STATS_INSERT_FAILED], NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
429 - rd_drop = rrddim_add(st_errors, nfstat_root.attr2name[CTA_STATS_DROP], NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
430 - rd_early_drop = rrddim_add(st_errors, nfstat_root.attr2name[CTA_STATS_EARLY_DROP], NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
431 - }
432 - else
433 - rrdset_next(st_errors);
448 + if(!errors_chart_generated) {
449 + errors_chart_generated = 1;
450
435 - rrddim_set_by_pointer(st_errors, rd_error, (collected_number) nfstat_root.metrics[CTA_STATS_ERROR]);
436 - rrddim_set_by_pointer(st_errors, rd_insert_failed, (collected_number) nfstat_root.metrics[CTA_STATS_INSERT_FAILED]);
437 - rrddim_set_by_pointer(st_errors, rd_drop, (collected_number) nfstat_root.metrics[CTA_STATS_DROP]);
438 - rrddim_set_by_pointer(st_errors, rd_early_drop, (collected_number) nfstat_root.metrics[CTA_STATS_EARLY_DROP]);
439 -
440 - rrdset_done(st_errors);
441 - }
451 + printf("CHART %s.%s '' 'Connection Tracker Errors' 'events/s' %s '' line %d %d detail %s\n"
452 + , RRD_TYPE_NET_STAT_NETFILTER
453 + , RRD_TYPE_NET_STAT_CONNTRACK "_errors"
454 + , RRD_TYPE_NET_STAT_CONNTRACK
455 + , NETDATA_CHART_PRIO_NETFILTER_ERRORS
456 + , nfstat_root.update_every
457 + , PLUGIN_NFACCT_NAME
458 + );
459 + printf("DIMENSION %s '' incremental 1 1\n", nfstat_root.attr2name[CTA_STATS_ERROR]);
460 + printf("DIMENSION %s '' incremental -1 1\n", nfstat_root.attr2name[CTA_STATS_INSERT_FAILED]);
461 + printf("DIMENSION %s '' incremental -1 1\n", nfstat_root.attr2name[CTA_STATS_DROP]);
462 + printf("DIMENSION %s '' incremental -1 1\n", nfstat_root.attr2name[CTA_STATS_EARLY_DROP]);
463 + }
464 +
465 + printf(
466 + "BEGIN %s.%s\n"
467 + , RRD_TYPE_NET_STAT_NETFILTER
468 + , RRD_TYPE_NET_STAT_CONNTRACK "_errors"
469 + );
470 + printf(
471 + "SET %s = %lld\n"
472 + , nfstat_root.attr2name[CTA_STATS_ERROR]
473 + , (collected_number) nfstat_root.metrics[CTA_STATS_ERROR]
474 + );
475 + printf(
476 + "SET %s = %lld\n"
477 + , nfstat_root.attr2name[CTA_STATS_INSERT_FAILED]
478 + , (collected_number) nfstat_root.metrics[CTA_STATS_INSERT_FAILED]
479 + );
480 + printf(
481 + "SET %s = %lld\n"
482 + , nfstat_root.attr2name[CTA_STATS_DROP]
483 + , (collected_number) nfstat_root.metrics[CTA_STATS_DROP]
484 + );
485 + printf(
486 + "SET %s = %lld\n"
487 + , nfstat_root.attr2name[CTA_STATS_EARLY_DROP]
488 + , (collected_number) nfstat_root.metrics[CTA_STATS_EARLY_DROP]
489 + );
490 + printf("END\n");
491
492 // ----------------------------------------------------------------
493
445 - {
446 - static RRDSET *st_expect = NULL;
447 - static RRDDIM *rd_new = NULL, *rd_created = NULL, *rd_deleted = NULL;
448 -
449 - if(!st_expect) {
450 - st_expect = rrdset_create_localhost(
451 - RRD_TYPE_NET_STAT_NETFILTER
452 - , RRD_TYPE_NET_STAT_CONNTRACK "_expect"
453 - , NULL
454 - , RRD_TYPE_NET_STAT_CONNTRACK
455 - , NULL
456 - , "Connection Tracker Expectations"
457 - , "expectations/s"
458 - , PLUGIN_NFACCT_NAME
459 - , NULL
460 - , NETDATA_CHART_PRIO_NETFILTER_EXPECT
461 - , nfstat_root.update_every
462 - , RRDSET_TYPE_LINE
463 - );
464 - rrdset_flag_set(st_expect, RRDSET_FLAG_DETAIL);
465 -
466 - rd_created = rrddim_add(st_expect, nfstat_root.attr2name_exp[CTA_STATS_EXP_CREATE], NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
467 - rd_deleted = rrddim_add(st_expect, nfstat_root.attr2name_exp[CTA_STATS_EXP_DELETE], NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
468 - rd_new = rrddim_add(st_expect, nfstat_root.attr2name_exp[CTA_STATS_EXP_NEW], NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
469 - }
470 - else
471 - rrdset_next(st_expect);
472 -
473 - rrddim_set_by_pointer(st_expect, rd_created, (collected_number) nfstat_root.metrics_exp[CTA_STATS_EXP_CREATE]);
474 - rrddim_set_by_pointer(st_expect, rd_deleted, (collected_number) nfstat_root.metrics_exp[CTA_STATS_EXP_DELETE]);
475 - rrddim_set_by_pointer(st_expect, rd_new, (collected_number) nfstat_root.metrics_exp[CTA_STATS_EXP_NEW]);
476 -
477 - rrdset_done(st_expect);
478 - }
494 + if(!expect_chart_generated) {
495 + expect_chart_generated = 1;
496
497 + printf("CHART %s.%s '' 'Connection Tracker Expectations' 'expectations/s' %s '' line %d %d detail %s\n"
498 + , RRD_TYPE_NET_STAT_NETFILTER
499 + , RRD_TYPE_NET_STAT_CONNTRACK "_expect"
500 + , RRD_TYPE_NET_STAT_CONNTRACK
501 + , NETDATA_CHART_PRIO_NETFILTER_EXPECT
502 + , nfstat_root.update_every
503 + , PLUGIN_NFACCT_NAME
504 + );
505 + printf("DIMENSION %s '' incremental 1 1\n", nfstat_root.attr2name[CTA_STATS_EXP_CREATE]);
506 + printf("DIMENSION %s '' incremental -1 1\n", nfstat_root.attr2name[CTA_STATS_EXP_DELETE]);
507 + printf("DIMENSION %s '' incremental 1 1\n", nfstat_root.attr2name[CTA_STATS_EXP_NEW]);
508 + }
509 +
510 + printf(
511 + "BEGIN %s.%s\n"
512 + , RRD_TYPE_NET_STAT_NETFILTER
513 + , RRD_TYPE_NET_STAT_CONNTRACK "_expect"
514 + );
515 + printf(
516 + "SET %s = %lld\n"
517 + , nfstat_root.attr2name[CTA_STATS_EXP_CREATE]
518 + , (collected_number) nfstat_root.metrics[CTA_STATS_EXP_CREATE]
519 + );
520 + printf(
521 + "SET %s = %lld\n"
522 + , nfstat_root.attr2name[CTA_STATS_EXP_DELETE]
523 + , (collected_number) nfstat_root.metrics[CTA_STATS_EXP_DELETE]
524 + );
525 + printf(
526 + "SET %s = %lld\n"
527 + , nfstat_root.attr2name[CTA_STATS_EXP_NEW]
528 + , (collected_number) nfstat_root.metrics[CTA_STATS_EXP_NEW]
529 + );
530 + printf("END\n");
531 }
532
533 #endif // HAVE_LINUX_NETFILTER_NFNETLINK_CONNTRACK_H
@@ -497,8 +548,8 @@ struct nfacct_data {
548 uint64_t pkts;
549 uint64_t bytes;
550
500 - RRDDIM *rd_bytes;
501 - RRDDIM *rd_packets;
551 + int packets_dimension_added;
552 + int bytes_dimension_added;
553
554 int updated;
555
@@ -579,24 +630,6 @@ static int nfacct_init(int update_every) {
630 return 0;
631 }
632
582 -static void nfacct_cleanup() {
583 - if(nfacct_root.mnl) {
584 - mnl_socket_close(nfacct_root.mnl);
585 - nfacct_root.mnl = NULL;
586 - }
587 -
588 - if(nfacct_root.nfacct_buffer) {
589 - nfacct_free(nfacct_root.nfacct_buffer);
590 - nfacct_root.nfacct_buffer = NULL;
591 - }
592 -
593 - freez(nfacct_root.buf);
594 - nfacct_root.buf = NULL;
595 - nfacct_root.buf_size = 0;
596 -
597 - // TODO: cleanup the metrics linked list
598 -}
599 -
633 static int nfacct_callback(const struct nlmsghdr *nlh, void *data) {
634 (void)data;
635
@@ -661,162 +694,216 @@ static int nfacct_collect() {
694 }
695
696 static void nfacct_send_metrics() {
664 - static RRDSET *st_bytes = NULL, *st_packets = NULL;
697 + static int bytes_chart_generated = 0, packets_chart_generated = 0;
698
699 if(!nfacct_root.nfacct_metrics) return;
700 struct nfacct_data *d;
701
669 - if(!st_packets) {
670 - st_packets = rrdset_create_localhost(
671 - "netfilter"
672 - , "nfacct_packets"
673 - , NULL
674 - , "nfacct"
675 - , NULL
676 - , "Netfilter Accounting Packets"
677 - , "packets/s"
678 - , PLUGIN_NFACCT_NAME
679 - , NULL
680 - , NETDATA_CHART_PRIO_NETFILTER_PACKETS
681 - , nfacct_root.update_every
682 - , RRDSET_TYPE_STACKED
702 + if(!packets_chart_generated) {
703 + packets_chart_generated = 1;
704 + printf("CHART netfilter.nfacct_packets '' 'Netfilter Accounting Packets' 'packets/s' 'nfacct' '' stacked %d %d %s\n"
705 + , NETDATA_CHART_PRIO_NETFILTER_PACKETS
706 + , nfacct_root.update_every
707 + , PLUGIN_NFACCT_NAME
708 );
709 }
685 - else rrdset_next(st_packets);
710
711 for(d = nfacct_root.nfacct_metrics; d ; d = d->next) {
712 if(likely(d->updated)) {
689 - if(unlikely(!d->rd_packets))
690 - d->rd_packets = rrddim_add(
691 - st_packets
692 - , d->name
693 - , NULL
694 - , 1
695 - , nfacct_root.update_every
696 - , RRD_ALGORITHM_INCREMENTAL
697 - );
698 -
699 - rrddim_set_by_pointer(
700 - st_packets
701 - , d->rd_packets
713 + if(unlikely(!d->packets_dimension_added)) {
714 + d->packets_dimension_added = 1;
715 + printf("CHART netfilter.nfacct_packets '' 'Netfilter Accounting Packets' 'packets/s'\n");
716 + printf("DIMENSION %s '' incremental 1 %d\n", d->name, nfacct_root.update_every);
717 + }
718 + printf(
719 + "BEGIN netfilter.nfacct_packets\n"
720 + "SET %s = %lld\n"
721 + "END\n"
722 + , d->name
723 , (collected_number)d->pkts
724 );
725 }
726 }
727
707 - rrdset_done(st_packets);
708 -
728 // ----------------------------------------------------------------
729
711 - st_bytes = rrdset_find_bytype_localhost("netfilter", "nfacct_bytes");
712 - if(!st_bytes) {
713 - st_bytes = rrdset_create_localhost(
714 - "netfilter"
715 - , "nfacct_bytes"
716 - , NULL
717 - , "nfacct"
718 - , NULL
719 - , "Netfilter Accounting Bandwidth"
720 - , "kilobytes/s"
721 - , PLUGIN_NFACCT_NAME
722 - , NULL
723 - , NETDATA_CHART_PRIO_NETFILTER_BYTES
724 - , nfacct_root.update_every
725 - , RRDSET_TYPE_STACKED
730 + if(!bytes_chart_generated) {
731 + bytes_chart_generated = 1;
732 + printf("CHART netfilter.nfacct_bytes '' 'Netfilter Accounting Bandwidth' 'kilobytes/s' 'nfacct' '' stacked %d %d %s\n"
733 + , NETDATA_CHART_PRIO_NETFILTER_BYTES
734 + , nfacct_root.update_every
735 + , PLUGIN_NFACCT_NAME
736 );
737 }
728 - else rrdset_next(st_bytes);
738
739 for(d = nfacct_root.nfacct_metrics; d ; d = d->next) {
740 if(likely(d->updated)) {
732 - if(unlikely(!d->rd_bytes))
733 - d->rd_bytes = rrddim_add(
734 - st_bytes
735 - , d->name
736 - , NULL
737 - , 1
738 - , 1000 * nfacct_root.update_every
739 - , RRD_ALGORITHM_INCREMENTAL
740 - );
741 -
742 - rrddim_set_by_pointer(
743 - st_bytes
744 - , d->rd_bytes
745 - , (collected_number)d->bytes
741 + if(unlikely(!d->bytes_dimension_added)) {
742 + d->bytes_dimension_added = 1;
743 + printf("CHART netfilter.nfacct_bytes '' 'Netfilter Accounting Bandwidth' 'kilobytes/s'\n");
744 + printf("DIMENSION %s '' incremental 1 %d\n", d->name, 1000 * nfacct_root.update_every);
745 + }
746 + printf(
747 + "BEGIN netfilter.nfacct_bytes\n"
748 + "SET %s = %lld\n"
749 + "END\n"
750 + , d->name
751 + , (collected_number)d->bytes
752 );
753 }
754 }
749 -
750 - rrdset_done(st_bytes);
755 }
756
757 #endif // HAVE_LIBNETFILTER_ACCT
754 -#endif // HAVE_LIBMNL
758
756 -// ----------------------------------------------------------------------------
759 +int main(int argc, char **argv) {
760
758 -static void nfacct_main_cleanup(void *ptr) {
759 - struct netdata_static_thread *static_thread = (struct netdata_static_thread *)ptr;
760 - static_thread->enabled = NETDATA_MAIN_THREAD_EXITING;
761 - info("cleaning up...");
761 + // ------------------------------------------------------------------------
762 + // initialization of netdata plugin
763
763 -#ifdef DO_NFACCT
764 - nfacct_cleanup();
765 -#endif
764 + program_name = "nfacct.plugin";
765
767 -#ifdef DO_NFSTAT
768 - nfstat_cleanup();
769 -#endif
766 + // disable syslog
767 + error_log_syslog = 0;
768
771 - static_thread->enabled = NETDATA_MAIN_THREAD_EXITED;
772 -}
769 + // set errors flood protection to 100 logs per hour
770 + error_log_errors_per_period = 100;
771 + error_log_throttle_period = 3600;
772 +
773 + // ------------------------------------------------------------------------
774 + // parse command line parameters
775 +
776 + int i, freq = 0;
777 + for(i = 1; i < argc ; i++) {
778 + if(isdigit(*argv[i]) && !freq) {
779 + int n = str2i(argv[i]);
780 + if(n > 0 && n < 86400) {
781 + freq = n;
782 + continue;
783 + }
784 + }
785 + else if(strcmp("version", argv[i]) == 0 || strcmp("-version", argv[i]) == 0 || strcmp("--version", argv[i]) == 0 || strcmp("-v", argv[i]) == 0 || strcmp("-V", argv[i]) == 0) {
786 + printf("nfacct.plugin %s\n", VERSION);
787 + exit(0);
788 + }
789 + else if(strcmp("debug", argv[i]) == 0) {
790 + debug = 1;
791 + continue;
792 + }
793 + else if(strcmp("-h", argv[i]) == 0 || strcmp("--help", argv[i]) == 0) {
794 + fprintf(stderr,
795 + "\n"
796 + " netdata nfacct.plugin %s\n"
797 + " Copyright (C) 2015-2017 Costa Tsaousis <costa@tsaousis.gr>\n"
798 + " Released under GNU General Public License v3 or later.\n"
799 + " All rights reserved.\n"
800 + "\n"
801 + " This program is a data collector plugin for netdata.\n"
802 + "\n"
803 + " Available command line options:\n"
804 + "\n"
805 + " COLLECTION_FREQUENCY data collection frequency in seconds\n"
806 + " minimum: %d\n"
807 + "\n"
808 + " debug enable verbose output\n"
809 + " default: disabled\n"
810 + "\n"
811 + " -v\n"
812 + " -V\n"
813 + " --version print version and exit\n"
814 + "\n"
815 + " -h\n"
816 + " --help print this message and exit\n"
817 + "\n"
818 + " For more information:\n"
819 + " https://github.com/netdata/netdata/tree/master/collectors/nfacct.plugin\n"
820 + "\n"
821 + , VERSION
822 + , netdata_update_every
823 + );
824 + exit(1);
825 + }
826
774 -void *nfacct_main(void *ptr) {
775 - netdata_thread_cleanup_push(nfacct_main_cleanup, ptr);
827 + error("nfacct.plugin: ignoring parameter '%s'", argv[i]);
828 + }
829
777 - int update_every = (int)config_get_number("plugin:netfilter", "update every", localhost->rrd_update_every);
778 - if(update_every < localhost->rrd_update_every)
779 - update_every = localhost->rrd_update_every;
830 + errno = 0;
831 +
832 + if(freq >= netdata_update_every)
833 + netdata_update_every = freq;
834 + else if(freq)
835 + error("update frequency %d seconds is too small for NFACCT. Using %d.", freq, netdata_update_every);
836
837 #ifdef DO_NFACCT
782 - int nfacct = !nfacct_init(update_every);
838 + if(debug) fprintf(stderr, "freeipmi.plugin: calling nfacct_init()\n");
839 + int nfacct = !nfacct_init(netdata_update_every);
840 #endif
841
842 #ifdef DO_NFSTAT
786 - int nfstat = !nfstat_init(update_every);
843 + if(debug) fprintf(stderr, "freeipmi.plugin: calling nfstat_init()\n");
844 + int nfstat = !nfstat_init(netdata_update_every);
845 #endif
846
847 // ------------------------------------------------------------------------
848 + // the main loop
849 +
850 + if(debug) fprintf(stderr, "nfacct.plugin: starting data collection\n");
851 +
852 + time_t started_t = now_monotonic_sec();
853 +
854 + size_t iteration;
855 + usec_t step = netdata_update_every * USEC_PER_SEC;
856
791 - usec_t step = update_every * USEC_PER_SEC;
857 heartbeat_t hb;
858 heartbeat_init(&hb);
794 - for(;;) {
795 - heartbeat_next(&hb, step);
859 + for(iteration = 0; 1; iteration++) {
860 + usec_t dt = heartbeat_next(&hb, step);
861
862 if(unlikely(netdata_exit)) break;
863
864 + if(debug && iteration)
865 + fprintf(stderr, "nfacct.plugin: iteration %zu, dt %llu usec\n"
866 + , iteration
867 + , dt
868 + );
869 +
870 #ifdef DO_NFACCT
871 if(likely(nfacct)) {
872 + if(debug) fprintf(stderr, "nfacct.plugin: calling nfacct_collect()\n");
873 nfacct = !nfacct_collect();
874
803 - if(likely(nfacct))
875 + if(likely(nfacct)) {
876 + if(debug) fprintf(stderr, "nfacct.plugin: calling nfacct_send_metrics()\n");
877 nfacct_send_metrics();
878 + }
879 }
880 #endif
881
882 #ifdef DO_NFSTAT
883 if(likely(nfstat)) {
884 + if(debug) fprintf(stderr, "nfacct.plugin: calling nfstat_collect()\n");
885 nfstat = !nfstat_collect();
886
812 - if(likely(nfstat))
887 + if(likely(nfstat)) {
888 + if(debug) fprintf(stderr, "nfacct.plugin: calling nfstat_send_metrics()\n");
889 nfstat_send_metrics();
890 + }
891 }
892 #endif
893 +
894 + fflush(stdout);
895 +
896 + // restart check (14400 seconds)
897 + if(now_monotonic_sec() - started_t > 14400) break;
898 }
899
818 - netdata_thread_cleanup_pop(1);
819 - return NULL;
900 + info("NFACCT process exiting");
901 +}
902 +
903 +#else // !HAVE_LIBMNL
904 +
905 +int main(int argc, char **argv) {
906 + fatal("nfacct.plugin is not compiled.");
907 }
908
822 -#endif // INTERNAL_PLUGIN_NFACCT
909 +#endif // !HAVE_LIBMNL
collectors/nfacct.plugin/plugin_nfacct.h deleted
-30
@@ -1,30 +0,0 @@
1 -// SPDX-License-Identifier: GPL-3.0-or-later
2 -
3 -#ifndef NETDATA_NFACCT_H
4 -#define NETDATA_NFACCT_H 1
5 -
6 -#include "../../daemon/common.h"
7 -
8 -#if defined(INTERNAL_PLUGIN_NFACCT)
9 -
10 -#define NETDATA_PLUGIN_HOOK_LINUX_NFACCT \
11 - { \
12 - .name = "PLUGIN[nfacct]", \
13 - .config_section = CONFIG_SECTION_PLUGINS, \
14 - .config_name = "nfacct", \
15 - .enabled = 1, \
16 - .thread = NULL, \
17 - .init_routine = NULL, \
18 - .start_routine = nfacct_main \
19 - },
20 -
21 -extern void *nfacct_main(void *ptr);
22 -
23 -#else // !defined(INTERNAL_PLUGIN_NFACCT)
24 -
25 -#define NETDATA_PLUGIN_HOOK_LINUX_NFACCT
26 -
27 -#endif // defined(INTERNAL_PLUGIN_NFACCT)
28 -
29 -#endif /* NETDATA_NFACCT_H */
30 -
collectors/plugins.d/README.md
+1
@@ -12,6 +12,7 @@ plugin|language|O/S|description
12 [cups.plugin](../cups.plugin/)|`C`|all|monitors **CUPS**
13 [fping.plugin](../fping.plugin/)|`C`|all|measures network latency, jitter and packet loss between the monitored node and any number of remote network end points.
14 [freeipmi.plugin](../freeipmi.plugin/)|`C`|linux|collects metrics from enterprise hardware sensors, on Linux servers.
15 +[nfacct.plugin](../nfacct.plugin/)|`C`|linux|collects netfilter firewall, connection tracker and accounting metrics using `libmnl` and `libnetfilter_acct`.
16 [node.d.plugin](../node.d.plugin/)|`node.js`|all|a **plugin orchestrator** for data collection modules written in `node.js`.
17 [python.d.plugin](../python.d.plugin/)|`python`|all|a **plugin orchestrator** for data collection modules written in `python` v2 or v3 (both are supported).
18
configure.ac
+3 -4
@@ -47,9 +47,9 @@ AC_USE_SYSTEM_EXTENSIONS
47
48 AC_ARG_ENABLE(
49 [plugin-nfacct],
50 - [AS_HELP_STRING([--enable-plugin-nfacct], [enable nfacct plugin, requires running netdata as root @<:@default disabled@:>@])],
50 + [AS_HELP_STRING([--enable-plugin-nfacct], [enable nfacct plugin @<:@default autodetect@:>@])],
51 ,
52 - [enable_plugin_nfacct="no"]
52 + [enable_plugin_nfacct="detect"]
53 )
54 AC_ARG_ENABLE(
55 [plugin-freeipmi],
@@ -441,7 +441,7 @@ AC_MSG_CHECKING([if cups.plugin should be enabled])
441 if test "${enable_plugin_cups}" != "no" -a "${have_cups}" = "yes"; then
442 enable_plugin_cups="yes"
443 AC_DEFINE([HAVE_CUPS], [1], [cups usability])
444 -
444 +
445 CUPS_CFLAGS="${CUPS_CFLAGS} `$CUPSCONFIG --cflags`"
446 CUPS_LIBS="${CUPS_LIBS} `$CUPSCONFIG --image --libs`"
447
@@ -484,7 +484,6 @@ if test "${enable_plugin_nfacct}" != "no" -a "${have_libnetfilter_acct}" = "yes"
484 enable_plugin_nfacct="yes"
485 AC_DEFINE([HAVE_LIBMNL], [1], [libmnl usability])
486 AC_DEFINE([HAVE_LIBNETFILTER_ACCT], [1], [libnetfilter_acct usability])
487 - AC_DEFINE([INTERNAL_PLUGIN_NFACCT], [1], [nfacct plugin usability])
487 OPTIONAL_NFACCT_CLFAGS="${NFACCT_CFLAGS} ${LIBMNL_CFLAGS}"
488 OPTIONAL_NFACCT_LIBS="${NFACCT_LIBS} ${LIBMNL_LIBS}"
489 else
daemon/main.c
-1
@@ -60,7 +60,6 @@ struct netdata_static_thread static_threads[] = {
60 NETDATA_PLUGIN_HOOK_MACOS
61
62 // linux internal plugins
63 - NETDATA_PLUGIN_HOOK_LINUX_NFACCT
63 NETDATA_PLUGIN_HOOK_LINUX_PROC
64 NETDATA_PLUGIN_HOOK_LINUX_DISKSPACE
65 NETDATA_PLUGIN_HOOK_LINUX_CGROUPS
docs/Add-more-charts-to-netdata.md
+3 -2
@@ -22,7 +22,7 @@ To collect non-system metrics, netdata supports a plugin architecture. The follo
22 - **[Print Servers](#print-servers)**, like CUPS
23 - **[System](#system)**, for processes and other system metrics
24 - **[Sensors](#sensors)**, like temperature, fans speed, voltage, humidity, HDD/SSD S.M.A.R.T attributes
25 -- **[Network](#network)**, such as SNMP devices, `fping`, access points, dns_query_time
25 +- **[Network](#network)**, such as SNMP devices, `fping`, access points, dns_query_time, nfacct
26 - **[Time Servers](#time-servers)**, like chrony
27 - **[Security](#security)**, like FreeRADIUS, OpenVPN, Fail2ban
28 - **[Telephony Servers](#telephony-servers)**, like openSIPS
@@ -43,7 +43,7 @@ netdata comes with **internal** and **external** plugins:
43 1. The **internal** ones are written in `C` and run as threads within the netdata daemon.
44 2. The **external** ones can be written in any computer language. The netdata daemon spawns these as processes (shown with `ps fax`) and reads their metrics using pipes (so the `stdout` of external plugins is connected to netdata for metrics collection and the `stderr` of external plugins is connected to `/var/log/netdata/error.log`).
45
46 -To make it easier to develop plugins, and minimize the number of threads and processes running, netdata supports **plugin orchestrators**, each of them supporting one or more data collection **modules**. Currently we ship plugin orchestrators for 4 languages: `C`, `python`, `node.js` and `bash` and 2 more are under development (`go` and `java`).
46 +To make it easier to develop plugins, and minimize the number of threads and processes running, netdata supports **plugin orchestrators**, each of them supporting one or more data collection **modules**. Currently we ship plugin orchestrators for 4 languages: `C`, `python`, `node.js` and `bash` and 2 more are under development (`go` and `java`).
47
48 #### enabling and disabling plugins
49
@@ -338,6 +338,7 @@ application|language|notes|
338 ap|BASH<br/>Shell Script|Uses the `iw` command to provide statistics of wireless clients connected to a wireless access point running on this host (works well with `hostapd`).<br/>&nbsp;<br/>netdata plugin: [charts.d.plugin](../collectors/charts.d.plugin#chartsdplugin)<br/>plugin module: [ap.chart.sh](../collectors/charts.d.plugin/ap)<br/>configuration file: [charts.d/ap.conf](../collectors/charts.d.plugin/ap)|
339 fping|C|Charts network latency statistics for any number of nodes, using the `fping` command. A recent (probably unreleased) version of fping is required. The plugin supplied can install it in `/usr/local`.<br/>&nbsp;<br/>netdata plugin: [fping.plugin](../collectors/fping.plugin) (this is a shell wrapper to start fping - once fping is started, netdata and fping communicate directly - it can also install the right version of fping)<br/>configuration file: [fping.conf](../collectors/fping.plugin)|
340 snmp|node.js|Connects to multiple snmp servers to collect real-time performance metrics.<br/>&nbsp;<br/>netdata plugin: [node.d.plugin](../collectors/node.d.plugin#nodedplugin)<br/>plugin module: [snmp.node.js](../collectors/node.d.plugin/snmp)<br/>configuration file: [node.d/snmp.conf](../collectors/node.d.plugin/snmp)|
341 +nfacct|C|collects netfilter firewall, connection tracker and accounting metrics using `libmnl` and `libnetfilter_acct`|
342 dns_query_time|python<br/>v2 or v3|Provides DNS query time statistics.<br/>&nbsp;<br/>Requires package `dnspython` (`pip install dnspython` or install package `python-dnspython`).<br/>&nbsp;<br/>netdata plugin: [python.d.plugin](../collectors/python.d.plugin)<br/>plugin module: [dns_query_time.chart.py](../collectors/python.d.plugin/dns_query_time)<br/>configuration file: [python.d/dns_query_time.conf](../collectors/python.d.plugin/dns_query_time)|
343 http|python<br />v2 or v3|Monitors a generic web page for status code and returned content in HTML
344 port|ptyhon<br />v2 or v3|Checks if a generic TCP port for its availability and response time
docs/generator/buildyaml.sh
+1 -1
@@ -167,7 +167,6 @@ navpart 3 collectors/statsd.plugin
167 navpart 3 collectors/cgroups.plugin
168 navpart 3 collectors/idlejitter.plugin
169 navpart 3 collectors/tc.plugin
170 -navpart 3 collectors/nfacct.plugin
170 navpart 3 collectors/checks.plugin
171 navpart 3 collectors/diskspace.plugin
172 navpart 3 collectors/freebsd.plugin
@@ -219,6 +218,7 @@ echo -ne " - BASH:
218 navpart 3 collectors/fping.plugin
219 navpart 3 collectors/freeipmi.plugin
220 navpart 3 collectors/cups.plugin
221 +navpart 3 collectors/nfacct.plugin
222
223 echo -ne " - 'docs/Third-Party-Plugins.md'
224 "
netdata-installer.sh
+8 -3
@@ -282,7 +282,7 @@ if [ "${UID}" -ne 0 ]; then
282 if [ -z "${NETDATA_PREFIX}" ]; then
283 netdata_banner "wrong command line options!"
284 cat <<NONROOTNOPREFIX
285 -
285 +
286 ${TPUT_RED}${TPUT_BOLD}Sorry! This will fail!${TPUT_RESET}
287
288 You are attempting to install netdata as non-root, but you plan
@@ -306,7 +306,7 @@ NONROOTNOPREFIX
306
307 else
308 cat <<NONROOT
309 -
309 +
310 ${TPUT_RED}${TPUT_BOLD}IMPORTANT${TPUT_RESET}:
311 You are about to install netdata as a non-root user.
312 Netdata will work, but a few data collection modules that
@@ -760,6 +760,11 @@ if [ ${UID} -eq 0 ]; then
760 run chmod 4750 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/freeipmi.plugin"
761 fi
762
763 + if [ -f "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/nfacct.plugin" ]; then
764 + run chown root:${NETDATA_GROUP} "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/nfacct.plugin"
765 + run chmod 4750 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/nfacct.plugin"
766 + fi
767 +
768 if [ -f "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/cgroup-network" ]; then
769 run chown root:${NETDATA_GROUP} "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/cgroup-network"
770 run chmod 4750 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/cgroup-network"
@@ -1007,7 +1012,7 @@ if [ "${AUTOUPDATE}" = "1" ]; then
1012 rm -f "${crondir}/netdata-updater.sh"
1013 fi
1014 progress "Installing new netdata-updater in cron"
1010 -
1015 +
1016 rm ${installer_dir}/netdata-updater.sh || : #TODO(paulfantom): this workaround should be removed after v1.13.0-rc1. It just needs to be propagated
1017
1018 rm -f "${crondir}/netdata-updater"