From 6d2e027eb728c8294fdd7c3692e9853b3ca2603b Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 21 Feb 2019 20:34:08 +0100 Subject: Merging upstream version 1.12.1. Signed-off-by: Daniel Baumann --- collectors/nfacct.plugin/plugin_nfacct.c | 677 +++++++++++++++++-------------- 1 file changed, 382 insertions(+), 295 deletions(-) (limited to 'collectors/nfacct.plugin/plugin_nfacct.c') diff --git a/collectors/nfacct.plugin/plugin_nfacct.c b/collectors/nfacct.plugin/plugin_nfacct.c index 7d42dd189..b6788e618 100644 --- a/collectors/nfacct.plugin/plugin_nfacct.c +++ b/collectors/nfacct.plugin/plugin_nfacct.c @@ -1,11 +1,18 @@ // SPDX-License-Identifier: GPL-3.0-or-later -#include "plugin_nfacct.h" - -#if defined(INTERNAL_PLUGIN_NFACCT) +#include "../../libnetdata/libnetdata.h" #define PLUGIN_NFACCT_NAME "nfacct.plugin" +#define NETDATA_CHART_PRIO_NETFILTER_NEW 8701 +#define NETDATA_CHART_PRIO_NETFILTER_CHANGES 8702 +#define NETDATA_CHART_PRIO_NETFILTER_EXPECT 8703 +#define NETDATA_CHART_PRIO_NETFILTER_ERRORS 8705 +#define NETDATA_CHART_PRIO_NETFILTER_SEARCH 8710 + +#define NETDATA_CHART_PRIO_NETFILTER_PACKETS 8906 +#define NETDATA_CHART_PRIO_NETFILTER_BYTES 8907 + #ifdef HAVE_LIBMNL #include @@ -15,6 +22,41 @@ static inline size_t mnl_buffer_size() { return (size_t)s; } +// callback required by fatal() +void netdata_cleanup_and_exit(int ret) { + exit(ret); +} + +void send_statistics( const char *action, const char *action_result, const char *action_data) { + (void) action; + (void) action_result; + (void) action_data; + return; +} + +// callbacks required by popen() +void signals_block(void) {}; +void signals_unblock(void) {}; +void signals_reset(void) {}; + +// callback required by eval() +int health_variable_lookup(const char *variable, uint32_t hash, struct rrdcalc *rc, calculated_number *result) { + (void)variable; + (void)hash; + (void)rc; + (void)result; + return 0; +}; + +// required by get_system_cpus() +char *netdata_configured_host_prefix = ""; + +// Variables + +static int debug = 0; + +static int netdata_update_every = 1; + // ---------------------------------------------------------------------------- // DO_NFSTAT - collect netfilter connection tracker statistics via netlink // example: https://github.com/formorer/pkg-conntrack-tools/blob/master/src/conntrack.c @@ -103,17 +145,6 @@ static int nfstat_init(int update_every) { return 0; } -static void nfstat_cleanup() { - if(nfstat_root.mnl) { - mnl_socket_close(nfstat_root.mnl); - nfstat_root.mnl = NULL; - } - - freez(nfstat_root.buf); - nfstat_root.buf = NULL; - nfstat_root.buf_size = 0; -} - static struct nlmsghdr * nfct_mnl_nlmsghdr_put(char *buf, uint16_t subsys, uint16_t type, uint8_t family, uint32_t seq) { struct nlmsghdr *nlh; struct nfgenmsg *nfh; @@ -292,191 +323,211 @@ static int nfstat_collect() { } static void nfstat_send_metrics() { - - { - static RRDSET *st_new = NULL; - static RRDDIM *rd_new = NULL, *rd_ignore = NULL, *rd_invalid = NULL; - - if(!st_new) { - st_new = rrdset_create_localhost( - RRD_TYPE_NET_STAT_NETFILTER - , RRD_TYPE_NET_STAT_CONNTRACK "_new" - , NULL - , RRD_TYPE_NET_STAT_CONNTRACK - , NULL - , "Connection Tracker New Connections" - , "connections/s" - , PLUGIN_NFACCT_NAME - , NULL - , NETDATA_CHART_PRIO_NETFILTER_NEW - , nfstat_root.update_every - , RRDSET_TYPE_LINE - ); - - rd_new = rrddim_add(st_new, nfstat_root.attr2name[CTA_STATS_NEW], NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); - rd_ignore = rrddim_add(st_new, nfstat_root.attr2name[CTA_STATS_IGNORE], NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL); - rd_invalid = rrddim_add(st_new, nfstat_root.attr2name[CTA_STATS_INVALID], NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL); - } - else - rrdset_next(st_new); - - rrddim_set_by_pointer(st_new, rd_new, (collected_number) nfstat_root.metrics[CTA_STATS_NEW]); - rrddim_set_by_pointer(st_new, rd_ignore, (collected_number) nfstat_root.metrics[CTA_STATS_IGNORE]); - rrddim_set_by_pointer(st_new, rd_invalid, (collected_number) nfstat_root.metrics[CTA_STATS_INVALID]); - - rrdset_done(st_new); - } + static int new_chart_generated = 0, changes_chart_generated = 0, search_chart_generated = 0, errors_chart_generated = 0, expect_chart_generated = 0; + + if(!new_chart_generated) { + new_chart_generated = 1; + + printf("CHART %s.%s '' 'Connection Tracker New Connections' 'connections/s' %s '' line %d %d %s\n" + , RRD_TYPE_NET_STAT_NETFILTER + , RRD_TYPE_NET_STAT_CONNTRACK "_new" + , RRD_TYPE_NET_STAT_CONNTRACK + , NETDATA_CHART_PRIO_NETFILTER_NEW + , nfstat_root.update_every + , PLUGIN_NFACCT_NAME + ); + printf("DIMENSION %s '' incremental 1 1\n", nfstat_root.attr2name[CTA_STATS_NEW]); + printf("DIMENSION %s '' incremental -1 1\n", nfstat_root.attr2name[CTA_STATS_IGNORE]); + printf("DIMENSION %s '' incremental -1 1\n", nfstat_root.attr2name[CTA_STATS_INVALID]); + } + + printf( + "BEGIN %s.%s\n" + , RRD_TYPE_NET_STAT_NETFILTER + , RRD_TYPE_NET_STAT_CONNTRACK "_new" + ); + printf( + "SET %s = %lld\n" + , nfstat_root.attr2name[CTA_STATS_NEW] + , (collected_number) nfstat_root.metrics[CTA_STATS_NEW] + ); + printf( + "SET %s = %lld\n" + , nfstat_root.attr2name[CTA_STATS_IGNORE] + , (collected_number) nfstat_root.metrics[CTA_STATS_IGNORE] + ); + printf( + "SET %s = %lld\n" + , nfstat_root.attr2name[CTA_STATS_INVALID] + , (collected_number) nfstat_root.metrics[CTA_STATS_INVALID] + ); + printf("END\n"); // ---------------------------------------------------------------- - { - static RRDSET *st_changes = NULL; - static RRDDIM *rd_inserted = NULL, *rd_deleted = NULL, *rd_delete_list = NULL; - - if(!st_changes) { - st_changes = rrdset_create_localhost( - RRD_TYPE_NET_STAT_NETFILTER - , RRD_TYPE_NET_STAT_CONNTRACK "_changes" - , NULL - , RRD_TYPE_NET_STAT_CONNTRACK - , NULL - , "Connection Tracker Changes" - , "changes/s" - , PLUGIN_NFACCT_NAME - , NULL - , NETDATA_CHART_PRIO_NETFILTER_CHANGES - , nfstat_root.update_every - , RRDSET_TYPE_LINE - ); - rrdset_flag_set(st_changes, RRDSET_FLAG_DETAIL); - - rd_inserted = rrddim_add(st_changes, nfstat_root.attr2name[CTA_STATS_INSERT], NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); - rd_deleted = rrddim_add(st_changes, nfstat_root.attr2name[CTA_STATS_DELETE], NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL); - rd_delete_list = rrddim_add(st_changes, nfstat_root.attr2name[CTA_STATS_DELETE_LIST], NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL); - } - else - rrdset_next(st_changes); - - rrddim_set_by_pointer(st_changes, rd_inserted, (collected_number) nfstat_root.metrics[CTA_STATS_INSERT]); - rrddim_set_by_pointer(st_changes, rd_deleted, (collected_number) nfstat_root.metrics[CTA_STATS_DELETE]); - rrddim_set_by_pointer(st_changes, rd_delete_list, (collected_number) nfstat_root.metrics[CTA_STATS_DELETE_LIST]); + if(!changes_chart_generated) { + changes_chart_generated = 1; - rrdset_done(st_changes); - } + printf("CHART %s.%s '' 'Connection Tracker Changes' 'changes/s' %s '' line %d %d detail %s\n" + , RRD_TYPE_NET_STAT_NETFILTER + , RRD_TYPE_NET_STAT_CONNTRACK "_changes" + , RRD_TYPE_NET_STAT_CONNTRACK + , NETDATA_CHART_PRIO_NETFILTER_CHANGES + , nfstat_root.update_every + , PLUGIN_NFACCT_NAME + ); + printf("DIMENSION %s '' incremental 1 1\n", nfstat_root.attr2name[CTA_STATS_INSERT]); + printf("DIMENSION %s '' incremental -1 1\n", nfstat_root.attr2name[CTA_STATS_DELETE]); + printf("DIMENSION %s '' incremental -1 1\n", nfstat_root.attr2name[CTA_STATS_DELETE_LIST]); + } + + printf( + "BEGIN %s.%s\n" + , RRD_TYPE_NET_STAT_NETFILTER + , RRD_TYPE_NET_STAT_CONNTRACK "_changes" + ); + printf( + "SET %s = %lld\n" + , nfstat_root.attr2name[CTA_STATS_INSERT] + , (collected_number) nfstat_root.metrics[CTA_STATS_INSERT] + ); + printf( + "SET %s = %lld\n" + , nfstat_root.attr2name[CTA_STATS_DELETE] + , (collected_number) nfstat_root.metrics[CTA_STATS_DELETE] + ); + printf( + "SET %s = %lld\n" + , nfstat_root.attr2name[CTA_STATS_DELETE_LIST] + , (collected_number) nfstat_root.metrics[CTA_STATS_DELETE_LIST] + ); + printf("END\n"); // ---------------------------------------------------------------- - { - static RRDSET *st_search = NULL; - static RRDDIM *rd_searched = NULL, *rd_restarted = NULL, *rd_found = NULL; - - if(!st_search) { - st_search = rrdset_create_localhost( - RRD_TYPE_NET_STAT_NETFILTER - , RRD_TYPE_NET_STAT_CONNTRACK "_search" - , NULL - , RRD_TYPE_NET_STAT_CONNTRACK - , NULL - , "Connection Tracker Searches" - , "searches/s" - , PLUGIN_NFACCT_NAME - , NULL - , NETDATA_CHART_PRIO_NETFILTER_SEARCH - , nfstat_root.update_every - , RRDSET_TYPE_LINE - ); - rrdset_flag_set(st_search, RRDSET_FLAG_DETAIL); - - rd_searched = rrddim_add(st_search, nfstat_root.attr2name[CTA_STATS_SEARCHED], NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); - rd_restarted = rrddim_add(st_search, nfstat_root.attr2name[CTA_STATS_SEARCH_RESTART], NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL); - rd_found = rrddim_add(st_search, nfstat_root.attr2name[CTA_STATS_FOUND], NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); - } - else - rrdset_next(st_search); + if(!search_chart_generated) { + search_chart_generated = 1; - rrddim_set_by_pointer(st_search, rd_searched, (collected_number) nfstat_root.metrics[CTA_STATS_SEARCHED]); - rrddim_set_by_pointer(st_search, rd_restarted, (collected_number) nfstat_root.metrics[CTA_STATS_SEARCH_RESTART]); - rrddim_set_by_pointer(st_search, rd_found, (collected_number) nfstat_root.metrics[CTA_STATS_FOUND]); - - rrdset_done(st_search); - } + printf("CHART %s.%s '' 'Connection Tracker Searches' 'searches/s' %s '' line %d %d detail %s\n" + , RRD_TYPE_NET_STAT_NETFILTER + , RRD_TYPE_NET_STAT_CONNTRACK "_search" + , RRD_TYPE_NET_STAT_CONNTRACK + , NETDATA_CHART_PRIO_NETFILTER_SEARCH + , nfstat_root.update_every + , PLUGIN_NFACCT_NAME + ); + printf("DIMENSION %s '' incremental 1 1\n", nfstat_root.attr2name[CTA_STATS_SEARCHED]); + printf("DIMENSION %s '' incremental -1 1\n", nfstat_root.attr2name[CTA_STATS_SEARCH_RESTART]); + printf("DIMENSION %s '' incremental 1 1\n", nfstat_root.attr2name[CTA_STATS_FOUND]); + } + + printf( + "BEGIN %s.%s\n" + , RRD_TYPE_NET_STAT_NETFILTER + , RRD_TYPE_NET_STAT_CONNTRACK "_search" + ); + printf( + "SET %s = %lld\n" + , nfstat_root.attr2name[CTA_STATS_SEARCHED] + , (collected_number) nfstat_root.metrics[CTA_STATS_SEARCHED] + ); + printf( + "SET %s = %lld\n" + , nfstat_root.attr2name[CTA_STATS_SEARCH_RESTART] + , (collected_number) nfstat_root.metrics[CTA_STATS_SEARCH_RESTART] + ); + printf( + "SET %s = %lld\n" + , nfstat_root.attr2name[CTA_STATS_FOUND] + , (collected_number) nfstat_root.metrics[CTA_STATS_FOUND] + ); + printf("END\n"); // ---------------------------------------------------------------- - { - static RRDSET *st_errors = NULL; - static RRDDIM *rd_error = NULL, *rd_insert_failed = NULL, *rd_drop = NULL, *rd_early_drop = NULL; - - if(!st_errors) { - st_errors = rrdset_create_localhost( - RRD_TYPE_NET_STAT_NETFILTER - , RRD_TYPE_NET_STAT_CONNTRACK "_errors" - , NULL - , RRD_TYPE_NET_STAT_CONNTRACK - , NULL - , "Connection Tracker Errors" - , "events/s" - , PLUGIN_NFACCT_NAME - , NULL - , NETDATA_CHART_PRIO_NETFILTER_ERRORS - , nfstat_root.update_every - , RRDSET_TYPE_LINE - ); - rrdset_flag_set(st_errors, RRDSET_FLAG_DETAIL); - - rd_error = rrddim_add(st_errors, nfstat_root.attr2name[CTA_STATS_ERROR], NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); - rd_insert_failed = rrddim_add(st_errors, nfstat_root.attr2name[CTA_STATS_INSERT_FAILED], NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL); - rd_drop = rrddim_add(st_errors, nfstat_root.attr2name[CTA_STATS_DROP], NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL); - rd_early_drop = rrddim_add(st_errors, nfstat_root.attr2name[CTA_STATS_EARLY_DROP], NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL); - } - else - rrdset_next(st_errors); + if(!errors_chart_generated) { + errors_chart_generated = 1; - rrddim_set_by_pointer(st_errors, rd_error, (collected_number) nfstat_root.metrics[CTA_STATS_ERROR]); - rrddim_set_by_pointer(st_errors, rd_insert_failed, (collected_number) nfstat_root.metrics[CTA_STATS_INSERT_FAILED]); - rrddim_set_by_pointer(st_errors, rd_drop, (collected_number) nfstat_root.metrics[CTA_STATS_DROP]); - rrddim_set_by_pointer(st_errors, rd_early_drop, (collected_number) nfstat_root.metrics[CTA_STATS_EARLY_DROP]); - - rrdset_done(st_errors); - } + printf("CHART %s.%s '' 'Connection Tracker Errors' 'events/s' %s '' line %d %d detail %s\n" + , RRD_TYPE_NET_STAT_NETFILTER + , RRD_TYPE_NET_STAT_CONNTRACK "_errors" + , RRD_TYPE_NET_STAT_CONNTRACK + , NETDATA_CHART_PRIO_NETFILTER_ERRORS + , nfstat_root.update_every + , PLUGIN_NFACCT_NAME + ); + printf("DIMENSION %s '' incremental 1 1\n", nfstat_root.attr2name[CTA_STATS_ERROR]); + printf("DIMENSION %s '' incremental -1 1\n", nfstat_root.attr2name[CTA_STATS_INSERT_FAILED]); + printf("DIMENSION %s '' incremental -1 1\n", nfstat_root.attr2name[CTA_STATS_DROP]); + printf("DIMENSION %s '' incremental -1 1\n", nfstat_root.attr2name[CTA_STATS_EARLY_DROP]); + } + + printf( + "BEGIN %s.%s\n" + , RRD_TYPE_NET_STAT_NETFILTER + , RRD_TYPE_NET_STAT_CONNTRACK "_errors" + ); + printf( + "SET %s = %lld\n" + , nfstat_root.attr2name[CTA_STATS_ERROR] + , (collected_number) nfstat_root.metrics[CTA_STATS_ERROR] + ); + printf( + "SET %s = %lld\n" + , nfstat_root.attr2name[CTA_STATS_INSERT_FAILED] + , (collected_number) nfstat_root.metrics[CTA_STATS_INSERT_FAILED] + ); + printf( + "SET %s = %lld\n" + , nfstat_root.attr2name[CTA_STATS_DROP] + , (collected_number) nfstat_root.metrics[CTA_STATS_DROP] + ); + printf( + "SET %s = %lld\n" + , nfstat_root.attr2name[CTA_STATS_EARLY_DROP] + , (collected_number) nfstat_root.metrics[CTA_STATS_EARLY_DROP] + ); + printf("END\n"); // ---------------------------------------------------------------- - { - static RRDSET *st_expect = NULL; - static RRDDIM *rd_new = NULL, *rd_created = NULL, *rd_deleted = NULL; - - if(!st_expect) { - st_expect = rrdset_create_localhost( - RRD_TYPE_NET_STAT_NETFILTER - , RRD_TYPE_NET_STAT_CONNTRACK "_expect" - , NULL - , RRD_TYPE_NET_STAT_CONNTRACK - , NULL - , "Connection Tracker Expectations" - , "expectations/s" - , PLUGIN_NFACCT_NAME - , NULL - , NETDATA_CHART_PRIO_NETFILTER_EXPECT - , nfstat_root.update_every - , RRDSET_TYPE_LINE - ); - rrdset_flag_set(st_expect, RRDSET_FLAG_DETAIL); - - rd_created = rrddim_add(st_expect, nfstat_root.attr2name_exp[CTA_STATS_EXP_CREATE], NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); - rd_deleted = rrddim_add(st_expect, nfstat_root.attr2name_exp[CTA_STATS_EXP_DELETE], NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL); - rd_new = rrddim_add(st_expect, nfstat_root.attr2name_exp[CTA_STATS_EXP_NEW], NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); - } - else - rrdset_next(st_expect); - - rrddim_set_by_pointer(st_expect, rd_created, (collected_number) nfstat_root.metrics_exp[CTA_STATS_EXP_CREATE]); - rrddim_set_by_pointer(st_expect, rd_deleted, (collected_number) nfstat_root.metrics_exp[CTA_STATS_EXP_DELETE]); - rrddim_set_by_pointer(st_expect, rd_new, (collected_number) nfstat_root.metrics_exp[CTA_STATS_EXP_NEW]); - - rrdset_done(st_expect); - } + if(!expect_chart_generated) { + expect_chart_generated = 1; + printf("CHART %s.%s '' 'Connection Tracker Expectations' 'expectations/s' %s '' line %d %d detail %s\n" + , RRD_TYPE_NET_STAT_NETFILTER + , RRD_TYPE_NET_STAT_CONNTRACK "_expect" + , RRD_TYPE_NET_STAT_CONNTRACK + , NETDATA_CHART_PRIO_NETFILTER_EXPECT + , nfstat_root.update_every + , PLUGIN_NFACCT_NAME + ); + printf("DIMENSION %s '' incremental 1 1\n", nfstat_root.attr2name[CTA_STATS_EXP_CREATE]); + printf("DIMENSION %s '' incremental -1 1\n", nfstat_root.attr2name[CTA_STATS_EXP_DELETE]); + printf("DIMENSION %s '' incremental 1 1\n", nfstat_root.attr2name[CTA_STATS_EXP_NEW]); + } + + printf( + "BEGIN %s.%s\n" + , RRD_TYPE_NET_STAT_NETFILTER + , RRD_TYPE_NET_STAT_CONNTRACK "_expect" + ); + printf( + "SET %s = %lld\n" + , nfstat_root.attr2name[CTA_STATS_EXP_CREATE] + , (collected_number) nfstat_root.metrics[CTA_STATS_EXP_CREATE] + ); + printf( + "SET %s = %lld\n" + , nfstat_root.attr2name[CTA_STATS_EXP_DELETE] + , (collected_number) nfstat_root.metrics[CTA_STATS_EXP_DELETE] + ); + printf( + "SET %s = %lld\n" + , nfstat_root.attr2name[CTA_STATS_EXP_NEW] + , (collected_number) nfstat_root.metrics[CTA_STATS_EXP_NEW] + ); + printf("END\n"); } #endif // HAVE_LINUX_NETFILTER_NFNETLINK_CONNTRACK_H @@ -497,8 +548,8 @@ struct nfacct_data { uint64_t pkts; uint64_t bytes; - RRDDIM *rd_bytes; - RRDDIM *rd_packets; + int packets_dimension_added; + int bytes_dimension_added; int updated; @@ -579,24 +630,6 @@ static int nfacct_init(int update_every) { return 0; } -static void nfacct_cleanup() { - if(nfacct_root.mnl) { - mnl_socket_close(nfacct_root.mnl); - nfacct_root.mnl = NULL; - } - - if(nfacct_root.nfacct_buffer) { - nfacct_free(nfacct_root.nfacct_buffer); - nfacct_root.nfacct_buffer = NULL; - } - - freez(nfacct_root.buf); - nfacct_root.buf = NULL; - nfacct_root.buf_size = 0; - - // TODO: cleanup the metrics linked list -} - static int nfacct_callback(const struct nlmsghdr *nlh, void *data) { (void)data; @@ -661,162 +694,216 @@ static int nfacct_collect() { } static void nfacct_send_metrics() { - static RRDSET *st_bytes = NULL, *st_packets = NULL; + static int bytes_chart_generated = 0, packets_chart_generated = 0; if(!nfacct_root.nfacct_metrics) return; struct nfacct_data *d; - if(!st_packets) { - st_packets = rrdset_create_localhost( - "netfilter" - , "nfacct_packets" - , NULL - , "nfacct" - , NULL - , "Netfilter Accounting Packets" - , "packets/s" - , PLUGIN_NFACCT_NAME - , NULL - , NETDATA_CHART_PRIO_NETFILTER_PACKETS - , nfacct_root.update_every - , RRDSET_TYPE_STACKED + if(!packets_chart_generated) { + packets_chart_generated = 1; + printf("CHART netfilter.nfacct_packets '' 'Netfilter Accounting Packets' 'packets/s' 'nfacct' '' stacked %d %d %s\n" + , NETDATA_CHART_PRIO_NETFILTER_PACKETS + , nfacct_root.update_every + , PLUGIN_NFACCT_NAME ); } - else rrdset_next(st_packets); for(d = nfacct_root.nfacct_metrics; d ; d = d->next) { if(likely(d->updated)) { - if(unlikely(!d->rd_packets)) - d->rd_packets = rrddim_add( - st_packets - , d->name - , NULL - , 1 - , nfacct_root.update_every - , RRD_ALGORITHM_INCREMENTAL - ); - - rrddim_set_by_pointer( - st_packets - , d->rd_packets + if(unlikely(!d->packets_dimension_added)) { + d->packets_dimension_added = 1; + printf("CHART netfilter.nfacct_packets '' 'Netfilter Accounting Packets' 'packets/s'\n"); + printf("DIMENSION %s '' incremental 1 %d\n", d->name, nfacct_root.update_every); + } + printf( + "BEGIN netfilter.nfacct_packets\n" + "SET %s = %lld\n" + "END\n" + , d->name , (collected_number)d->pkts ); } } - rrdset_done(st_packets); - // ---------------------------------------------------------------- - st_bytes = rrdset_find_bytype_localhost("netfilter", "nfacct_bytes"); - if(!st_bytes) { - st_bytes = rrdset_create_localhost( - "netfilter" - , "nfacct_bytes" - , NULL - , "nfacct" - , NULL - , "Netfilter Accounting Bandwidth" - , "kilobytes/s" - , PLUGIN_NFACCT_NAME - , NULL - , NETDATA_CHART_PRIO_NETFILTER_BYTES - , nfacct_root.update_every - , RRDSET_TYPE_STACKED + if(!bytes_chart_generated) { + bytes_chart_generated = 1; + printf("CHART netfilter.nfacct_bytes '' 'Netfilter Accounting Bandwidth' 'kilobytes/s' 'nfacct' '' stacked %d %d %s\n" + , NETDATA_CHART_PRIO_NETFILTER_BYTES + , nfacct_root.update_every + , PLUGIN_NFACCT_NAME ); } - else rrdset_next(st_bytes); for(d = nfacct_root.nfacct_metrics; d ; d = d->next) { if(likely(d->updated)) { - if(unlikely(!d->rd_bytes)) - d->rd_bytes = rrddim_add( - st_bytes - , d->name - , NULL - , 1 - , 1000 * nfacct_root.update_every - , RRD_ALGORITHM_INCREMENTAL - ); - - rrddim_set_by_pointer( - st_bytes - , d->rd_bytes - , (collected_number)d->bytes + if(unlikely(!d->bytes_dimension_added)) { + d->bytes_dimension_added = 1; + printf("CHART netfilter.nfacct_bytes '' 'Netfilter Accounting Bandwidth' 'kilobytes/s'\n"); + printf("DIMENSION %s '' incremental 1 %d\n", d->name, 1000 * nfacct_root.update_every); + } + printf( + "BEGIN netfilter.nfacct_bytes\n" + "SET %s = %lld\n" + "END\n" + , d->name + , (collected_number)d->bytes ); } } - - rrdset_done(st_bytes); } #endif // HAVE_LIBNETFILTER_ACCT -#endif // HAVE_LIBMNL -// ---------------------------------------------------------------------------- +int main(int argc, char **argv) { -static void nfacct_main_cleanup(void *ptr) { - struct netdata_static_thread *static_thread = (struct netdata_static_thread *)ptr; - static_thread->enabled = NETDATA_MAIN_THREAD_EXITING; - info("cleaning up..."); + // ------------------------------------------------------------------------ + // initialization of netdata plugin -#ifdef DO_NFACCT - nfacct_cleanup(); -#endif + program_name = "nfacct.plugin"; -#ifdef DO_NFSTAT - nfstat_cleanup(); -#endif + // disable syslog + error_log_syslog = 0; - static_thread->enabled = NETDATA_MAIN_THREAD_EXITED; -} + // set errors flood protection to 100 logs per hour + error_log_errors_per_period = 100; + error_log_throttle_period = 3600; + + // ------------------------------------------------------------------------ + // parse command line parameters + + int i, freq = 0; + for(i = 1; i < argc ; i++) { + if(isdigit(*argv[i]) && !freq) { + int n = str2i(argv[i]); + if(n > 0 && n < 86400) { + freq = n; + continue; + } + } + 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) { + printf("nfacct.plugin %s\n", VERSION); + exit(0); + } + else if(strcmp("debug", argv[i]) == 0) { + debug = 1; + continue; + } + else if(strcmp("-h", argv[i]) == 0 || strcmp("--help", argv[i]) == 0) { + fprintf(stderr, + "\n" + " netdata nfacct.plugin %s\n" + " Copyright (C) 2015-2017 Costa Tsaousis \n" + " Released under GNU General Public License v3 or later.\n" + " All rights reserved.\n" + "\n" + " This program is a data collector plugin for netdata.\n" + "\n" + " Available command line options:\n" + "\n" + " COLLECTION_FREQUENCY data collection frequency in seconds\n" + " minimum: %d\n" + "\n" + " debug enable verbose output\n" + " default: disabled\n" + "\n" + " -v\n" + " -V\n" + " --version print version and exit\n" + "\n" + " -h\n" + " --help print this message and exit\n" + "\n" + " For more information:\n" + " https://github.com/netdata/netdata/tree/master/collectors/nfacct.plugin\n" + "\n" + , VERSION + , netdata_update_every + ); + exit(1); + } -void *nfacct_main(void *ptr) { - netdata_thread_cleanup_push(nfacct_main_cleanup, ptr); + error("nfacct.plugin: ignoring parameter '%s'", argv[i]); + } - int update_every = (int)config_get_number("plugin:netfilter", "update every", localhost->rrd_update_every); - if(update_every < localhost->rrd_update_every) - update_every = localhost->rrd_update_every; + errno = 0; + + if(freq >= netdata_update_every) + netdata_update_every = freq; + else if(freq) + error("update frequency %d seconds is too small for NFACCT. Using %d.", freq, netdata_update_every); #ifdef DO_NFACCT - int nfacct = !nfacct_init(update_every); + if(debug) fprintf(stderr, "freeipmi.plugin: calling nfacct_init()\n"); + int nfacct = !nfacct_init(netdata_update_every); #endif #ifdef DO_NFSTAT - int nfstat = !nfstat_init(update_every); + if(debug) fprintf(stderr, "freeipmi.plugin: calling nfstat_init()\n"); + int nfstat = !nfstat_init(netdata_update_every); #endif // ------------------------------------------------------------------------ + // the main loop + + if(debug) fprintf(stderr, "nfacct.plugin: starting data collection\n"); + + time_t started_t = now_monotonic_sec(); + + size_t iteration; + usec_t step = netdata_update_every * USEC_PER_SEC; - usec_t step = update_every * USEC_PER_SEC; heartbeat_t hb; heartbeat_init(&hb); - for(;;) { - heartbeat_next(&hb, step); + for(iteration = 0; 1; iteration++) { + usec_t dt = heartbeat_next(&hb, step); if(unlikely(netdata_exit)) break; + if(debug && iteration) + fprintf(stderr, "nfacct.plugin: iteration %zu, dt %llu usec\n" + , iteration + , dt + ); + #ifdef DO_NFACCT if(likely(nfacct)) { + if(debug) fprintf(stderr, "nfacct.plugin: calling nfacct_collect()\n"); nfacct = !nfacct_collect(); - if(likely(nfacct)) + if(likely(nfacct)) { + if(debug) fprintf(stderr, "nfacct.plugin: calling nfacct_send_metrics()\n"); nfacct_send_metrics(); + } } #endif #ifdef DO_NFSTAT if(likely(nfstat)) { + if(debug) fprintf(stderr, "nfacct.plugin: calling nfstat_collect()\n"); nfstat = !nfstat_collect(); - if(likely(nfstat)) + if(likely(nfstat)) { + if(debug) fprintf(stderr, "nfacct.plugin: calling nfstat_send_metrics()\n"); nfstat_send_metrics(); + } } #endif + + fflush(stdout); + + // restart check (14400 seconds) + if(now_monotonic_sec() - started_t > 14400) break; } - netdata_thread_cleanup_pop(1); - return NULL; + info("NFACCT process exiting"); +} + +#else // !HAVE_LIBMNL + +int main(int argc, char **argv) { + fatal("nfacct.plugin is not compiled."); } -#endif // INTERNAL_PLUGIN_NFACCT +#endif // !HAVE_LIBMNL -- cgit v1.2.3