summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am10
-rw-r--r--src/Makefile.in15
-rw-r--r--src/adaptive_resortable_list.c11
-rw-r--r--src/adaptive_resortable_list.h3
-rw-r--r--src/appconfig.c6
-rw-r--r--src/apps_plugin.c8
-rw-r--r--src/avl.c5
-rw-r--r--src/backends.c10
-rw-r--r--src/cgroup-network.c184
-rw-r--r--src/clocks.c6
-rw-r--r--src/common.c7
-rw-r--r--src/common.h17
-rw-r--r--src/eval.c30
-rw-r--r--src/eval.h2
-rw-r--r--src/freebsd_devstat.c177
-rw-r--r--src/freebsd_getifaddrs.c14
-rw-r--r--src/freebsd_getmntinfo.c4
-rw-r--r--src/freebsd_ipfw.c10
-rw-r--r--src/freebsd_kstat_zfs.c98
-rw-r--r--src/freebsd_sysctl.c1412
-rw-r--r--src/freeipmi_plugin.c56
-rw-r--r--src/global_statistics.c381
-rw-r--r--src/health.c13
-rw-r--r--src/health.h88
-rw-r--r--src/health_config.c14
-rw-r--r--src/health_log.c4
-rw-r--r--src/ipc.c81
-rw-r--r--src/macos_fw.c260
-rw-r--r--src/macos_mach_smi.c83
-rw-r--r--src/macos_sysctl.c519
-rw-r--r--src/main.c225
-rw-r--r--src/main.h6
-rw-r--r--src/plugin_checks.c52
-rw-r--r--src/plugin_checks.h2
-rw-r--r--src/plugin_freebsd.c19
-rw-r--r--src/plugin_freebsd.h2
-rw-r--r--src/plugin_idlejitter.c2
-rw-r--r--src/plugin_nfacct.c14
-rw-r--r--src/plugin_proc.c19
-rw-r--r--src/plugin_proc.h2
-rw-r--r--src/plugin_proc_diskspace.c70
-rw-r--r--src/plugin_tc.c170
-rw-r--r--src/plugins_d.c292
-rw-r--r--src/plugins_d.h9
-rw-r--r--src/proc_diskstats.c312
-rw-r--r--src/proc_interrupts.c4
-rw-r--r--src/proc_loadavg.c4
-rw-r--r--src/proc_meminfo.c14
-rw-r--r--src/proc_net_dev.c93
-rw-r--r--src/proc_net_ip_vs_stats.c63
-rw-r--r--src/proc_net_netstat.c76
-rw-r--r--src/proc_net_rpc_nfs.c403
-rw-r--r--src/proc_net_rpc_nfsd.c947
-rw-r--r--src/proc_net_snmp.c1217
-rw-r--r--src/proc_net_snmp6.c917
-rw-r--r--src/proc_net_sockstat.c514
-rw-r--r--src/proc_net_sockstat6.c269
-rw-r--r--src/proc_net_softnet_stat.c32
-rw-r--r--src/proc_net_stat_conntrack.c215
-rw-r--r--src/proc_net_stat_synproxy.c78
-rw-r--r--src/proc_softirqs.c4
-rw-r--r--src/proc_spl_kstat_zfs.c16
-rw-r--r--src/proc_stat.c16
-rw-r--r--src/proc_sys_kernel_random_entropy_avail.c2
-rw-r--r--src/proc_uptime.c2
-rw-r--r--src/proc_vmstat.c14
-rw-r--r--src/registry.c58
-rw-r--r--src/rrd.h97
-rw-r--r--src/rrd2json.c82
-rw-r--r--src/rrd2json.h1
-rw-r--r--src/rrdcalc.c56
-rw-r--r--src/rrdcalctemplate.c40
-rw-r--r--src/rrddim.c8
-rw-r--r--src/rrddimvar.c42
-rw-r--r--src/rrdfamily.c19
-rw-r--r--src/rrdhost.c105
-rw-r--r--src/rrdpush.c860
-rw-r--r--src/rrdpush.h2
-rw-r--r--src/rrdset.c75
-rw-r--r--src/rrdsetvar.c113
-rw-r--r--src/rrdvar.c93
-rw-r--r--src/signals.h2
-rw-r--r--src/simple_pattern.c145
-rw-r--r--src/simple_pattern.h5
-rw-r--r--src/socket.c51
-rw-r--r--src/socket.h7
-rw-r--r--src/statsd.c562
-rw-r--r--src/storage_number.c2
-rw-r--r--src/storage_number.h3
-rw-r--r--src/sys_devices_system_edac_mc.c4
-rw-r--r--src/sys_devices_system_node.c2
-rw-r--r--src/sys_fs_cgroup.c87
-rw-r--r--src/sys_kernel_mm_ksm.c6
-rw-r--r--src/unit_test.c66
-rw-r--r--src/web_api_v1.c359
-rw-r--r--src/web_api_v1.h2
-rw-r--r--src/web_buffer_svg.c72
-rw-r--r--src/web_buffer_svg.h2
-rw-r--r--src/web_client.c155
-rw-r--r--src/web_client.h30
-rw-r--r--src/web_server.c152
-rw-r--r--src/zfs_common.c56
-rw-r--r--src/zfs_common.h10
103 files changed, 9269 insertions, 3786 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index feddc326..1a1d3748 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -137,7 +137,8 @@ netdata_SOURCES = \
sys_devices_system_node.c \
unit_test.c \
unit_test.h \
- url.c url.h \
+ url.c \
+ url.h \
web_api_old.c \
web_api_old.h \
web_api_v1.c \
@@ -176,7 +177,8 @@ netdata_SOURCES += \
$(NULL)
else
netdata_SOURCES += \
- ipc.c ipc.h \
+ ipc.c \
+ ipc.h \
plugin_proc.c \
plugin_proc.h \
plugin_proc_diskspace.c \
@@ -193,6 +195,8 @@ netdata_SOURCES += \
proc_net_rpc_nfsd.c \
proc_net_snmp.c \
proc_net_snmp6.c \
+ proc_net_sockstat.c \
+ proc_net_sockstat6.c \
proc_net_softnet_stat.c \
proc_net_stat_conntrack.c \
proc_net_stat_synproxy.c \
@@ -258,6 +262,8 @@ cgroup_network_SOURCES = \
inlined.h \
log.c log.h \
procfile.c procfile.h \
+ popen.c popen.h \
+ signals.c signals.h \
$(NULL)
cgroup_network_LDADD = \
diff --git a/src/Makefile.in b/src/Makefile.in
index bc73c712..bf902c21 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -106,7 +106,8 @@ plugins_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3)
@FREEBSD_FALSE@@MACOS_TRUE@ $(NULL)
@FREEBSD_FALSE@@MACOS_FALSE@am__append_6 = \
-@FREEBSD_FALSE@@MACOS_FALSE@ ipc.c ipc.h \
+@FREEBSD_FALSE@@MACOS_FALSE@ ipc.c \
+@FREEBSD_FALSE@@MACOS_FALSE@ ipc.h \
@FREEBSD_FALSE@@MACOS_FALSE@ plugin_proc.c \
@FREEBSD_FALSE@@MACOS_FALSE@ plugin_proc.h \
@FREEBSD_FALSE@@MACOS_FALSE@ plugin_proc_diskspace.c \
@@ -123,6 +124,8 @@ plugins_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3)
@FREEBSD_FALSE@@MACOS_FALSE@ proc_net_rpc_nfsd.c \
@FREEBSD_FALSE@@MACOS_FALSE@ proc_net_snmp.c \
@FREEBSD_FALSE@@MACOS_FALSE@ proc_net_snmp6.c \
+@FREEBSD_FALSE@@MACOS_FALSE@ proc_net_sockstat.c \
+@FREEBSD_FALSE@@MACOS_FALSE@ proc_net_sockstat6.c \
@FREEBSD_FALSE@@MACOS_FALSE@ proc_net_softnet_stat.c \
@FREEBSD_FALSE@@MACOS_FALSE@ proc_net_stat_conntrack.c \
@FREEBSD_FALSE@@MACOS_FALSE@ proc_net_stat_synproxy.c \
@@ -179,7 +182,8 @@ apps_plugin_OBJECTS = $(am_apps_plugin_OBJECTS)
am__DEPENDENCIES_1 =
apps_plugin_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
am_cgroup_network_OBJECTS = cgroup-network.$(OBJEXT) clocks.$(OBJEXT) \
- common.$(OBJEXT) log.$(OBJEXT) procfile.$(OBJEXT)
+ common.$(OBJEXT) log.$(OBJEXT) procfile.$(OBJEXT) \
+ popen.$(OBJEXT) signals.$(OBJEXT)
cgroup_network_OBJECTS = $(am_cgroup_network_OBJECTS)
cgroup_network_DEPENDENCIES = $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1)
@@ -224,6 +228,7 @@ am__netdata_SOURCES_DIST = adaptive_resortable_list.c \
proc_loadavg.c proc_meminfo.c proc_net_dev.c \
proc_net_ip_vs_stats.c proc_net_netstat.c proc_net_rpc_nfs.c \
proc_net_rpc_nfsd.c proc_net_snmp.c proc_net_snmp6.c \
+ proc_net_sockstat.c proc_net_sockstat6.c \
proc_net_softnet_stat.c proc_net_stat_conntrack.c \
proc_net_stat_synproxy.c proc_spl_kstat_zfs.c proc_stat.c \
proc_sys_kernel_random_entropy_avail.c proc_vmstat.c \
@@ -254,6 +259,8 @@ am__netdata_SOURCES_DIST = adaptive_resortable_list.c \
@FREEBSD_FALSE@@MACOS_FALSE@ proc_net_rpc_nfsd.$(OBJEXT) \
@FREEBSD_FALSE@@MACOS_FALSE@ proc_net_snmp.$(OBJEXT) \
@FREEBSD_FALSE@@MACOS_FALSE@ proc_net_snmp6.$(OBJEXT) \
+@FREEBSD_FALSE@@MACOS_FALSE@ proc_net_sockstat.$(OBJEXT) \
+@FREEBSD_FALSE@@MACOS_FALSE@ proc_net_sockstat6.$(OBJEXT) \
@FREEBSD_FALSE@@MACOS_FALSE@ proc_net_softnet_stat.$(OBJEXT) \
@FREEBSD_FALSE@@MACOS_FALSE@ proc_net_stat_conntrack.$(OBJEXT) \
@FREEBSD_FALSE@@MACOS_FALSE@ proc_net_stat_synproxy.$(OBJEXT) \
@@ -616,6 +623,8 @@ cgroup_network_SOURCES = \
inlined.h \
log.c log.h \
procfile.c procfile.h \
+ popen.c popen.h \
+ signals.c signals.h \
$(NULL)
cgroup_network_LDADD = \
@@ -815,6 +824,8 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proc_net_rpc_nfsd.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proc_net_snmp.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proc_net_snmp6.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proc_net_sockstat.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proc_net_sockstat6.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proc_net_softnet_stat.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proc_net_stat_conntrack.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proc_net_stat_synproxy.Po@am__quote@
diff --git a/src/adaptive_resortable_list.c b/src/adaptive_resortable_list.c
index f74c53ea..add1d8c9 100644
--- a/src/adaptive_resortable_list.c
+++ b/src/adaptive_resortable_list.c
@@ -2,7 +2,7 @@
// the default processor() of the ARL
// can be overwritten at arl_create()
-static inline void arl_callback_str2ull(const char *name, uint32_t hash, const char *value, void *dst) {
+inline void arl_callback_str2ull(const char *name, uint32_t hash, const char *value, void *dst) {
(void)name;
(void)hash;
@@ -11,6 +11,15 @@ static inline void arl_callback_str2ull(const char *name, uint32_t hash, const c
// fprintf(stderr, "name '%s' with hash %u and value '%s' is %llu\n", name, hash, value, *d);
}
+inline void arl_callback_str2kernel_uint_t(const char *name, uint32_t hash, const char *value, void *dst) {
+ (void)name;
+ (void)hash;
+
+ register kernel_uint_t *d = dst;
+ *d = str2kernel_uint_t(value);
+ // fprintf(stderr, "name '%s' with hash %u and value '%s' is %llu\n", name, hash, value, (unsigned long long)*d);
+}
+
// create a new ARL
ARL_BASE *arl_create(const char *name, void (*processor)(const char *, uint32_t, const char *, void *), size_t rechecks) {
ARL_BASE *base = callocz(1, sizeof(ARL_BASE));
diff --git a/src/adaptive_resortable_list.h b/src/adaptive_resortable_list.h
index 609cd0c4..c007fa31 100644
--- a/src/adaptive_resortable_list.h
+++ b/src/adaptive_resortable_list.h
@@ -110,6 +110,9 @@ extern int arl_find_or_create_and_relink(ARL_BASE *base, const char *s, const ch
// begin an ARL iteration
extern void arl_begin(ARL_BASE *base);
+extern void arl_callback_str2ull(const char *name, uint32_t hash, const char *value, void *dst);
+extern void arl_callback_str2kernel_uint_t(const char *name, uint32_t hash, const char *value, void *dst);
+
// check a keyword against the ARL
// this is to be called for each keyword read from source data
// s = the keyword, as collected
diff --git a/src/appconfig.c b/src/appconfig.c
index 2c7721b8..40cade81 100644
--- a/src/appconfig.c
+++ b/src/appconfig.c
@@ -567,6 +567,7 @@ void appconfig_generate(struct config *root, BUFFER *wb, int only_changed)
else pri = 2;
if(i == pri) {
+ int loaded = 0;
int used = 0;
int changed = 0;
int count = 0;
@@ -574,13 +575,14 @@ void appconfig_generate(struct config *root, BUFFER *wb, int only_changed)
config_section_wrlock(co);
for(cv = co->values; cv ; cv = cv->next) {
used += (cv->flags & CONFIG_VALUE_USED)?1:0;
+ loaded += (cv->flags & CONFIG_VALUE_LOADED)?1:0;
changed += (cv->flags & CONFIG_VALUE_CHANGED)?1:0;
count++;
}
config_section_unlock(co);
if(!count) continue;
- if(only_changed && !changed) continue;
+ if(only_changed && !changed && !loaded) continue;
if(!used) {
buffer_sprintf(wb, "\n# section '%s' is not used.", co->name);
@@ -594,7 +596,7 @@ void appconfig_generate(struct config *root, BUFFER *wb, int only_changed)
if(used && !(cv->flags & CONFIG_VALUE_USED)) {
buffer_sprintf(wb, "\n\t# option '%s' is not used.\n", cv->name);
}
- buffer_sprintf(wb, "\t%s%s = %s\n", ((!(cv->flags & CONFIG_VALUE_CHANGED)) && (cv->flags & CONFIG_VALUE_USED))?"# ":"", cv->name, cv->value);
+ buffer_sprintf(wb, "\t%s%s = %s\n", ((!(cv->flags & CONFIG_VALUE_LOADED)) && (!(cv->flags & CONFIG_VALUE_CHANGED)) && (cv->flags & CONFIG_VALUE_USED))?"# ":"", cv->name, cv->value);
}
config_section_unlock(co);
}
diff --git a/src/apps_plugin.c b/src/apps_plugin.c
index c0eb5c08..3ac79777 100644
--- a/src/apps_plugin.c
+++ b/src/apps_plugin.c
@@ -1572,14 +1572,22 @@ static inline int read_pid_file_descriptors(struct pid_stat *p, void *ptr) {
break;
default:
/* print protocol number and socket address */
+#if __FreeBSD_version < 1200031
sprintf(fdsname, "socket: other: %d %s %s", fds->kf_sock_protocol, fds->kf_sa_local.__ss_pad1, fds->kf_sa_local.__ss_pad2);
+#else
+ sprintf(fdsname, "socket: other: %d %s %s", fds->kf_sock_protocol, fds->kf_un.kf_sock.kf_sa_local.__ss_pad1, fds->kf_un.kf_sock.kf_sa_local.__ss_pad2);
+#endif
}
break;
case KF_TYPE_PIPE:
sprintf(fdsname, "pipe: %lu %lu", fds->kf_un.kf_pipe.kf_pipe_addr, fds->kf_un.kf_pipe.kf_pipe_peer);
break;
case KF_TYPE_PTS:
+#if __FreeBSD_version < 1200031
sprintf(fdsname, "other: pts: %u", fds->kf_un.kf_pts.kf_pts_dev);
+#else
+ sprintf(fdsname, "other: pts: %lu", fds->kf_un.kf_pts.kf_pts_dev);
+#endif
break;
case KF_TYPE_SHM:
sprintf(fdsname, "other: shm: %s size: %lu", fds->kf_path, fds->kf_un.kf_file.kf_file_size);
diff --git a/src/avl.c b/src/avl.c
index 0ea119a7..a2c6911e 100644
--- a/src/avl.c
+++ b/src/avl.c
@@ -306,7 +306,10 @@ int avl_walker(avl *node, int (*callback)(void *entry, void *data), void *data)
}
int avl_traverse(avl_tree *t, int (*callback)(void *entry, void *data), void *data) {
- return avl_walker(t->root, callback, data);
+ if(t->root)
+ return avl_walker(t->root, callback, data);
+ else
+ return 0;
}
// ---------------------------
diff --git a/src/backends.c b/src/backends.c
index eed4ab40..df9a1ccb 100644
--- a/src/backends.c
+++ b/src/backends.c
@@ -615,18 +615,18 @@ void *backends_main(void *ptr) {
chart_backend_reconnects = 0,
chart_backend_latency = 0;
- RRDSET *chart_metrics = rrdset_create_localhost("netdata", "backend_metrics", NULL, "backend", NULL, "Netdata Buffered Metrics", "metrics", 130600, backend_update_every, RRDSET_TYPE_LINE);
+ RRDSET *chart_metrics = rrdset_create_localhost("netdata", "backend_metrics", NULL, "backend", NULL, "Netdata Buffered Metrics", "metrics", "backends", NULL, 130600, backend_update_every, RRDSET_TYPE_LINE);
rrddim_add(chart_metrics, "buffered", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
rrddim_add(chart_metrics, "lost", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
rrddim_add(chart_metrics, "sent", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
- RRDSET *chart_bytes = rrdset_create_localhost("netdata", "backend_bytes", NULL, "backend", NULL, "Netdata Backend Data Size", "KB", 130610, backend_update_every, RRDSET_TYPE_AREA);
+ RRDSET *chart_bytes = rrdset_create_localhost("netdata", "backend_bytes", NULL, "backend", NULL, "Netdata Backend Data Size", "KB", "backends", NULL, 130610, backend_update_every, RRDSET_TYPE_AREA);
rrddim_add(chart_bytes, "buffered", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
rrddim_add(chart_bytes, "lost", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
rrddim_add(chart_bytes, "sent", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
rrddim_add(chart_bytes, "received", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
- RRDSET *chart_ops = rrdset_create_localhost("netdata", "backend_ops", NULL, "backend", NULL, "Netdata Backend Operations", "operations", 130630, backend_update_every, RRDSET_TYPE_LINE);
+ RRDSET *chart_ops = rrdset_create_localhost("netdata", "backend_ops", NULL, "backend", NULL, "Netdata Backend Operations", "operations", "backends", NULL, 130630, backend_update_every, RRDSET_TYPE_LINE);
rrddim_add(chart_ops, "write", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
rrddim_add(chart_ops, "discard", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
rrddim_add(chart_ops, "reconnect", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
@@ -640,11 +640,11 @@ void *backends_main(void *ptr) {
*
* issue #1432 and https://www.softlab.ntua.gr/facilities/documentation/unix/unix-socket-faq/unix-socket-faq-2.html
*
- RRDSET *chart_latency = rrdset_create_localhost("netdata", "backend_latency", NULL, "backend", NULL, "Netdata Backend Latency", "ms", 130620, backend_update_every, RRDSET_TYPE_AREA);
+ RRDSET *chart_latency = rrdset_create_localhost("netdata", "backend_latency", NULL, "backend", NULL, "Netdata Backend Latency", "ms", "backends", NULL, 130620, backend_update_every, RRDSET_TYPE_AREA);
rrddim_add(chart_latency, "latency", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
*/
- RRDSET *chart_rusage = rrdset_create_localhost("netdata", "backend_thread_cpu", NULL, "backend", NULL, "NetData Backend Thread CPU usage", "milliseconds/s", 130630, backend_update_every, RRDSET_TYPE_STACKED);
+ RRDSET *chart_rusage = rrdset_create_localhost("netdata", "backend_thread_cpu", NULL, "backend", NULL, "NetData Backend Thread CPU usage", "milliseconds/s", "backends", NULL, 130630, backend_update_every, RRDSET_TYPE_STACKED);
rrddim_add(chart_rusage, "user", NULL, 1, 1000, RRD_ALGORITHM_INCREMENTAL);
rrddim_add(chart_rusage, "system", NULL, 1, 1000, RRD_ALGORITHM_INCREMENTAL);
diff --git a/src/cgroup-network.c b/src/cgroup-network.c
index 8894d60e..7b1a0234 100644
--- a/src/cgroup-network.c
+++ b/src/cgroup-network.c
@@ -1,4 +1,5 @@
#include "common.h"
+#include <libgen.h>
#ifdef HAVE_SETNS
#ifndef _GNU_SOURCE
@@ -14,6 +15,10 @@ void netdata_cleanup_and_exit(int ret) {
exit(ret);
}
+void health_reload(void) {};
+void rrdhost_save_all(void) {};
+
+
struct iface {
const char *device;
uint32_t hash;
@@ -269,38 +274,62 @@ pid_t read_pid_from_cgroup(const char *path) {
return pid;
}
-void usage(void) {
- fprintf(stderr, "%s [ -p PID | --pid PID | --cgroup /path/to/cgroup ]\n", program_name);
- exit(1);
-}
-int main(int argc, char **argv) {
- pid_t pid = 0;
+// ----------------------------------------------------------------------------
+// send the result to netdata
- program_name = argv[0];
- program_version = VERSION;
- error_log_syslog = 0;
+struct found_device {
+ const char *host_device;
+ const char *guest_device;
- if(argc == 2 && (!strcmp(argv[1], "version") || !strcmp(argv[1], "-version") || !strcmp(argv[1], "--version") || !strcmp(argv[1], "-v") || !strcmp(argv[1], "-V"))) {
- fprintf(stderr, "cgroup-network %s\n", VERSION);
- exit(0);
- }
+ uint32_t host_device_hash;
- if(argc != 3)
- usage();
+ struct found_device *next;
+} *detected_devices = NULL;
- if(!strcmp(argv[1], "-p") || !strcmp(argv[1], "--pid")) {
- pid = atoi(argv[2]);
+void add_device(const char *host, const char *guest) {
+ uint32_t hash = simple_hash(host);
+
+ if(guest && (!*guest || strcmp(host, guest) == 0))
+ guest = NULL;
+
+ struct found_device *f;
+ for(f = detected_devices; f ; f = f->next) {
+ if(f->host_device_hash == hash && strcmp(host, f->host_device) == 0) {
+
+ if(guest && !f->guest_device)
+ f->guest_device = strdup(guest);
+
+ return;
+ }
}
- else if(!strcmp(argv[1], "--cgroup")) {
- pid = read_pid_from_cgroup(argv[2]);
+
+ f = mallocz(sizeof(struct found_device));
+ f->host_device = strdupz(host);
+ f->host_device_hash = hash;
+ f->guest_device = (guest)?strdupz(guest):NULL;
+ f->next = detected_devices;
+ detected_devices = f;
+}
+
+int send_devices(void) {
+ int found = 0;
+
+ struct found_device *f;
+ for(f = detected_devices; f ; f = f->next) {
+ found++;
+ printf("%s %s\n", f->host_device, (f->guest_device)?f->guest_device:f->host_device);
}
- else
- usage();
- if(pid <= 0)
- fatal("Invalid pid %d", (int)pid);
+ return found;
+}
+
+// ----------------------------------------------------------------------------
+// this function should be called only **ONCE**
+// also it has to be the **LAST** to be called
+// since it switches namespaces, so after this call, everything is different!
+void detect_veth_interfaces(pid_t pid) {
struct iface *host, *cgroup, *h, *c;
const char *prefix = getenv("NETDATA_HOST_PREFIX");
@@ -321,20 +350,117 @@ int main(int argc, char **argv) {
if(!eligible_ifaces(cgroup))
fatal("there are not double-linked cgroup interfaces available.");
- int found = 0;
for(h = host; h ; h = h->next) {
if(iface_is_eligible(h)) {
for (c = cgroup; c; c = c->next) {
if(iface_is_eligible(c) && h->ifindex == c->iflink && h->iflink == c->ifindex) {
- printf("%s %s\n", h->device, c->device);
- found++;
+ add_device(h->device, c->device);
}
}
}
}
+}
- if(!found)
- return 1;
+// ----------------------------------------------------------------------------
+// call the external helper
- return 0;
+#define CGROUP_NETWORK_INTERFACE_MAX_LINE 2048
+void call_the_helper(const char *me, pid_t pid, const char *cgroup) {
+ const char *pluginsdir = getenv("NETDATA_PLUGINS_DIR");
+ char *m = NULL;
+
+ if(!pluginsdir || !*pluginsdir) {
+ m = strdupz(me);
+ pluginsdir = dirname(m);
+ }
+
+ if(setresuid(0, 0, 0) == -1)
+ error("setresuid(0, 0, 0) failed.");
+
+ char buffer[CGROUP_NETWORK_INTERFACE_MAX_LINE + 1];
+ if(cgroup)
+ snprintfz(buffer, CGROUP_NETWORK_INTERFACE_MAX_LINE, "exec %s/cgroup-network-helper.sh --cgroup '%s'", pluginsdir, cgroup);
+ else
+ snprintfz(buffer, CGROUP_NETWORK_INTERFACE_MAX_LINE, "exec %s/cgroup-network-helper.sh --pid %d", pluginsdir, pid);
+
+ info("running: %s", buffer);
+
+ pid_t cgroup_pid;
+ FILE *fp = mypopen(buffer, &cgroup_pid);
+ if(fp) {
+ char *s;
+ while((s = fgets(buffer, CGROUP_NETWORK_INTERFACE_MAX_LINE, fp))) {
+ trim(s);
+
+ if(*s && *s != '\n') {
+ char *t = s;
+ while(*t && *t != ' ') t++;
+ if(*t == ' ') {
+ *t = '\0';
+ t++;
+ }
+
+ if(!*s || !*t) continue;
+ add_device(s, t);
+ }
+ }
+
+ mypclose(fp, cgroup_pid);
+ }
+ else
+ error("cannot execute cgroup-network helper script: %s", buffer);
+
+ freez(m);
+}
+
+
+// ----------------------------------------------------------------------------
+// main
+
+void usage(void) {
+ fprintf(stderr, "%s [ -p PID | --pid PID | --cgroup /path/to/cgroup ]\n", program_name);
+ exit(1);
+}
+
+int main(int argc, char **argv) {
+ pid_t pid = 0;
+
+ program_name = argv[0];
+ program_version = VERSION;
+ error_log_syslog = 0;
+
+ if(argc == 2 && (!strcmp(argv[1], "version") || !strcmp(argv[1], "-version") || !strcmp(argv[1], "--version") || !strcmp(argv[1], "-v") || !strcmp(argv[1], "-V"))) {
+ fprintf(stderr, "cgroup-network %s\n", VERSION);
+ exit(0);
+ }
+
+ if(argc != 3)
+ usage();
+
+ if(!strcmp(argv[1], "-p") || !strcmp(argv[1], "--pid")) {
+ pid = atoi(argv[2]);
+
+ if(pid <= 0) {
+ errno = 0;
+ fatal("Invalid pid %d given", (int) pid);
+ }
+
+ call_the_helper(argv[0], pid, NULL);
+ }
+ else if(!strcmp(argv[1], "--cgroup")) {
+ pid = read_pid_from_cgroup(argv[2]);
+ call_the_helper(argv[0], pid, argv[2]);
+
+ if(pid <= 0 && !detected_devices) {
+ errno = 0;
+ fatal("Invalid pid %d read from cgroup '%s'", (int) pid, argv[2]);
+ }
+ }
+ else
+ usage();
+
+ if(pid > 0)
+ detect_veth_interfaces(pid);
+
+ return send_devices();
}
diff --git a/src/clocks.c b/src/clocks.c
index 8f2aa740..2b1c36e3 100644
--- a/src/clocks.c
+++ b/src/clocks.c
@@ -115,8 +115,12 @@ usec_t heartbeat_next(heartbeat_t *hb, usec_t tick)
if(likely(*hb != 0ULL)) {
usec_t dt = now - *hb;
*hb = now;
- if(unlikely(dt >= tick + tick / 2))
+
+ if(unlikely(dt >= tick + tick / 2)) {
+ errno = 0;
error("heartbeat missed %llu microseconds", dt - tick);
+ }
+
return dt;
}
else {
diff --git a/src/common.c b/src/common.c
index 5a953672..a976e96e 100644
--- a/src/common.c
+++ b/src/common.c
@@ -17,6 +17,7 @@ char *netdata_configured_cache_dir = NULL;
char *netdata_configured_varlib_dir = NULL;
char *netdata_configured_home_dir = NULL;
char *netdata_configured_host_prefix = NULL;
+char *netdata_configured_timezone = NULL;
int enable_ksm = 1;
@@ -1119,10 +1120,14 @@ pid_t gettid(void) {
#ifdef __FreeBSD__
return (pid_t)pthread_getthreadid_np();
#elif defined(__APPLE__)
+#if (defined __MAC_OS_X_VERSION_MIN_REQUIRED && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060)
uint64_t curthreadid;
pthread_threadid_np(NULL, &curthreadid);
return (pid_t)curthreadid;
-#else
+#else /* __MAC_OS_X_VERSION_MIN_REQUIRED */
+ return (pid_t)pthread_self;
+#endif /* __MAC_OS_X_VERSION_MIN_REQUIRED */
+#else /* __APPLE__*/
return (pid_t)syscall(SYS_gettid);
#endif /* __FreeBSD__, __APPLE__*/
}
diff --git a/src/common.h b/src/common.h
index 51d2bba5..667fe9d7 100644
--- a/src/common.h
+++ b/src/common.h
@@ -203,10 +203,21 @@
#define NETDATA_OS_TYPE "linux"
#endif /* __FreeBSD__, __APPLE__*/
-#include "statistical.h"
-#include "socket.h"
+typedef enum rrdcalc_status {
+ RRDCALC_STATUS_REMOVED = -2,
+ RRDCALC_STATUS_UNDEFINED = -1,
+ RRDCALC_STATUS_UNINITIALIZED = 0,
+ RRDCALC_STATUS_CLEAR = 1,
+ RRDCALC_STATUS_RAISED = 2,
+ RRDCALC_STATUS_WARNING = 3,
+ RRDCALC_STATUS_CRITICAL = 4
+} RRDCALC_STATUS;
+
#include "eval.h"
#include "health.h"
+
+#include "statistical.h"
+#include "socket.h"
#include "rrd.h"
#include "plugin_tc.h"
#include "plugins_d.h"
@@ -232,12 +243,14 @@
extern char *netdata_configured_hostname;
extern char *netdata_configured_config_dir;
extern char *netdata_configured_log_dir;
+extern char *netdata_configured_plugins_dir_base;
extern char *netdata_configured_plugins_dir;
extern char *netdata_configured_web_dir;
extern char *netdata_configured_cache_dir;
extern char *netdata_configured_varlib_dir;
extern char *netdata_configured_home_dir;
extern char *netdata_configured_host_prefix;
+extern char *netdata_configured_timezone;
extern void netdata_fix_chart_id(char *s);
extern void netdata_fix_chart_name(char *s);
diff --git a/src/eval.c b/src/eval.c
index 9248109b..84369f6d 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -166,7 +166,7 @@ static inline calculated_number eval_variable(EVAL_EXPRESSION *exp, EVAL_VARIABL
}
if(exp->rrdcalc && health_variable_lookup(v->name, v->hash, exp->rrdcalc, &n)) {
- buffer_sprintf(exp->error_msg, "[ $%s = ", v->name);
+ buffer_sprintf(exp->error_msg, "[ ${%s} = ", v->name);
print_parsed_as_constant(exp->error_msg, n);
buffer_strcat(exp->error_msg, " ] ");
return n;
@@ -232,7 +232,7 @@ calculated_number eval_equal(EVAL_EXPRESSION *exp, EVAL_NODE *op, int *error) {
if(isinf(n1) && isinf(n2)) return 1;
if(isnan(n1) || isnan(n2)) return 0;
if(isinf(n1) || isinf(n2)) return 0;
- return n1 == n2;
+ return calculated_number_equal(n1, n2);
}
calculated_number eval_not_equal(EVAL_EXPRESSION *exp, EVAL_NODE *op, int *error) {
return !eval_equal(exp, op, error);
@@ -355,7 +355,7 @@ static inline calculated_number eval_node(EVAL_EXPRESSION *exp, EVAL_NODE *op, i
static inline void print_parsed_as_variable(BUFFER *out, EVAL_VARIABLE *v, int *error) {
(void)error;
- buffer_sprintf(out, "$%s", v->name);
+ buffer_sprintf(out, "${%s}", v->name);
}
static inline void print_parsed_as_constant(BUFFER *out, calculated_number n) {
@@ -703,17 +703,31 @@ static inline int parse_variable(const char **string, char *buffer, size_t len)
const char *s = *string;
// $
- if(s[0] == '$') {
+ if(*s == '$') {
size_t i = 0;
s++;
- while(*s && !isvariableterm(*s) && i < len)
- buffer[i++] = *s++;
+ if(*s == '{') {
+ // ${variable_name}
+
+ s++;
+ while (*s && *s != '}' && i < len)
+ buffer[i++] = *s++;
+
+ if(*s == '}')
+ s++;
+ }
+ else {
+ // $variable_name
+
+ while (*s && !isvariableterm(*s) && i < len)
+ buffer[i++] = *s++;
+ }
buffer[i] = '\0';
- if(buffer[0]) {
- *string = &s[0];
+ if (buffer[0]) {
+ *string = s;
return 1;
}
}
diff --git a/src/eval.h b/src/eval.h
index d68b9af4..cd271148 100644
--- a/src/eval.h
+++ b/src/eval.h
@@ -14,7 +14,7 @@ typedef struct eval_expression {
const char *source;
const char *parsed_as;
- int *status;
+ RRDCALC_STATUS *status;
calculated_number *this;
time_t *after;
time_t *before;
diff --git a/src/freebsd_devstat.c b/src/freebsd_devstat.c
index 5b0687d5..2ed64ad4 100644
--- a/src/freebsd_devstat.c
+++ b/src/freebsd_devstat.c
@@ -27,10 +27,15 @@ struct disk {
struct prev_dstat {
collected_number bytes_read;
collected_number bytes_write;
+ collected_number bytes_free;
collected_number operations_read;
collected_number operations_write;
+ collected_number operations_other;
+ collected_number operations_free;
collected_number duration_read_ms;
collected_number duration_write_ms;
+ collected_number duration_other_ms;
+ collected_number duration_free_ms;
collected_number busy_time_ms;
} prev_dstat;
@@ -39,10 +44,13 @@ struct disk {
RRDSET *st_io;
RRDDIM *rd_io_in;
RRDDIM *rd_io_out;
+ RRDDIM *rd_io_free;
RRDSET *st_ops;
RRDDIM *rd_ops_in;
RRDDIM *rd_ops_out;
+ RRDDIM *rd_ops_other;
+ RRDDIM *rd_ops_free;
RRDSET *st_qops;
RRDDIM *rd_qops;
@@ -53,14 +61,19 @@ struct disk {
RRDSET *st_iotime;
RRDDIM *rd_iotime_in;
RRDDIM *rd_iotime_out;
+ RRDDIM *rd_iotime_other;
+ RRDDIM *rd_iotime_free;
RRDSET *st_await;
RRDDIM *rd_await_in;
RRDDIM *rd_await_out;
+ RRDDIM *rd_await_other;
+ RRDDIM *rd_await_free;
RRDSET *st_avagsz;
RRDDIM *rd_avagsz_in;
RRDDIM *rd_avagsz_out;
+ RRDDIM *rd_avagsz_free;
RRDSET *st_svctm;
RRDDIM *rd_svctm;
@@ -244,7 +257,8 @@ int do_kern_devstat(int update_every, usec_t dt) {
for (i = 0; i < numdevs; i++) {
if (likely(do_system_io)) {
- if (((dstat[i].device_type & DEVSTAT_TYPE_MASK) == DEVSTAT_TYPE_DIRECT) || ((dstat[i].device_type & DEVSTAT_TYPE_MASK) == DEVSTAT_TYPE_STORARRAY)) {
+ if (((dstat[i].device_type & DEVSTAT_TYPE_MASK) == DEVSTAT_TYPE_DIRECT) ||
+ ((dstat[i].device_type & DEVSTAT_TYPE_MASK) == DEVSTAT_TYPE_STORARRAY)) {
total_disk_kbytes_read += dstat[i].bytes[DEVSTAT_READ] / KILO_FACTOR;
total_disk_kbytes_write += dstat[i].bytes[DEVSTAT_WRITE] / KILO_FACTOR;
}
@@ -254,11 +268,14 @@ int do_kern_devstat(int update_every, usec_t dt) {
if ((dstat[i].device_type & DEVSTAT_TYPE_PASS) == DEVSTAT_TYPE_PASS)
continue;
- if (((dstat[i].device_type & DEVSTAT_TYPE_MASK) == DEVSTAT_TYPE_DIRECT) || ((dstat[i].device_type & DEVSTAT_TYPE_MASK) == DEVSTAT_TYPE_STORARRAY)) {
+ if (((dstat[i].device_type & DEVSTAT_TYPE_MASK) == DEVSTAT_TYPE_DIRECT) ||
+ ((dstat[i].device_type & DEVSTAT_TYPE_MASK) == DEVSTAT_TYPE_STORARRAY)) {
char disk[DEVSTAT_NAME_LEN + MAX_INT_DIGITS + 1];
struct cur_dstat {
collected_number duration_read_ms;
collected_number duration_write_ms;
+ collected_number duration_other_ms;
+ collected_number duration_free_ms;
collected_number busy_time_ms;
} cur_dstat;
@@ -299,12 +316,19 @@ int do_kern_devstat(int update_every, usec_t dt) {
dm->prev_dstat.bytes_read = dstat[i].bytes[DEVSTAT_READ];
dm->prev_dstat.bytes_write = dstat[i].bytes[DEVSTAT_WRITE];
+ dm->prev_dstat.bytes_free = dstat[i].bytes[DEVSTAT_FREE];
dm->prev_dstat.operations_read = dstat[i].operations[DEVSTAT_READ];
dm->prev_dstat.operations_write = dstat[i].operations[DEVSTAT_WRITE];
+ dm->prev_dstat.operations_other = dstat[i].operations[DEVSTAT_NO_DATA];
+ dm->prev_dstat.operations_free = dstat[i].operations[DEVSTAT_FREE];
dm->prev_dstat.duration_read_ms = dstat[i].duration[DEVSTAT_READ].sec * 1000
+ dstat[i].duration[DEVSTAT_READ].frac * BINTIME_SCALE;
dm->prev_dstat.duration_write_ms = dstat[i].duration[DEVSTAT_WRITE].sec * 1000
- + dstat[i].duration[DEVSTAT_READ].frac * BINTIME_SCALE;
+ + dstat[i].duration[DEVSTAT_WRITE].frac * BINTIME_SCALE;
+ dm->prev_dstat.duration_other_ms = dstat[i].duration[DEVSTAT_NO_DATA].sec * 1000
+ + dstat[i].duration[DEVSTAT_NO_DATA].frac * BINTIME_SCALE;
+ dm->prev_dstat.duration_free_ms = dstat[i].duration[DEVSTAT_FREE].sec * 1000
+ + dstat[i].duration[DEVSTAT_FREE].frac * BINTIME_SCALE;
dm->prev_dstat.busy_time_ms = dstat[i].busy_time.sec * 1000
+ dstat[i].busy_time.frac * BINTIME_SCALE;
}
@@ -312,13 +336,20 @@ int do_kern_devstat(int update_every, usec_t dt) {
cur_dstat.duration_read_ms = dstat[i].duration[DEVSTAT_READ].sec * 1000
+ dstat[i].duration[DEVSTAT_READ].frac * BINTIME_SCALE;
cur_dstat.duration_write_ms = dstat[i].duration[DEVSTAT_WRITE].sec * 1000
- + dstat[i].duration[DEVSTAT_READ].frac * BINTIME_SCALE;
+ + dstat[i].duration[DEVSTAT_WRITE].frac * BINTIME_SCALE;
+ cur_dstat.duration_other_ms = dstat[i].duration[DEVSTAT_NO_DATA].sec * 1000
+ + dstat[i].duration[DEVSTAT_NO_DATA].frac * BINTIME_SCALE;
+ cur_dstat.duration_free_ms = dstat[i].duration[DEVSTAT_FREE].sec * 1000
+ + dstat[i].duration[DEVSTAT_FREE].frac * BINTIME_SCALE;
+
cur_dstat.busy_time_ms = dstat[i].busy_time.sec * 1000 + dstat[i].busy_time.frac * BINTIME_SCALE;
// --------------------------------------------------------------------
if(dm->do_io == CONFIG_BOOLEAN_YES || (dm->do_io == CONFIG_BOOLEAN_AUTO &&
- (dstat[i].bytes[DEVSTAT_READ] || dstat[i].bytes[DEVSTAT_WRITE]))) {
+ (dstat[i].bytes[DEVSTAT_READ] ||
+ dstat[i].bytes[DEVSTAT_WRITE] ||
+ dstat[i].bytes[DEVSTAT_FREE]))) {
if (unlikely(!dm->st_io)) {
dm->st_io = rrdset_create_localhost("disk",
disk,
@@ -327,6 +358,8 @@ int do_kern_devstat(int update_every, usec_t dt) {
"disk.io",
"Disk I/O Bandwidth",
"kilobytes/s",
+ "freebsd",
+ "devstat",
2000,
update_every,
RRDSET_TYPE_AREA
@@ -336,18 +369,24 @@ int do_kern_devstat(int update_every, usec_t dt) {
RRD_ALGORITHM_INCREMENTAL);
dm->rd_io_out = rrddim_add(dm->st_io, "writes", NULL, -1, KILO_FACTOR,
RRD_ALGORITHM_INCREMENTAL);
+ dm->rd_io_free = rrddim_add(dm->st_io, "frees", NULL, -1, KILO_FACTOR,
+ RRD_ALGORITHM_INCREMENTAL);
} else
rrdset_next(dm->st_io);
- rrddim_set_by_pointer(dm->st_io, dm->rd_io_in, dstat[i].bytes[DEVSTAT_READ]);
- rrddim_set_by_pointer(dm->st_io, dm->rd_io_out, dstat[i].bytes[DEVSTAT_WRITE]);
+ rrddim_set_by_pointer(dm->st_io, dm->rd_io_in, dstat[i].bytes[DEVSTAT_READ]);
+ rrddim_set_by_pointer(dm->st_io, dm->rd_io_out, dstat[i].bytes[DEVSTAT_WRITE]);
+ rrddim_set_by_pointer(dm->st_io, dm->rd_io_free, dstat[i].bytes[DEVSTAT_FREE]);
rrdset_done(dm->st_io);
}
// --------------------------------------------------------------------
if(dm->do_ops == CONFIG_BOOLEAN_YES || (dm->do_ops == CONFIG_BOOLEAN_AUTO &&
- (dstat[i].operations[DEVSTAT_READ] || dstat[i].operations[DEVSTAT_WRITE]))) {
+ (dstat[i].operations[DEVSTAT_READ] ||
+ dstat[i].operations[DEVSTAT_WRITE] ||
+ dstat[i].operations[DEVSTAT_NO_DATA] ||
+ dstat[i].operations[DEVSTAT_FREE]))) {
if (unlikely(!dm->st_ops)) {
dm->st_ops = rrdset_create_localhost("disk_ops",
disk,
@@ -356,6 +395,8 @@ int do_kern_devstat(int update_every, usec_t dt) {
"disk.ops",
"Disk Completed I/O Operations",
"operations/s",
+ "freebsd",
+ "devstat",
2001,
update_every,
RRDSET_TYPE_LINE
@@ -363,14 +404,21 @@ int do_kern_devstat(int update_every, usec_t dt) {
rrdset_flag_set(dm->st_ops, RRDSET_FLAG_DETAIL);
- dm->rd_ops_in = rrddim_add(dm->st_ops, "reads", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- dm->rd_ops_out = rrddim_add(dm->st_ops, "writes", NULL, -1, 1,
- RRD_ALGORITHM_INCREMENTAL);
+ dm->rd_ops_in = rrddim_add(dm->st_ops, "reads", NULL, 1, 1,
+ RRD_ALGORITHM_INCREMENTAL);
+ dm->rd_ops_out = rrddim_add(dm->st_ops, "writes", NULL, -1, 1,
+ RRD_ALGORITHM_INCREMENTAL);
+ dm->rd_ops_other = rrddim_add(dm->st_ops, "other", NULL, 1, 1,
+ RRD_ALGORITHM_INCREMENTAL);
+ dm->rd_ops_free = rrddim_add(dm->st_ops, "frees", NULL, -1, 1,
+ RRD_ALGORITHM_INCREMENTAL);
} else
rrdset_next(dm->st_ops);
- rrddim_set_by_pointer(dm->st_ops, dm->rd_ops_in, dstat[i].operations[DEVSTAT_READ]);
- rrddim_set_by_pointer(dm->st_ops, dm->rd_ops_out, dstat[i].operations[DEVSTAT_WRITE]);
+ rrddim_set_by_pointer(dm->st_ops, dm->rd_ops_in, dstat[i].operations[DEVSTAT_READ]);
+ rrddim_set_by_pointer(dm->st_ops, dm->rd_ops_out, dstat[i].operations[DEVSTAT_WRITE]);
+ rrddim_set_by_pointer(dm->st_ops, dm->rd_ops_other, dstat[i].operations[DEVSTAT_NO_DATA]);
+ rrddim_set_by_pointer(dm->st_ops, dm->rd_ops_free, dstat[i].operations[DEVSTAT_FREE]);
rrdset_done(dm->st_ops);
}
@@ -386,6 +434,8 @@ int do_kern_devstat(int update_every, usec_t dt) {
"disk.qops",
"Disk Current I/O Operations",
"operations",
+ "freebsd",
+ "devstat",
2002,
update_every,
RRDSET_TYPE_LINE
@@ -413,6 +463,8 @@ int do_kern_devstat(int update_every, usec_t dt) {
"disk.util",
"Disk Utilization Time",
"% of time working",
+ "freebsd",
+ "devstat",
2004,
update_every,
RRDSET_TYPE_AREA
@@ -432,7 +484,10 @@ int do_kern_devstat(int update_every, usec_t dt) {
// --------------------------------------------------------------------
if(dm->do_iotime == CONFIG_BOOLEAN_YES || (dm->do_iotime == CONFIG_BOOLEAN_AUTO &&
- (cur_dstat.duration_read_ms || cur_dstat.duration_write_ms))) {
+ (cur_dstat.duration_read_ms ||
+ cur_dstat.duration_write_ms ||
+ cur_dstat.duration_other_ms ||
+ cur_dstat.duration_free_ms))) {
if (unlikely(!dm->st_iotime)) {
dm->st_iotime = rrdset_create_localhost("disk_iotime",
disk,
@@ -441,6 +496,8 @@ int do_kern_devstat(int update_every, usec_t dt) {
"disk.iotime",
"Disk Total I/O Time",
"milliseconds/s",
+ "freebsd",
+ "devstat",
2022,
update_every,
RRDSET_TYPE_LINE
@@ -448,15 +505,21 @@ int do_kern_devstat(int update_every, usec_t dt) {
rrdset_flag_set(dm->st_iotime, RRDSET_FLAG_DETAIL);
- dm->rd_iotime_in = rrddim_add(dm->st_iotime, "reads", NULL, 1, 1,
- RRD_ALGORITHM_INCREMENTAL);
- dm->rd_iotime_out = rrddim_add(dm->st_iotime, "writes", NULL, -1, 1,
- RRD_ALGORITHM_INCREMENTAL);
+ dm->rd_iotime_in = rrddim_add(dm->st_iotime, "reads", NULL, 1, 1,
+ RRD_ALGORITHM_INCREMENTAL);
+ dm->rd_iotime_out = rrddim_add(dm->st_iotime, "writes", NULL, -1, 1,
+ RRD_ALGORITHM_INCREMENTAL);
+ dm->rd_iotime_other = rrddim_add(dm->st_iotime, "other", NULL, 1, 1,
+ RRD_ALGORITHM_INCREMENTAL);
+ dm->rd_iotime_free = rrddim_add(dm->st_iotime, "frees", NULL, -1, 1,
+ RRD_ALGORITHM_INCREMENTAL);
} else
rrdset_next(dm->st_iotime);
- rrddim_set_by_pointer(dm->st_iotime, dm->rd_iotime_in, cur_dstat.duration_read_ms);
- rrddim_set_by_pointer(dm->st_iotime, dm->rd_iotime_out, cur_dstat.duration_write_ms);
+ rrddim_set_by_pointer(dm->st_iotime, dm->rd_iotime_in, cur_dstat.duration_read_ms);
+ rrddim_set_by_pointer(dm->st_iotime, dm->rd_iotime_out, cur_dstat.duration_write_ms);
+ rrddim_set_by_pointer(dm->st_iotime, dm->rd_iotime_other, cur_dstat.duration_other_ms);
+ rrddim_set_by_pointer(dm->st_iotime, dm->rd_iotime_free, cur_dstat.duration_free_ms);
rrdset_done(dm->st_iotime);
}
@@ -469,7 +532,10 @@ int do_kern_devstat(int update_every, usec_t dt) {
// --------------------------------------------------------------------
if(dm->do_await == CONFIG_BOOLEAN_YES || (dm->do_await == CONFIG_BOOLEAN_AUTO &&
- (dstat[i].operations[DEVSTAT_READ] || dstat[i].operations[DEVSTAT_WRITE]))) {
+ (dstat[i].operations[DEVSTAT_READ] ||
+ dstat[i].operations[DEVSTAT_WRITE] ||
+ dstat[i].operations[DEVSTAT_NO_DATA] ||
+ dstat[i].operations[DEVSTAT_FREE]))) {
if (unlikely(!dm->st_await)) {
dm->st_await = rrdset_create_localhost("disk_await",
disk,
@@ -478,6 +544,8 @@ int do_kern_devstat(int update_every, usec_t dt) {
"disk.await",
"Average Completed I/O Operation Time",
"ms per operation",
+ "freebsd",
+ "devstat",
2005,
update_every,
RRDSET_TYPE_LINE
@@ -485,9 +553,13 @@ int do_kern_devstat(int update_every, usec_t dt) {
rrdset_flag_set(dm->st_await, RRDSET_FLAG_DETAIL);
- dm->rd_await_in = rrddim_add(dm->st_await, "reads", NULL, 1, 1,
+ dm->rd_await_in = rrddim_add(dm->st_await, "reads", NULL, 1, 1,
+ RRD_ALGORITHM_ABSOLUTE);
+ dm->rd_await_out = rrddim_add(dm->st_await, "writes", NULL, -1, 1,
RRD_ALGORITHM_ABSOLUTE);
- dm->rd_await_out = rrddim_add(dm->st_await, "writes", NULL, -1, 1,
+ dm->rd_await_other = rrddim_add(dm->st_await, "other", NULL, 1, 1,
+ RRD_ALGORITHM_ABSOLUTE);
+ dm->rd_await_free = rrddim_add(dm->st_await, "frees", NULL, -1, 1,
RRD_ALGORITHM_ABSOLUTE);
} else
rrdset_next(dm->st_await);
@@ -506,13 +578,29 @@ int do_kern_devstat(int update_every, usec_t dt) {
(dstat[i].operations[DEVSTAT_WRITE] -
dm->prev_dstat.operations_write) :
0);
+ rrddim_set_by_pointer(dm->st_await, dm->rd_await_other,
+ (dstat[i].operations[DEVSTAT_NO_DATA] -
+ dm->prev_dstat.operations_other) ?
+ (cur_dstat.duration_other_ms - dm->prev_dstat.duration_other_ms) /
+ (dstat[i].operations[DEVSTAT_NO_DATA] -
+ dm->prev_dstat.operations_other) :
+ 0);
+ rrddim_set_by_pointer(dm->st_await, dm->rd_await_free,
+ (dstat[i].operations[DEVSTAT_FREE] -
+ dm->prev_dstat.operations_free) ?
+ (cur_dstat.duration_free_ms - dm->prev_dstat.duration_free_ms) /
+ (dstat[i].operations[DEVSTAT_FREE] -
+ dm->prev_dstat.operations_free) :
+ 0);
rrdset_done(dm->st_await);
}
// --------------------------------------------------------------------
if(dm->do_avagsz == CONFIG_BOOLEAN_YES || (dm->do_avagsz == CONFIG_BOOLEAN_AUTO &&
- (dstat[i].operations[DEVSTAT_READ] || dstat[i].operations[DEVSTAT_WRITE]))) {
+ (dstat[i].operations[DEVSTAT_READ] ||
+ dstat[i].operations[DEVSTAT_WRITE] ||
+ dstat[i].operations[DEVSTAT_FREE]))) {
if (unlikely(!dm->st_avagsz)) {
dm->st_avagsz = rrdset_create_localhost("disk_avgsz",
disk,
@@ -521,6 +609,8 @@ int do_kern_devstat(int update_every, usec_t dt) {
"disk.avgsz",
"Average Completed I/O Operation Bandwidth",
"kilobytes per operation",
+ "freebsd",
+ "devstat",
2006,
update_every,
RRDSET_TYPE_AREA
@@ -528,10 +618,12 @@ int do_kern_devstat(int update_every, usec_t dt) {
rrdset_flag_set(dm->st_avagsz, RRDSET_FLAG_DETAIL);
- dm->rd_avagsz_in = rrddim_add(dm->st_avagsz, "reads", NULL, 1, KILO_FACTOR,
- RRD_ALGORITHM_ABSOLUTE);
- dm->rd_avagsz_out = rrddim_add(dm->st_avagsz, "writes", NULL, -1, KILO_FACTOR,
- RRD_ALGORITHM_ABSOLUTE);
+ dm->rd_avagsz_in = rrddim_add(dm->st_avagsz, "reads", NULL, 1, KILO_FACTOR,
+ RRD_ALGORITHM_ABSOLUTE);
+ dm->rd_avagsz_out = rrddim_add(dm->st_avagsz, "writes", NULL, -1, KILO_FACTOR,
+ RRD_ALGORITHM_ABSOLUTE);
+ dm->rd_avagsz_free = rrddim_add(dm->st_avagsz, "frees", NULL, -1, KILO_FACTOR,
+ RRD_ALGORITHM_ABSOLUTE);
} else
rrdset_next(dm->st_avagsz);
@@ -549,13 +641,23 @@ int do_kern_devstat(int update_every, usec_t dt) {
(dstat[i].operations[DEVSTAT_WRITE] -
dm->prev_dstat.operations_write) :
0);
+ rrddim_set_by_pointer(dm->st_avagsz, dm->rd_avagsz_free,
+ (dstat[i].operations[DEVSTAT_FREE] -
+ dm->prev_dstat.operations_free) ?
+ (dstat[i].bytes[DEVSTAT_FREE] - dm->prev_dstat.bytes_free) /
+ (dstat[i].operations[DEVSTAT_FREE] -
+ dm->prev_dstat.operations_free) :
+ 0);
rrdset_done(dm->st_avagsz);
}
// --------------------------------------------------------------------
if(dm->do_svctm == CONFIG_BOOLEAN_YES || (dm->do_svctm == CONFIG_BOOLEAN_AUTO &&
- (dstat[i].operations[DEVSTAT_READ] || dstat[i].operations[DEVSTAT_WRITE]))) {
+ (dstat[i].operations[DEVSTAT_READ] ||
+ dstat[i].operations[DEVSTAT_WRITE] ||
+ dstat[i].operations[DEVSTAT_NO_DATA] ||
+ dstat[i].operations[DEVSTAT_FREE]))) {
if (unlikely(!dm->st_svctm)) {
dm->st_svctm = rrdset_create_localhost("disk_svctm",
disk,
@@ -564,6 +666,8 @@ int do_kern_devstat(int update_every, usec_t dt) {
"disk.svctm",
"Average Service Time",
"ms per operation",
+ "freebsd",
+ "devstat",
2007,
update_every,
RRDSET_TYPE_LINE
@@ -578,10 +682,14 @@ int do_kern_devstat(int update_every, usec_t dt) {
rrddim_set_by_pointer(dm->st_svctm, dm->rd_svctm,
((dstat[i].operations[DEVSTAT_READ] - dm->prev_dstat.operations_read) +
- (dstat[i].operations[DEVSTAT_WRITE] - dm->prev_dstat.operations_write)) ?
+ (dstat[i].operations[DEVSTAT_WRITE] - dm->prev_dstat.operations_write) +
+ (dstat[i].operations[DEVSTAT_NO_DATA] - dm->prev_dstat.operations_other) +
+ (dstat[i].operations[DEVSTAT_FREE] - dm->prev_dstat.operations_free)) ?
(cur_dstat.busy_time_ms - dm->prev_dstat.busy_time_ms) /
((dstat[i].operations[DEVSTAT_READ] - dm->prev_dstat.operations_read) +
- (dstat[i].operations[DEVSTAT_WRITE] - dm->prev_dstat.operations_write)) :
+ (dstat[i].operations[DEVSTAT_WRITE] - dm->prev_dstat.operations_write) +
+ (dstat[i].operations[DEVSTAT_NO_DATA] - dm->prev_dstat.operations_other) +
+ (dstat[i].operations[DEVSTAT_FREE] - dm->prev_dstat.operations_free)) :
0);
rrdset_done(dm->st_svctm);
}
@@ -590,10 +698,15 @@ int do_kern_devstat(int update_every, usec_t dt) {
dm->prev_dstat.bytes_read = dstat[i].bytes[DEVSTAT_READ];
dm->prev_dstat.bytes_write = dstat[i].bytes[DEVSTAT_WRITE];
+ dm->prev_dstat.bytes_free = dstat[i].bytes[DEVSTAT_FREE];
dm->prev_dstat.operations_read = dstat[i].operations[DEVSTAT_READ];
dm->prev_dstat.operations_write = dstat[i].operations[DEVSTAT_WRITE];
+ dm->prev_dstat.operations_other = dstat[i].operations[DEVSTAT_NO_DATA];
+ dm->prev_dstat.operations_free = dstat[i].operations[DEVSTAT_FREE];
dm->prev_dstat.duration_read_ms = cur_dstat.duration_read_ms;
dm->prev_dstat.duration_write_ms = cur_dstat.duration_write_ms;
+ dm->prev_dstat.duration_other_ms = cur_dstat.duration_other_ms;
+ dm->prev_dstat.duration_free_ms = cur_dstat.duration_free_ms;
dm->prev_dstat.busy_time_ms = cur_dstat.busy_time_ms;
}
}
@@ -613,6 +726,8 @@ int do_kern_devstat(int update_every, usec_t dt) {
NULL,
"Disk I/O",
"kilobytes/s",
+ "freebsd",
+ "devstat",
150,
update_every,
RRDSET_TYPE_AREA
diff --git a/src/freebsd_getifaddrs.c b/src/freebsd_getifaddrs.c
index 1a4448bd..94c0a6a4 100644
--- a/src/freebsd_getifaddrs.c
+++ b/src/freebsd_getifaddrs.c
@@ -228,6 +228,8 @@ int do_getifaddrs(int update_every, usec_t dt) {
NULL,
"IPv4 Bandwidth",
"kilobits/s",
+ "freebsd",
+ "getifaddrs",
500,
update_every,
RRDSET_TYPE_AREA
@@ -265,6 +267,8 @@ int do_getifaddrs(int update_every, usec_t dt) {
NULL,
"IPv6 Bandwidth",
"kilobits/s",
+ "freebsd",
+ "getifaddrs",
500,
update_every,
RRDSET_TYPE_AREA
@@ -333,6 +337,8 @@ int do_getifaddrs(int update_every, usec_t dt) {
"net.net",
"Bandwidth",
"kilobits/s",
+ "freebsd",
+ "getifaddrs",
7000,
update_every,
RRDSET_TYPE_AREA
@@ -360,6 +366,8 @@ int do_getifaddrs(int update_every, usec_t dt) {
"net.packets",
"Packets",
"packets/s",
+ "freebsd",
+ "getifaddrs",
7001,
update_every,
RRDSET_TYPE_LINE
@@ -397,6 +405,8 @@ int do_getifaddrs(int update_every, usec_t dt) {
"net.errors",
"Interface Errors",
"errors/s",
+ "freebsd",
+ "getifaddrs",
7002,
update_every,
RRDSET_TYPE_LINE
@@ -429,6 +439,8 @@ int do_getifaddrs(int update_every, usec_t dt) {
"net.drops",
"Interface Drops",
"drops/s",
+ "freebsd",
+ "getifaddrs",
7003,
update_every,
RRDSET_TYPE_LINE
@@ -462,6 +474,8 @@ int do_getifaddrs(int update_every, usec_t dt) {
"net.events",
"Network Interface Events",
"events/s",
+ "freebsd",
+ "getifaddrs",
7006,
update_every,
RRDSET_TYPE_LINE
diff --git a/src/freebsd_getmntinfo.c b/src/freebsd_getmntinfo.c
index e7ca56b5..66be5331 100644
--- a/src/freebsd_getmntinfo.c
+++ b/src/freebsd_getmntinfo.c
@@ -223,6 +223,8 @@ int do_getmntinfo(int update_every, usec_t dt) {
"disk.space",
title,
"GB",
+ "freebsd",
+ "getmntinfo",
2023,
update_every,
RRDSET_TYPE_STACKED
@@ -260,6 +262,8 @@ int do_getmntinfo(int update_every, usec_t dt) {
"disk.inodes",
title,
"Inodes",
+ "freebsd",
+ "getmntinfo",
2024,
update_every,
RRDSET_TYPE_STACKED
diff --git a/src/freebsd_ipfw.c b/src/freebsd_ipfw.c
index b89650a0..81264b3f 100644
--- a/src/freebsd_ipfw.c
+++ b/src/freebsd_ipfw.c
@@ -162,6 +162,8 @@ int do_ipfw(int update_every, usec_t dt) {
NULL,
"Memory allocated by rules",
"bytes",
+ "freebsd",
+ "ipfw",
3005,
update_every,
RRDSET_TYPE_STACKED
@@ -193,6 +195,8 @@ int do_ipfw(int update_every, usec_t dt) {
NULL,
"Packets",
"packets/s",
+ "freebsd",
+ "ipfw",
3001,
update_every,
RRDSET_TYPE_STACKED
@@ -208,6 +212,8 @@ int do_ipfw(int update_every, usec_t dt) {
NULL,
"Bytes",
"bytes/s",
+ "freebsd",
+ "ipfw",
3002,
update_every,
RRDSET_TYPE_STACKED
@@ -310,6 +316,8 @@ int do_ipfw(int update_every, usec_t dt) {
NULL,
"Active rules",
"rules",
+ "freebsd",
+ "ipfw",
3003,
update_every,
RRDSET_TYPE_STACKED
@@ -325,6 +333,8 @@ int do_ipfw(int update_every, usec_t dt) {
NULL,
"Expired rules",
"rules",
+ "freebsd",
+ "ipfw",
3004,
update_every,
RRDSET_TYPE_STACKED
diff --git a/src/freebsd_kstat_zfs.c b/src/freebsd_kstat_zfs.c
index 17642994..1bd48d4b 100644
--- a/src/freebsd_kstat_zfs.c
+++ b/src/freebsd_kstat_zfs.c
@@ -1,9 +1,11 @@
#include "common.h"
#include "zfs_common.h"
-struct arcstats arcstats = { 0 };
+extern struct arcstats arcstats;
+// --------------------------------------------------------------------------------------------------------------------
// kstat.zfs.misc.arcstats
+
int do_kstat_zfs_misc_arcstats(int update_every, usec_t dt) {
(void)dt;
@@ -103,15 +105,15 @@ int do_kstat_zfs_misc_arcstats(int update_every, usec_t dt) {
int arc_sys_free[5];
} mibs;
- l2exist = -1;
+ arcstats.l2exist = -1;
if(unlikely(sysctlbyname("kstat.zfs.misc.arcstats.l2_size", &l2_size, &uint64_t_size, NULL, 0)))
return 0;
if(likely(l2_size))
- l2exist = 1;
+ arcstats.l2exist = 1;
else
- l2exist = 0;
+ arcstats.l2exist = 0;
GETSYSCTL_SIMPLE("kstat.zfs.misc.arcstats.hits", mibs.hits, arcstats.hits);
GETSYSCTL_SIMPLE("kstat.zfs.misc.arcstats.misses", mibs.misses, arcstats.misses);
@@ -205,8 +207,92 @@ int do_kstat_zfs_misc_arcstats(int update_every, usec_t dt) {
// missing mib: GETSYSCTL_SIMPLE("kstat.zfs.misc.arcstats.arc_need_free", mibs.arc_need_free, arcstats.arc_need_free);
// missing mib: GETSYSCTL_SIMPLE("kstat.zfs.misc.arcstats.arc_sys_free", mibs.arc_sys_free, arcstats.arc_sys_free);
- generate_charts_arcstats(update_every);
- generate_charts_arc_summary(update_every);
+ generate_charts_arcstats("freebsd", update_every);
+ generate_charts_arc_summary("freebsd", update_every);
+
+ return 0;
+}
+
+// --------------------------------------------------------------------------------------------------------------------
+// kstat.zfs.misc.zio_trim
+
+int do_kstat_zfs_misc_zio_trim(int update_every, usec_t dt) {
+ (void)dt;
+ static int mib_bytes[5] = {0, 0, 0, 0, 0}, mib_success[5] = {0, 0, 0, 0, 0},
+ mib_failed[5] = {0, 0, 0, 0, 0}, mib_unsupported[5] = {0, 0, 0, 0, 0};
+ uint64_t bytes, success, failed, unsupported;
+
+ if (unlikely(GETSYSCTL_SIMPLE("kstat.zfs.misc.zio_trim.bytes", mib_bytes, bytes) ||
+ GETSYSCTL_SIMPLE("kstat.zfs.misc.zio_trim.success", mib_success, success) ||
+ GETSYSCTL_SIMPLE("kstat.zfs.misc.zio_trim.failed", mib_failed, failed) ||
+ GETSYSCTL_SIMPLE("kstat.zfs.misc.zio_trim.unsupported", mib_unsupported, unsupported))) {
+ error("DISABLED: zfs.trim_bytes chart");
+ error("DISABLED: zfs.trim_success chart");
+ error("DISABLED: kstat.zfs.misc.zio_trim module");
+ return 1;
+ } else {
+
+ // --------------------------------------------------------------------
+
+ static RRDSET *st_bytes = NULL;
+ static RRDDIM *rd_bytes = NULL;
+
+ if (unlikely(!st_bytes)) {
+ st_bytes = rrdset_create_localhost(
+ "zfs",
+ "trim_bytes",
+ NULL,
+ "trim",
+ NULL,
+ "Successfully TRIMmed bytes",
+ "bytes",
+ "freebsd",
+ "zfs",
+ 2320,
+ update_every,
+ RRDSET_TYPE_LINE
+ );
+
+ rd_bytes = rrddim_add(st_bytes, "TRIMmed", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ }
+ else rrdset_next(st_bytes);
+
+ rrddim_set_by_pointer(st_bytes, rd_bytes, bytes);
+ rrdset_done(st_bytes);
+
+ // --------------------------------------------------------------------
+
+ static RRDSET *st_requests = NULL;
+ static RRDDIM *rd_successful = NULL, *rd_failed = NULL, *rd_unsupported = NULL;
+
+ if (unlikely(!st_requests)) {
+ st_requests = rrdset_create_localhost(
+ "zfs",
+ "trim_requests",
+ NULL,
+ "trim",
+ NULL,
+ "TRIM requests",
+ "requests",
+ "freebsd",
+ "zfs",
+ 2321,
+ update_every,
+ RRDSET_TYPE_STACKED
+ );
+
+ rd_successful = rrddim_add(st_requests, "successful", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_failed = rrddim_add(st_requests, "failed", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_unsupported = rrddim_add(st_requests, "unsupported", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ }
+ else rrdset_next(st_requests);
+
+ rrddim_set_by_pointer(st_requests, rd_successful, success);
+ rrddim_set_by_pointer(st_requests, rd_failed, failed);
+ rrddim_set_by_pointer(st_requests, rd_unsupported, unsupported);
+ rrdset_done(st_requests);
+
+ }
return 0;
} \ No newline at end of file
diff --git a/src/freebsd_sysctl.c b/src/freebsd_sysctl.c
index a87b872d..9f5615df 100644
--- a/src/freebsd_sysctl.c
+++ b/src/freebsd_sysctl.c
@@ -27,6 +27,62 @@
int system_pagesize = PAGE_SIZE;
int number_of_cpus = 1;
+#if __FreeBSD_version >= 1200029
+struct __vmmeter {
+ uint64_t v_swtch;
+ uint64_t v_trap;
+ uint64_t v_syscall;
+ uint64_t v_intr;
+ uint64_t v_soft;
+ uint64_t v_vm_faults;
+ uint64_t v_io_faults;
+ uint64_t v_cow_faults;
+ uint64_t v_cow_optim;
+ uint64_t v_zfod;
+ uint64_t v_ozfod;
+ uint64_t v_swapin;
+ uint64_t v_swapout;
+ uint64_t v_swappgsin;
+ uint64_t v_swappgsout;
+ uint64_t v_vnodein;
+ uint64_t v_vnodeout;
+ uint64_t v_vnodepgsin;
+ uint64_t v_vnodepgsout;
+ uint64_t v_intrans;
+ uint64_t v_reactivated;
+ uint64_t v_pdwakeups;
+ uint64_t v_pdpages;
+ uint64_t v_pdshortfalls;
+ uint64_t v_dfree;
+ uint64_t v_pfree;
+ uint64_t v_tfree;
+ uint64_t v_forks;
+ uint64_t v_vforks;
+ uint64_t v_rforks;
+ uint64_t v_kthreads;
+ uint64_t v_forkpages;
+ uint64_t v_vforkpages;
+ uint64_t v_rforkpages;
+ uint64_t v_kthreadpages;
+ u_int v_page_size;
+ u_int v_page_count;
+ u_int v_free_reserved;
+ u_int v_free_target;
+ u_int v_free_min;
+ u_int v_free_count;
+ u_int v_wire_count;
+ u_int v_active_count;
+ u_int v_inactive_target;
+ u_int v_inactive_count;
+ u_int v_laundry_count;
+ u_int v_pageout_free_min;
+ u_int v_interrupt_free_min;
+ u_int v_free_severe;
+};
+typedef struct __vmmeter vmmeter_t;
+#else
+typedef struct vmmeter vmmeter_t;
+#endif
// --------------------------------------------------------------------------------------------------------------------
// FreeBSD plugin initialization
@@ -77,16 +133,19 @@ int do_vm_loadavg(int update_every, usec_t dt){
static RRDDIM *rd_load1 = NULL, *rd_load2 = NULL, *rd_load3 = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("system",
- "load",
- NULL,
- "load",
- NULL,
- "System Load Average",
- "load",
- 100,
- (update_every < MIN_LOADAVG_UPDATE_EVERY) ?
- MIN_LOADAVG_UPDATE_EVERY : update_every, RRDSET_TYPE_LINE
+ st = rrdset_create_localhost(
+ "system",
+ "load",
+ NULL,
+ "load",
+ NULL,
+ "System Load Average",
+ "load",
+ "freebsd",
+ "vm.loadavg",
+ 100,
+ (update_every < MIN_LOADAVG_UPDATE_EVERY) ?
+ MIN_LOADAVG_UPDATE_EVERY : update_every, RRDSET_TYPE_LINE
);
rd_load1 = rrddim_add(st, "load1", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
rd_load2 = rrddim_add(st, "load5", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
@@ -143,16 +202,19 @@ int do_vm_vmtotal(int update_every, usec_t dt) {
static RRDDIM *rd = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("system",
- "active_processes",
- NULL,
- "processes",
- NULL,
- "System Active Processes",
- "processes",
- 750,
- update_every,
- RRDSET_TYPE_LINE
+ st = rrdset_create_localhost(
+ "system",
+ "active_processes",
+ NULL,
+ "processes",
+ NULL,
+ "System Active Processes",
+ "processes",
+ "freebsd",
+ "vm.vmtotal",
+ 750,
+ update_every,
+ RRDSET_TYPE_LINE
);
rd = rrddim_add(st, "active", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
}
@@ -169,16 +231,19 @@ int do_vm_vmtotal(int update_every, usec_t dt) {
static RRDDIM *rd_running = NULL, *rd_blocked = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("system",
- "processes",
- NULL,
- "processes",
- NULL,
- "System Processes",
- "processes",
- 600,
- update_every,
- RRDSET_TYPE_LINE
+ st = rrdset_create_localhost(
+ "system",
+ "processes",
+ NULL,
+ "processes",
+ NULL,
+ "System Processes",
+ "processes",
+ "freebsd",
+ "vm.vmtotal",
+ 600,
+ update_every,
+ RRDSET_TYPE_LINE
);
rd_running = rrddim_add(st, "running", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
@@ -198,16 +263,19 @@ int do_vm_vmtotal(int update_every, usec_t dt) {
static RRDDIM *rd = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("mem",
- "committed",
- NULL,
- "system",
- NULL,
- "Committed (Allocated) Memory",
- "MB",
- 5000,
- update_every,
- RRDSET_TYPE_AREA
+ st = rrdset_create_localhost(
+ "mem",
+ "committed",
+ NULL,
+ "system",
+ NULL,
+ "Committed (Allocated) Memory",
+ "MB",
+ "freebsd",
+ "vm.vmtotal",
+ 5000,
+ update_every,
+ RRDSET_TYPE_AREA
);
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
@@ -254,15 +322,18 @@ int do_kern_cp_time(int update_every, usec_t dt) {
static RRDDIM *rd_nice = NULL, *rd_system = NULL, *rd_user = NULL, *rd_interrupt = NULL, *rd_idle = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("system",
- "cpu",
- NULL,
- "cpu",
- "system.cpu",
- "Total CPU utilization",
- "percentage",
- 100, update_every,
- RRDSET_TYPE_STACKED
+ st = rrdset_create_localhost(
+ "system",
+ "cpu",
+ NULL,
+ "cpu",
+ "system.cpu",
+ "Total CPU utilization",
+ "percentage",
+ "freebsd",
+ "kern.cp_time",
+ 100, update_every,
+ RRDSET_TYPE_STACKED
);
rd_nice = rrddim_add(st, "nice", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
@@ -332,16 +403,19 @@ int do_kern_cp_times(int update_every, usec_t dt) {
for (i = 0; i < number_of_cpus; i++) {
if (unlikely(!all_cpu_charts[i].st)) {
snprintfz(all_cpu_charts[i].cpuid, MAX_INT_DIGITS, "cpu%d", i);
- all_cpu_charts[i].st = rrdset_create_localhost("cpu",
- all_cpu_charts[i].cpuid,
- NULL,
- "utilization",
- "cpu.cpu",
- "Core utilization",
- "percentage",
- 1000,
- update_every,
- RRDSET_TYPE_STACKED
+ all_cpu_charts[i].st = rrdset_create_localhost(
+ "cpu",
+ all_cpu_charts[i].cpuid,
+ NULL,
+ "utilization",
+ "cpu.cpu",
+ "Core utilization",
+ "percentage",
+ "freebsd",
+ "kern.cp_times",
+ 1000,
+ update_every,
+ RRDSET_TYPE_STACKED
);
all_cpu_charts[i].rd_nice = rrddim_add(all_cpu_charts[i].st, "nice", NULL, 1, 1,
@@ -413,18 +487,22 @@ int do_dev_cpu_temperature(int update_every, usec_t dt) {
}
if (unlikely(!st)) {
- st = rrdset_create_localhost("cpu",
- "temperature",
- NULL,
- "temperature",
- "cpu.temperatute",
- "Core temperature",
- "degree",
- 1050,
- update_every,
- RRDSET_TYPE_LINE
+ st = rrdset_create_localhost(
+ "cpu",
+ "temperature",
+ NULL,
+ "temperature",
+ "cpu.temperatute",
+ "Core temperature",
+ "Celsius",
+ "freebsd",
+ "dev.cpu.temperature",
+ 1050,
+ update_every,
+ RRDSET_TYPE_LINE
);
- } else rrdset_next(st);
+ }
+ else rrdset_next(st);
for (i = 0; i < number_of_cpus; i++) {
if (unlikely(!rd_pcpu_temperature[i])) {
@@ -443,6 +521,52 @@ int do_dev_cpu_temperature(int update_every, usec_t dt) {
}
// --------------------------------------------------------------------------------------------------------------------
+// dev.cpu.0.freq
+
+int do_dev_cpu_0_freq(int update_every, usec_t dt) {
+ (void)dt;
+ static int mib[4] = {0, 0, 0, 0};
+ int cpufreq;
+
+ if (unlikely(GETSYSCTL_SIMPLE("dev.cpu.0.freq", mib, cpufreq))) {
+ error("DISABLED: cpu.scaling_cur_freq chart");
+ error("DISABLED: dev.cpu.0.freq module");
+ return 1;
+ } else {
+
+ // --------------------------------------------------------------------
+
+ static RRDSET *st = NULL;
+ static RRDDIM *rd = NULL;
+
+ if (unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "cpu",
+ "scaling_cur_freq",
+ NULL,
+ "cpufreq",
+ NULL,
+ "Current CPU Scaling Frequency",
+ "MHz",
+ "freebsd",
+ "dev.cpu.0.freq",
+ 5003,
+ update_every,
+ RRDSET_TYPE_LINE
+ );
+
+ rd = rrddim_add(st, "frequency", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
+ }
+ else rrdset_next(st);
+
+ rrddim_set_by_pointer(st, rd, cpufreq);
+ rrdset_done(st);
+ }
+
+ return 0;
+}
+
+// --------------------------------------------------------------------------------------------------------------------
// hw.intrcnt
int do_hw_intcnt(int update_every, usec_t dt) {
@@ -480,16 +604,19 @@ int do_hw_intcnt(int update_every, usec_t dt) {
static RRDDIM *rd_intr = NULL;
if (unlikely(!st_intr)) {
- st_intr = rrdset_create_localhost("system",
- "intr",
- NULL,
- "interrupts",
- NULL,
- "Total Hardware Interrupts",
- "interrupts/s",
- 900,
- update_every,
- RRDSET_TYPE_LINE
+ st_intr = rrdset_create_localhost(
+ "system",
+ "intr",
+ NULL,
+ "interrupts",
+ NULL,
+ "Total Hardware Interrupts",
+ "interrupts/s",
+ "freebsd",
+ "hw.intrcnt",
+ 900,
+ update_every,
+ RRDSET_TYPE_LINE
);
rrdset_flag_set(st_intr, RRDSET_FLAG_DETAIL);
@@ -519,20 +646,22 @@ int do_hw_intcnt(int update_every, usec_t dt) {
// --------------------------------------------------------------------
static RRDSET *st_interrupts = NULL;
- RRDDIM *rd_interrupts = NULL;
void *p;
if (unlikely(!st_interrupts))
- st_interrupts = rrdset_create_localhost("system",
- "interrupts",
- NULL,
- "interrupts",
- NULL,
- "System interrupts",
- "interrupts/s",
- 1000,
- update_every,
- RRDSET_TYPE_STACKED
+ st_interrupts = rrdset_create_localhost(
+ "system",
+ "interrupts",
+ NULL,
+ "interrupts",
+ NULL,
+ "System interrupts",
+ "interrupts/s",
+ "freebsd",
+ "hw.intrcnt",
+ 1000,
+ update_every,
+ RRDSET_TYPE_STACKED
);
else
rrdset_next(st_interrupts);
@@ -540,9 +669,11 @@ int do_hw_intcnt(int update_every, usec_t dt) {
for (i = 0; i < nintr; i++) {
p = intrnames + i * (MAXCOMLEN + 1);
if (unlikely((intrcnt[i] != 0) && (*(char *) p != 0))) {
- rd_interrupts = rrddim_find(st_interrupts, p);
+ RRDDIM *rd_interrupts = rrddim_find(st_interrupts, p);
+
if (unlikely(!rd_interrupts))
rd_interrupts = rrddim_add(st_interrupts, p, NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+
rrddim_set_by_pointer(st_interrupts, rd_interrupts, intrcnt[i]);
}
}
@@ -576,16 +707,19 @@ int do_vm_stats_sys_v_intr(int update_every, usec_t dt) {
static RRDDIM *rd = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("system",
- "dev_intr",
- NULL,
- "interrupts",
- NULL,
- "Device Interrupts",
- "interrupts/s",
- 1000,
- update_every,
- RRDSET_TYPE_LINE
+ st = rrdset_create_localhost(
+ "system",
+ "dev_intr",
+ NULL,
+ "interrupts",
+ NULL,
+ "Device Interrupts",
+ "interrupts/s",
+ "freebsd",
+ "vm.stats.sys.v_intr",
+ 1000,
+ update_every,
+ RRDSET_TYPE_LINE
);
rd = rrddim_add(st, "interrupts", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -619,16 +753,19 @@ int do_vm_stats_sys_v_soft(int update_every, usec_t dt) {
static RRDDIM *rd = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("system",
- "soft_intr",
- NULL,
- "interrupts",
- NULL,
- "Software Interrupts",
- "interrupts/s",
- 1100,
- update_every,
- RRDSET_TYPE_LINE
+ st = rrdset_create_localhost(
+ "system",
+ "soft_intr",
+ NULL,
+ "interrupts",
+ NULL,
+ "Software Interrupts",
+ "interrupts/s",
+ "freebsd",
+ "vm.stats.sys.v_soft",
+ 1100,
+ update_every,
+ RRDSET_TYPE_LINE
);
rd = rrddim_add(st, "interrupts", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -662,16 +799,19 @@ int do_vm_stats_sys_v_swtch(int update_every, usec_t dt) {
static RRDDIM *rd = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("system",
- "ctxt",
- NULL,
- "processes",
- NULL,
- "CPU Context Switches",
- "context switches/s",
- 800,
- update_every,
- RRDSET_TYPE_LINE
+ st = rrdset_create_localhost(
+ "system",
+ "ctxt",
+ NULL,
+ "processes",
+ NULL,
+ "CPU Context Switches",
+ "context switches/s",
+ "freebsd",
+ "vm.stats.sys.v_swtch",
+ 800,
+ update_every,
+ RRDSET_TYPE_LINE
);
rd = rrddim_add(st, "switches", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -705,16 +845,19 @@ int do_vm_stats_sys_v_forks(int update_every, usec_t dt) {
static RRDDIM *rd = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("system",
- "forks",
- NULL,
- "processes",
- NULL,
- "Started Processes",
- "processes/s",
- 700,
- update_every,
- RRDSET_TYPE_LINE
+ st = rrdset_create_localhost(
+ "system",
+ "forks",
+ NULL,
+ "processes",
+ NULL,
+ "Started Processes",
+ "processes/s",
+ "freebsd",
+ "vm.stats.sys.v_swtch",
+ 700,
+ update_every,
+ RRDSET_TYPE_LINE
);
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
@@ -779,16 +922,19 @@ int do_vm_swap_info(int update_every, usec_t dt) {
static RRDDIM *rd_free = NULL, *rd_used = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("system",
- "swap",
- NULL,
- "swap",
- NULL,
- "System Swap",
- "MB",
- 201,
- update_every,
- RRDSET_TYPE_STACKED
+ st = rrdset_create_localhost(
+ "system",
+ "swap",
+ NULL,
+ "swap",
+ NULL,
+ "System Swap",
+ "MB",
+ "freebsd",
+ "vm.swap_info",
+ 201,
+ update_every,
+ RRDSET_TYPE_STACKED
);
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
@@ -813,7 +959,7 @@ int do_system_ram(int update_every, usec_t dt) {
(void)dt;
static int mib_active_count[4] = {0, 0, 0, 0}, mib_inactive_count[4] = {0, 0, 0, 0}, mib_wire_count[4] = {0, 0, 0, 0},
mib_cache_count[4] = {0, 0, 0, 0}, mib_vfs_bufspace[2] = {0, 0}, mib_free_count[4] = {0, 0, 0, 0};
- struct vmmeter vmmeter_data;
+ vmmeter_t vmmeter_data;
int vfs_bufspace_count;
if (unlikely(GETSYSCTL_SIMPLE("vm.stats.vm.v_active_count", mib_active_count, vmmeter_data.v_active_count) ||
@@ -825,7 +971,7 @@ int do_system_ram(int update_every, usec_t dt) {
GETSYSCTL_SIMPLE("vfs.bufspace", mib_vfs_bufspace, vfs_bufspace_count) ||
GETSYSCTL_SIMPLE("vm.stats.vm.v_free_count", mib_free_count, vmmeter_data.v_free_count))) {
error("DISABLED: system.ram chart");
- error("DISABLED: System.ram module");
+ error("DISABLED: system.ram module");
return 1;
} else {
@@ -835,18 +981,20 @@ int do_system_ram(int update_every, usec_t dt) {
static RRDDIM *rd_free = NULL, *rd_active = NULL, *rd_inactive = NULL,
*rd_wired = NULL, *rd_cache = NULL, *rd_buffers = NULL;
- st = rrdset_find_localhost("system.ram");
if (unlikely(!st)) {
- st = rrdset_create_localhost("system",
- "ram",
- NULL,
- "ram",
- NULL,
- "System RAM",
- "MB",
- 200,
- update_every,
- RRDSET_TYPE_STACKED
+ st = rrdset_create_localhost(
+ "system",
+ "ram",
+ NULL,
+ "ram",
+ NULL,
+ "System RAM",
+ "MB",
+ "freebsd",
+ "system.ram",
+ 200,
+ update_every,
+ RRDSET_TYPE_STACKED
);
rd_free = rrddim_add(st, "free", NULL, system_pagesize, MEGA_FACTOR, RRD_ALGORITHM_ABSOLUTE);
@@ -880,7 +1028,7 @@ int do_system_ram(int update_every, usec_t dt) {
int do_vm_stats_sys_v_swappgs(int update_every, usec_t dt) {
(void)dt;
static int mib_swappgsin[4] = {0, 0, 0, 0}, mib_swappgsout[4] = {0, 0, 0, 0};
- struct vmmeter vmmeter_data;
+ vmmeter_t vmmeter_data;
if (unlikely(GETSYSCTL_SIMPLE("vm.stats.vm.v_swappgsin", mib_swappgsin, vmmeter_data.v_swappgsin) ||
GETSYSCTL_SIMPLE("vm.stats.vm.v_swappgsout", mib_swappgsout, vmmeter_data.v_swappgsout))) {
@@ -895,16 +1043,19 @@ int do_vm_stats_sys_v_swappgs(int update_every, usec_t dt) {
static RRDDIM *rd_in = NULL, *rd_out = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("system",
- "swapio",
- NULL,
- "swap",
- NULL,
- "Swap I/O",
- "kilobytes/s",
- 250,
- update_every,
- RRDSET_TYPE_AREA
+ st = rrdset_create_localhost(
+ "system",
+ "swapio",
+ NULL,
+ "swap",
+ NULL,
+ "Swap I/O",
+ "kilobytes/s",
+ "freebsd",
+ "vm.stats.vm.v_swappgs",
+ 250,
+ update_every,
+ RRDSET_TYPE_AREA
);
rd_in = rrddim_add(st, "in", NULL, system_pagesize, KILO_FACTOR, RRD_ALGORITHM_INCREMENTAL);
@@ -927,7 +1078,7 @@ int do_vm_stats_sys_v_pgfaults(int update_every, usec_t dt) {
(void)dt;
static int mib_vm_faults[4] = {0, 0, 0, 0}, mib_io_faults[4] = {0, 0, 0, 0}, mib_cow_faults[4] = {0, 0, 0, 0},
mib_cow_optim[4] = {0, 0, 0, 0}, mib_intrans[4] = {0, 0, 0, 0};
- struct vmmeter vmmeter_data;
+ vmmeter_t vmmeter_data;
if (unlikely(GETSYSCTL_SIMPLE("vm.stats.vm.v_vm_faults", mib_vm_faults, vmmeter_data.v_vm_faults) ||
GETSYSCTL_SIMPLE("vm.stats.vm.v_io_faults", mib_io_faults, vmmeter_data.v_io_faults) ||
@@ -946,16 +1097,19 @@ int do_vm_stats_sys_v_pgfaults(int update_every, usec_t dt) {
*rd_cow_optimized = NULL, *rd_in_transit = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("mem",
- "pgfaults",
- NULL,
- "system",
- NULL,
- "Memory Page Faults",
- "page faults/s",
- 500,
- update_every,
- RRDSET_TYPE_LINE
+ st = rrdset_create_localhost(
+ "mem",
+ "pgfaults",
+ NULL,
+ "system",
+ NULL,
+ "Memory Page Faults",
+ "page faults/s",
+ "freebsd",
+ "vm.stats.vm.v_pgfaults",
+ 500,
+ update_every,
+ RRDSET_TYPE_LINE
);
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
@@ -1025,16 +1179,19 @@ int do_kern_ipc_sem(int update_every, usec_t dt) {
static RRDDIM *rd_semaphores = NULL, *rd_semaphore_arrays = NULL;
if (unlikely(!st_semaphores)) {
- st_semaphores = rrdset_create_localhost("system",
- "ipc_semaphores",
- NULL,
- "ipc semaphores",
- NULL,
- "IPC Semaphores",
- "semaphores",
- 1000,
- update_every,
- RRDSET_TYPE_AREA
+ st_semaphores = rrdset_create_localhost(
+ "system",
+ "ipc_semaphores",
+ NULL,
+ "ipc semaphores",
+ NULL,
+ "IPC Semaphores",
+ "semaphores",
+ "freebsd",
+ "kern.ipc.sem",
+ 1000,
+ update_every,
+ RRDSET_TYPE_AREA
);
rd_semaphores = rrddim_add(st_semaphores, "semaphores", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
@@ -1047,16 +1204,19 @@ int do_kern_ipc_sem(int update_every, usec_t dt) {
// --------------------------------------------------------------------
if (unlikely(!st_semaphore_arrays)) {
- st_semaphore_arrays = rrdset_create_localhost("system",
- "ipc_semaphore_arrays",
- NULL,
- "ipc semaphores",
- NULL,
- "IPC Semaphore Arrays",
- "arrays",
- 1000,
- update_every,
- RRDSET_TYPE_AREA
+ st_semaphore_arrays = rrdset_create_localhost(
+ "system",
+ "ipc_semaphore_arrays",
+ NULL,
+ "ipc semaphores",
+ NULL,
+ "IPC Semaphore Arrays",
+ "arrays",
+ "freebsd",
+ "kern.ipc.sem",
+ 1000,
+ update_every,
+ RRDSET_TYPE_AREA
);
rd_semaphore_arrays = rrddim_add(st_semaphore_arrays, "arrays", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
@@ -1118,16 +1278,19 @@ int do_kern_ipc_shm(int update_every, usec_t dt) {
static RRDDIM *rd_segments = NULL, *rd_allocated = NULL;
if (unlikely(!st_segs)) {
- st_segs = rrdset_create_localhost("system",
- "ipc_shared_mem_segs",
- NULL,
- "ipc shared memory",
- NULL,
- "IPC Shared Memory Segments",
- "segments",
- 1000,
- update_every,
- RRDSET_TYPE_AREA
+ st_segs = rrdset_create_localhost(
+ "system",
+ "ipc_shared_mem_segs",
+ NULL,
+ "ipc shared memory",
+ NULL,
+ "IPC Shared Memory Segments",
+ "segments",
+ "freebsd",
+ "kern.ipc.shm",
+ 1000,
+ update_every,
+ RRDSET_TYPE_AREA
);
rd_segments = rrddim_add(st_segs, "segments", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
@@ -1140,16 +1303,19 @@ int do_kern_ipc_shm(int update_every, usec_t dt) {
// --------------------------------------------------------------------
if (unlikely(!st_size)) {
- st_size = rrdset_create_localhost("system",
- "ipc_shared_mem_size",
- NULL,
- "ipc shared memory",
- NULL,
- "IPC Shared Memory Segments Size",
- "kilobytes",
- 1000,
- update_every,
- RRDSET_TYPE_AREA
+ st_size = rrdset_create_localhost(
+ "system",
+ "ipc_shared_mem_size",
+ NULL,
+ "ipc shared memory",
+ NULL,
+ "IPC Shared Memory Segments Size",
+ "kilobytes",
+ "freebsd",
+ "kern.ipc.shm",
+ 1000,
+ update_every,
+ RRDSET_TYPE_AREA
);
rd_allocated = rrddim_add(st_size, "allocated", NULL, 1, KILO_FACTOR, RRD_ALGORITHM_ABSOLUTE);
@@ -1217,16 +1383,19 @@ int do_kern_ipc_msq(int update_every, usec_t dt) {
static RRDDIM *rd_queues = NULL, *rd_messages = NULL, *rd_allocated = NULL, *rd_used = NULL;
if (unlikely(!st_queues)) {
- st_queues = rrdset_create_localhost("system",
- "ipc_msq_queues",
- NULL,
- "ipc message queues",
- NULL,
- "Number of IPC Message Queues",
- "queues",
- 990,
- update_every,
- RRDSET_TYPE_AREA
+ st_queues = rrdset_create_localhost(
+ "system",
+ "ipc_msq_queues",
+ NULL,
+ "ipc message queues",
+ NULL,
+ "Number of IPC Message Queues",
+ "queues",
+ "freebsd",
+ "kern.ipc.msq",
+ 990,
+ update_every,
+ RRDSET_TYPE_AREA
);
rd_queues = rrddim_add(st_queues, "queues", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
@@ -1239,16 +1408,19 @@ int do_kern_ipc_msq(int update_every, usec_t dt) {
// --------------------------------------------------------------------
if (unlikely(!st_messages)) {
- st_messages = rrdset_create_localhost("system",
- "ipc_msq_messages",
- NULL,
- "ipc message queues",
- NULL,
- "Number of Messages in IPC Message Queues",
- "messages",
- 1000,
- update_every,
- RRDSET_TYPE_AREA
+ st_messages = rrdset_create_localhost(
+ "system",
+ "ipc_msq_messages",
+ NULL,
+ "ipc message queues",
+ NULL,
+ "Number of Messages in IPC Message Queues",
+ "messages",
+ "freebsd",
+ "kern.ipc.msq",
+ 1000,
+ update_every,
+ RRDSET_TYPE_AREA
);
rd_messages = rrddim_add(st_messages, "messages", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
@@ -1261,16 +1433,19 @@ int do_kern_ipc_msq(int update_every, usec_t dt) {
// --------------------------------------------------------------------
if (unlikely(!st_size)) {
- st_size = rrdset_create_localhost("system",
- "ipc_msq_size",
- NULL,
- "ipc message queues",
- NULL,
- "Size of IPC Message Queues",
- "bytes",
- 1100,
- update_every,
- RRDSET_TYPE_LINE
+ st_size = rrdset_create_localhost(
+ "system",
+ "ipc_msq_size",
+ NULL,
+ "ipc message queues",
+ NULL,
+ "Size of IPC Message Queues",
+ "bytes",
+ "freebsd",
+ "kern.ipc.msq",
+ 1100,
+ update_every,
+ RRDSET_TYPE_LINE
);
rd_allocated = rrddim_add(st_size, "allocated", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
@@ -1302,16 +1477,19 @@ int do_uptime(int update_every, usec_t dt) {
static RRDDIM *rd = NULL;
if(unlikely(!st)) {
- st = rrdset_create_localhost("system",
- "uptime",
- NULL,
- "uptime",
- NULL,
- "System Uptime",
- "seconds",
- 1000,
- update_every,
- RRDSET_TYPE_LINE
+ st = rrdset_create_localhost(
+ "system",
+ "uptime",
+ NULL,
+ "uptime",
+ NULL,
+ "System Uptime",
+ "seconds",
+ "freebsd",
+ "uptime",
+ 1000,
+ update_every,
+ RRDSET_TYPE_LINE
);
rd = rrddim_add(st, "uptime", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
@@ -1427,16 +1605,19 @@ int do_net_isr(int update_every, usec_t dt) {
static RRDDIM *rd_dispatched = NULL, *rd_hybrid_dispatched = NULL, *rd_qdrops = NULL, *rd_queued = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("system",
- "softnet_stat",
- NULL,
- "softnet_stat",
- NULL,
- "System softnet_stat",
- "events/s",
- 955,
- update_every,
- RRDSET_TYPE_LINE
+ st = rrdset_create_localhost(
+ "system",
+ "softnet_stat",
+ NULL,
+ "softnet_stat",
+ NULL,
+ "System softnet_stat",
+ "events/s",
+ "freebsd",
+ "net.isr",
+ 955,
+ update_every,
+ RRDSET_TYPE_LINE
);
rd_dispatched = rrddim_add(st, "dispatched", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -1477,16 +1658,19 @@ int do_net_isr(int update_every, usec_t dt) {
snprintfz(all_softnet_charts[i].netisr_cpuid, MAX_INT_DIGITS + 17, "cpu%d_softnet_stat", i);
if (unlikely(!all_softnet_charts[i].st)) {
- all_softnet_charts[i].st = rrdset_create_localhost("cpu",
- all_softnet_charts[i].netisr_cpuid,
- NULL,
- "softnet_stat",
- NULL,
- "Per CPU netisr statistics",
- "events/s",
- 1101 + i,
- update_every,
- RRDSET_TYPE_LINE
+ all_softnet_charts[i].st = rrdset_create_localhost(
+ "cpu",
+ all_softnet_charts[i].netisr_cpuid,
+ NULL,
+ "softnet_stat",
+ NULL,
+ "Per CPU netisr statistics",
+ "events/s",
+ "freebsd",
+ "net.isr",
+ 1101 + i,
+ update_every,
+ RRDSET_TYPE_LINE
);
all_softnet_charts[i].rd_dispatched = rrddim_add(all_softnet_charts[i].st, "dispatched",
@@ -1536,16 +1720,19 @@ int do_net_inet_tcp_states(int update_every, usec_t dt) {
static RRDDIM *rd = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv4",
- "tcpsock",
- NULL,
- "tcp",
- NULL,
- "IPv4 TCP Connections",
- "active connections",
- 2500,
- update_every,
- RRDSET_TYPE_LINE
+ st = rrdset_create_localhost(
+ "ipv4",
+ "tcpsock",
+ NULL,
+ "tcp",
+ NULL,
+ "IPv4 TCP Connections",
+ "active connections",
+ "freebsd",
+ "net.inet.tcp.states",
+ 2500,
+ update_every,
+ RRDSET_TYPE_LINE
);
rd = rrddim_add(st, "CurrEstab", "connections", 1, 1, RRD_ALGORITHM_ABSOLUTE);
@@ -1564,7 +1751,8 @@ int do_net_inet_tcp_states(int update_every, usec_t dt) {
int do_net_inet_tcp_stats(int update_every, usec_t dt) {
(void)dt;
- static int do_tcp_packets = -1, do_tcp_errors = -1, do_tcp_handshake = -1, do_tcpext_connaborts = -1, do_tcpext_ofo = -1, do_tcpext_syncookies = -1, do_ecn = -1;
+ static int do_tcp_packets = -1, do_tcp_errors = -1, do_tcp_handshake = -1, do_tcpext_connaborts = -1, do_tcpext_ofo = -1,
+ do_tcpext_syncookies = -1, do_tcpext_listen = -1, do_ecn = -1;
if (unlikely(do_tcp_packets == -1)) {
do_tcp_packets = config_get_boolean("plugin:freebsd:net.inet.tcp.stats", "ipv4 TCP packets", 1);
@@ -1576,12 +1764,15 @@ int do_net_inet_tcp_stats(int update_every, usec_t dt) {
CONFIG_BOOLEAN_AUTO);
do_tcpext_syncookies = config_get_boolean_ondemand("plugin:freebsd:net.inet.tcp.stats", "TCP SYN cookies",
CONFIG_BOOLEAN_AUTO);
+ do_tcpext_listen = config_get_boolean_ondemand("plugin:freebsd:net.inet.tcp.stats", "TCP listen issues",
+ CONFIG_BOOLEAN_AUTO);
do_ecn = config_get_boolean_ondemand("plugin:freebsd:net.inet.tcp.stats", "ECN packets",
CONFIG_BOOLEAN_AUTO);
}
// see http://net-snmp.sourceforge.net/docs/mibs/tcp.html
- if (likely(do_tcp_packets || do_tcp_errors || do_tcp_handshake || do_tcpext_connaborts || do_tcpext_ofo || do_tcpext_syncookies || do_ecn)) {
+ if (likely(do_tcp_packets || do_tcp_errors || do_tcp_handshake || do_tcpext_connaborts || do_tcpext_ofo ||
+ do_tcpext_syncookies || do_tcpext_listen || do_ecn)) {
static int mib[4] = {0, 0, 0, 0};
struct tcpstat tcpstat;
@@ -1598,6 +1789,8 @@ int do_net_inet_tcp_stats(int update_every, usec_t dt) {
error("DISABLED: ipv4.tcpofo chart");
do_tcpext_syncookies = 0;
error("DISABLED: ipv4.tcpsyncookies chart");
+ do_tcpext_listen = 0;
+ error("DISABLED: ipv4.tcplistenissues chart");
do_ecn = 0;
error("DISABLED: ipv4.ecnpkts chart");
error("DISABLED: net.inet.tcp.stats module");
@@ -1611,16 +1804,19 @@ int do_net_inet_tcp_stats(int update_every, usec_t dt) {
static RRDDIM *rd_in_segs = NULL, *rd_out_segs = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv4",
- "tcppackets",
- NULL,
- "tcp",
- NULL,
- "IPv4 TCP Packets",
- "packets/s",
- 2600,
- update_every,
- RRDSET_TYPE_LINE
+ st = rrdset_create_localhost(
+ "ipv4",
+ "tcppackets",
+ NULL,
+ "tcp",
+ NULL,
+ "IPv4 TCP Packets",
+ "packets/s",
+ "freebsd",
+ "net.inet.tcp.stats",
+ 2600,
+ update_every,
+ RRDSET_TYPE_LINE
);
rd_in_segs = rrddim_add(st, "InSegs", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -1640,16 +1836,19 @@ int do_net_inet_tcp_stats(int update_every, usec_t dt) {
static RRDDIM *rd_in_errs = NULL, *rd_in_csum_errs = NULL, *rd_retrans_segs = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv4",
- "tcperrors",
- NULL,
- "tcp",
- NULL,
- "IPv4 TCP Errors",
- "packets/s",
- 2700,
- update_every,
- RRDSET_TYPE_LINE
+ st = rrdset_create_localhost(
+ "ipv4",
+ "tcperrors",
+ NULL,
+ "tcp",
+ NULL,
+ "IPv4 TCP Errors",
+ "packets/s",
+ "freebsd",
+ "net.inet.tcp.stats",
+ 2700,
+ update_every,
+ RRDSET_TYPE_LINE
);
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
@@ -1679,16 +1878,19 @@ int do_net_inet_tcp_stats(int update_every, usec_t dt) {
*rd_attempt_fails = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv4",
- "tcphandshake",
- NULL,
- "tcp",
- NULL,
- "IPv4 TCP Handshake Issues",
- "events/s",
- 2900,
- update_every,
- RRDSET_TYPE_LINE
+ st = rrdset_create_localhost(
+ "ipv4",
+ "tcphandshake",
+ NULL,
+ "tcp",
+ NULL,
+ "IPv4 TCP Handshake Issues",
+ "events/s",
+ "freebsd",
+ "net.inet.tcp.stats",
+ 2900,
+ update_every,
+ RRDSET_TYPE_LINE
);
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
@@ -1717,16 +1919,19 @@ int do_net_inet_tcp_stats(int update_every, usec_t dt) {
*rd_on_timeout = NULL, *rd_on_linger = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv4",
- "tcpconnaborts",
- NULL,
- "tcp",
- NULL,
- "TCP Connection Aborts",
- "connections/s",
- 3010,
- update_every,
- RRDSET_TYPE_LINE
+ st = rrdset_create_localhost(
+ "ipv4",
+ "tcpconnaborts",
+ NULL,
+ "tcp",
+ NULL,
+ "TCP Connection Aborts",
+ "connections/s",
+ "freebsd",
+ "net.inet.tcp.stats",
+ 3010,
+ update_every,
+ RRDSET_TYPE_LINE
);
rd_on_data = rrddim_add(st, "TCPAbortOnData", "baddata", 1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -1754,16 +1959,19 @@ int do_net_inet_tcp_stats(int update_every, usec_t dt) {
static RRDDIM *rd_ofo_queue = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv4",
- "tcpofo",
- NULL,
- "tcp",
- NULL,
- "TCP Out-Of-Order Queue",
- "packets/s",
- 3050,
- update_every,
- RRDSET_TYPE_LINE
+ st = rrdset_create_localhost(
+ "ipv4",
+ "tcpofo",
+ NULL,
+ "tcp",
+ NULL,
+ "TCP Out-Of-Order Queue",
+ "packets/s",
+ "freebsd",
+ "net.inet.tcp.stats",
+ 3050,
+ update_every,
+ RRDSET_TYPE_LINE
);
rd_ofo_queue = rrddim_add(st, "TCPOFOQueue", "inqueue", 1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -1783,16 +1991,19 @@ int do_net_inet_tcp_stats(int update_every, usec_t dt) {
static RRDDIM *rd_recv = NULL, *rd_send = NULL, *rd_failed = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv4",
- "tcpsyncookies",
- NULL,
- "tcp",
- NULL,
- "TCP SYN Cookies",
- "packets/s",
- 3100,
- update_every,
- RRDSET_TYPE_LINE
+ st = rrdset_create_localhost(
+ "ipv4",
+ "tcpsyncookies",
+ NULL,
+ "tcp",
+ NULL,
+ "TCP SYN Cookies",
+ "packets/s",
+ "freebsd",
+ "net.inet.tcp.stats",
+ 3100,
+ update_every,
+ RRDSET_TYPE_LINE
);
rd_recv = rrddim_add(st, "SyncookiesRecv", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -1806,6 +2017,41 @@ int do_net_inet_tcp_stats(int update_every, usec_t dt) {
rrddim_set_by_pointer(st, rd_failed, tcpstat.tcps_sc_zonefail);
rrdset_done(st);
}
+
+ // --------------------------------------------------------------------
+
+ if(do_tcpext_listen == CONFIG_BOOLEAN_YES || (do_tcpext_listen == CONFIG_BOOLEAN_AUTO && tcpstat.tcps_listendrop)) {
+ do_tcpext_listen = CONFIG_BOOLEAN_YES;
+
+ static RRDSET *st_listen = NULL;
+ static RRDDIM *rd_overflows = NULL;
+
+ if(unlikely(!st_listen)) {
+
+ st_listen = rrdset_create_localhost(
+ "ipv4",
+ "tcplistenissues",
+ NULL,
+ "tcp",
+ NULL,
+ "TCP Listen Socket Issues",
+ "packets/s",
+ "freebsd",
+ "net.inet.tcp.stats",
+ 3015,
+ update_every,
+ RRDSET_TYPE_LINE
+ );
+
+ rd_overflows = rrddim_add(st_listen, "ListenOverflows", "overflows", 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ }
+ else
+ rrdset_next(st_listen);
+
+ rrddim_set_by_pointer(st_listen, rd_overflows, tcpstat.tcps_listendrop);
+
+ rrdset_done(st_listen);
+ }
// --------------------------------------------------------------------
@@ -1816,16 +2062,19 @@ int do_net_inet_tcp_stats(int update_every, usec_t dt) {
static RRDDIM *rd_ce = NULL, *rd_no_ect = NULL, *rd_ect0 = NULL, *rd_ect1 = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv4",
- "ecnpkts",
- NULL,
- "ecn",
- NULL,
- "IPv4 ECN Statistics",
- "packets/s",
- 8700,
- update_every,
- RRDSET_TYPE_LINE
+ st = rrdset_create_localhost(
+ "ipv4",
+ "ecnpkts",
+ NULL,
+ "ecn",
+ NULL,
+ "IPv4 ECN Statistics",
+ "packets/s",
+ "freebsd",
+ "net.inet.tcp.stats",
+ 8700,
+ update_every,
+ RRDSET_TYPE_LINE
);
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
@@ -1887,16 +2136,19 @@ int do_net_inet_udp_stats(int update_every, usec_t dt) {
static RRDDIM *rd_in = NULL, *rd_out = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv4",
- "udppackets",
- NULL,
- "udp",
- NULL,
- "IPv4 UDP Packets",
- "packets/s",
- 2601,
- update_every,
- RRDSET_TYPE_LINE
+ st = rrdset_create_localhost(
+ "ipv4",
+ "udppackets",
+ NULL,
+ "udp",
+ NULL,
+ "IPv4 UDP Packets",
+ "packets/s",
+ "freebsd",
+ "net.inet.udp.stats",
+ 2601,
+ update_every,
+ RRDSET_TYPE_LINE
);
rd_in = rrddim_add(st, "InDatagrams", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -1917,16 +2169,19 @@ int do_net_inet_udp_stats(int update_every, usec_t dt) {
*rd_in_csum_errors = NULL, *rd_ignored_multi = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv4",
- "udperrors",
- NULL,
- "udp",
- NULL,
- "IPv4 UDP Errors",
- "events/s",
- 2701,
- update_every,
- RRDSET_TYPE_LINE
+ st = rrdset_create_localhost(
+ "ipv4",
+ "udperrors",
+ NULL,
+ "udp",
+ NULL,
+ "IPv4 UDP Errors",
+ "events/s",
+ "freebsd",
+ "net.inet.udp.stats",
+ 2701,
+ update_every,
+ RRDSET_TYPE_LINE
);
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
@@ -2000,16 +2255,19 @@ int do_net_inet_icmp_stats(int update_every, usec_t dt) {
static RRDDIM *rd_in = NULL, *rd_out = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv4",
- "icmp",
- NULL,
- "icmp",
- NULL,
- "IPv4 ICMP Packets",
- "packets/s",
- 2602,
- update_every,
- RRDSET_TYPE_LINE
+ st = rrdset_create_localhost(
+ "ipv4"
+ , "icmp"
+ , NULL
+ , "icmp"
+ , NULL
+ , "IPv4 ICMP Packets"
+ , "packets/s"
+ , "freebsd"
+ , "net.inet.icmp.stats"
+ , 2602
+ , update_every
+ , RRDSET_TYPE_LINE
);
rd_in = rrddim_add(st, "InMsgs", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -2030,9 +2288,20 @@ int do_net_inet_icmp_stats(int update_every, usec_t dt) {
static RRDDIM *rd_in = NULL, *rd_out = NULL, *rd_in_csum = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv4", "icmp_errors", NULL, "icmp", NULL, "IPv4 ICMP Errors",
- "packets/s",
- 2603, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "ipv4"
+ , "icmp_errors"
+ , NULL
+ , "icmp"
+ , NULL
+ , "IPv4 ICMP Errors"
+ , "packets/s"
+ , "freebsd"
+ , "net.inet.icmp.stats"
+ , 2603
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rd_in = rrddim_add(st, "InErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
rd_out = rrddim_add(st, "OutErrors", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -2055,8 +2324,20 @@ int do_net_inet_icmp_stats(int update_every, usec_t dt) {
static RRDDIM *rd_in_reps = NULL, *rd_out_reps = NULL, *rd_in = NULL, *rd_out = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv4", "icmpmsg", NULL, "icmp", NULL, "IPv4 ICMP Messages",
- "packets/s", 2604, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "ipv4"
+ , "icmpmsg"
+ , NULL
+ , "icmp"
+ , NULL
+ , "IPv4 ICMP Messages"
+ , "packets/s"
+ , "freebsd"
+ , "net.inet.icmp.stats"
+ , 2604
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rd_in_reps = rrddim_add(st, "InEchoReps", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
rd_out_reps = rrddim_add(st, "OutEchoReps", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -2121,16 +2402,19 @@ int do_net_inet_ip_stats(int update_every, usec_t dt) {
*rd_in_delivers = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv4",
- "packets",
- NULL,
- "packets",
- NULL,
- "IPv4 Packets",
- "packets/s",
- 3000,
- update_every,
- RRDSET_TYPE_LINE
+ st = rrdset_create_localhost(
+ "ipv4",
+ "packets",
+ NULL,
+ "packets",
+ NULL,
+ "IPv4 Packets",
+ "packets/s",
+ "freebsd",
+ "net.inet.ip.stats",
+ 3000,
+ update_every,
+ RRDSET_TYPE_LINE
);
rd_in_receives = rrddim_add(st, "InReceives", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -2154,16 +2438,19 @@ int do_net_inet_ip_stats(int update_every, usec_t dt) {
static RRDDIM *rd_ok = NULL, *rd_fails = NULL, *rd_created = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv4",
- "fragsout",
- NULL,
- "fragments",
- NULL,
- "IPv4 Fragments Sent",
- "packets/s",
- 3010,
- update_every,
- RRDSET_TYPE_LINE
+ st = rrdset_create_localhost(
+ "ipv4",
+ "fragsout",
+ NULL,
+ "fragments",
+ NULL,
+ "IPv4 Fragments Sent",
+ "packets/s",
+ "freebsd",
+ "net.inet.ip.stats",
+ 3010,
+ update_every,
+ RRDSET_TYPE_LINE
);
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
@@ -2187,16 +2474,19 @@ int do_net_inet_ip_stats(int update_every, usec_t dt) {
static RRDDIM *rd_ok = NULL, *rd_failed = NULL, *rd_all = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv4",
- "fragsin",
- NULL,
- "fragments",
- NULL,
- "IPv4 Fragments Reassembly",
- "packets/s",
- 3011,
- update_every,
- RRDSET_TYPE_LINE
+ st = rrdset_create_localhost(
+ "ipv4",
+ "fragsin",
+ NULL,
+ "fragments",
+ NULL,
+ "IPv4 Fragments Reassembly",
+ "packets/s",
+ "freebsd",
+ "net.inet.ip.stats",
+ 3011,
+ update_every,
+ RRDSET_TYPE_LINE
);
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
@@ -2222,16 +2512,19 @@ int do_net_inet_ip_stats(int update_every, usec_t dt) {
*rd_in_addr_errors = NULL, *rd_in_unknown_protos = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv4",
- "errors",
- NULL,
- "errors",
- NULL,
- "IPv4 Errors",
- "packets/s",
- 3002,
- update_every,
- RRDSET_TYPE_LINE
+ st = rrdset_create_localhost(
+ "ipv4",
+ "errors",
+ NULL,
+ "errors",
+ NULL,
+ "IPv4 Errors",
+ "packets/s",
+ "freebsd",
+ "net.inet.ip.stats",
+ 3002,
+ update_every,
+ RRDSET_TYPE_LINE
);
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
@@ -2310,16 +2603,19 @@ int do_net_inet6_ip6_stats(int update_every, usec_t dt) {
static RRDDIM *rd_received = NULL, *rd_sent = NULL, *rd_forwarded = NULL, *rd_delivers = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv6",
- "packets",
- NULL,
- "packets",
- NULL,
- "IPv6 Packets",
- "packets/s",
- 3000,
- update_every,
- RRDSET_TYPE_LINE
+ st = rrdset_create_localhost(
+ "ipv6",
+ "packets",
+ NULL,
+ "packets",
+ NULL,
+ "IPv6 Packets",
+ "packets/s",
+ "freebsd",
+ "net.inet6.ip6.stats",
+ 3000,
+ update_every,
+ RRDSET_TYPE_LINE
);
rd_received = rrddim_add(st, "received", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -2347,16 +2643,19 @@ int do_net_inet6_ip6_stats(int update_every, usec_t dt) {
static RRDDIM *rd_ok = NULL, *rd_failed = NULL, *rd_all = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv6",
- "fragsout",
- NULL,
- "fragments",
- NULL,
- "IPv6 Fragments Sent",
- "packets/s",
- 3010,
- update_every,
- RRDSET_TYPE_LINE
+ st = rrdset_create_localhost(
+ "ipv6",
+ "fragsout",
+ NULL,
+ "fragments",
+ NULL,
+ "IPv6 Fragments Sent",
+ "packets/s",
+ "freebsd",
+ "net.inet6.ip6.stats",
+ 3010,
+ update_every,
+ RRDSET_TYPE_LINE
);
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
@@ -2384,16 +2683,19 @@ int do_net_inet6_ip6_stats(int update_every, usec_t dt) {
static RRDDIM *rd_ok = NULL, *rd_failed = NULL, *rd_timeout = NULL, *rd_all = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv6",
- "fragsin",
- NULL,
- "fragments",
- NULL,
- "IPv6 Fragments Reassembly",
- "packets/s",
- 3011,
- update_every,
- RRDSET_TYPE_LINE
+ st = rrdset_create_localhost(
+ "ipv6",
+ "fragsin",
+ NULL,
+ "fragments",
+ NULL,
+ "IPv6 Fragments Reassembly",
+ "packets/s",
+ "freebsd",
+ "net.inet6.ip6.stats",
+ 3011,
+ update_every,
+ RRDSET_TYPE_LINE
);
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
@@ -2432,16 +2734,19 @@ int do_net_inet6_ip6_stats(int update_every, usec_t dt) {
*rd_in_no_routes = NULL, *rd_out_no_routes = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv6",
- "errors",
- NULL,
- "errors",
- NULL,
- "IPv6 Errors",
- "packets/s",
- 3002,
- update_every,
- RRDSET_TYPE_LINE
+ st = rrdset_create_localhost(
+ "ipv6",
+ "errors",
+ NULL,
+ "errors",
+ NULL,
+ "IPv6 Errors",
+ "packets/s",
+ "freebsd",
+ "net.inet6.ip6.stats",
+ 3002,
+ update_every,
+ RRDSET_TYPE_LINE
);
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
@@ -2543,16 +2848,19 @@ int do_net_inet6_icmp6_stats(int update_every, usec_t dt) {
static RRDDIM *rd_received = NULL, *rd_sent = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv6",
- "icmp",
- NULL,
- "icmp",
- NULL,
- "IPv6 ICMP Messages",
- "messages/s",
- 10000,
- update_every,
- RRDSET_TYPE_LINE
+ st = rrdset_create_localhost(
+ "ipv6",
+ "icmp",
+ NULL,
+ "icmp",
+ NULL,
+ "IPv6 ICMP Messages",
+ "messages/s",
+ "freebsd",
+ "net.inet6.icmp6.stats",
+ 10000,
+ update_every,
+ RRDSET_TYPE_LINE
);
rd_received = rrddim_add(st, "received", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -2575,16 +2883,19 @@ int do_net_inet6_icmp6_stats(int update_every, usec_t dt) {
static RRDDIM *rd_received = NULL, *rd_sent = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv6",
- "icmpredir",
- NULL,
- "icmp",
- NULL,
- "IPv6 ICMP Redirects",
- "redirects/s",
- 10050,
- update_every,
- RRDSET_TYPE_LINE
+ st = rrdset_create_localhost(
+ "ipv6",
+ "icmpredir",
+ NULL,
+ "icmp",
+ NULL,
+ "IPv6 ICMP Redirects",
+ "redirects/s",
+ "freebsd",
+ "net.inet6.icmp6.stats",
+ 10050,
+ update_every,
+ RRDSET_TYPE_LINE
);
rd_received = rrddim_add(st, "received", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -2620,15 +2931,18 @@ int do_net_inet6_icmp6_stats(int update_every, usec_t dt) {
*rd_out_parm_problems = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv6",
- "icmperrors",
- NULL, "icmp",
- NULL,
- "IPv6 ICMP Errors",
- "errors/s",
- 10100,
- update_every,
- RRDSET_TYPE_LINE
+ st = rrdset_create_localhost(
+ "ipv6",
+ "icmperrors",
+ NULL, "icmp",
+ NULL,
+ "IPv6 ICMP Errors",
+ "errors/s",
+ "freebsd",
+ "net.inet6.icmp6.stats",
+ 10100,
+ update_every,
+ RRDSET_TYPE_LINE
);
rd_in_errors = rrddim_add(st, "InErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -2671,16 +2985,19 @@ int do_net_inet6_icmp6_stats(int update_every, usec_t dt) {
static RRDDIM *rd_in = NULL, *rd_out = NULL, *rd_in_replies = NULL, *rd_out_replies = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv6",
- "icmpechos",
- NULL,
- "icmp",
- NULL,
- "IPv6 ICMP Echo",
- "messages/s",
- 10200,
- update_every,
- RRDSET_TYPE_LINE
+ st = rrdset_create_localhost(
+ "ipv6",
+ "icmpechos",
+ NULL,
+ "icmp",
+ NULL,
+ "IPv6 ICMP Echo",
+ "messages/s",
+ "freebsd",
+ "net.inet6.icmp6.stats",
+ 10200,
+ update_every,
+ RRDSET_TYPE_LINE
);
rd_in = rrddim_add(st, "InEchos", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -2711,16 +3028,19 @@ int do_net_inet6_icmp6_stats(int update_every, usec_t dt) {
*rd_in_advertisements = NULL, *rd_out_advertisements = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv6",
- "icmprouter",
- NULL,
- "icmp",
- NULL,
- "IPv6 Router Messages",
- "messages/s",
- 10400,
- update_every,
- RRDSET_TYPE_LINE
+ st = rrdset_create_localhost(
+ "ipv6",
+ "icmprouter",
+ NULL,
+ "icmp",
+ NULL,
+ "IPv6 Router Messages",
+ "messages/s",
+ "freebsd",
+ "net.inet6.icmp6.stats",
+ 10400,
+ update_every,
+ RRDSET_TYPE_LINE
);
rd_in_solicits = rrddim_add(st, "InSolicits", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -2751,16 +3071,19 @@ int do_net_inet6_icmp6_stats(int update_every, usec_t dt) {
*rd_in_advertisements = NULL, *rd_out_advertisements = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv6",
- "icmpneighbor",
- NULL,
- "icmp",
- NULL,
- "IPv6 Neighbor Messages",
- "messages/s",
- 10500,
- update_every,
- RRDSET_TYPE_LINE
+ st = rrdset_create_localhost(
+ "ipv6",
+ "icmpneighbor",
+ NULL,
+ "icmp",
+ NULL,
+ "IPv6 Neighbor Messages",
+ "messages/s",
+ "freebsd",
+ "net.inet6.icmp6.stats",
+ 10500,
+ update_every,
+ RRDSET_TYPE_LINE
);
rd_in_solicits = rrddim_add(st, "InSolicits", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -2798,16 +3121,19 @@ int do_net_inet6_icmp6_stats(int update_every, usec_t dt) {
*rd_out_135 = NULL, *rd_out_143 = NULL;
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv6",
- "icmptypes",
- NULL,
- "icmp",
- NULL,
- "IPv6 ICMP Types",
- "messages/s",
- 10700,
- update_every,
- RRDSET_TYPE_LINE
+ st = rrdset_create_localhost(
+ "ipv6",
+ "icmptypes",
+ NULL,
+ "icmp",
+ NULL,
+ "IPv6 ICMP Types",
+ "messages/s",
+ "freebsd",
+ "net.inet6.icmp6.stats",
+ 10700,
+ update_every,
+ RRDSET_TYPE_LINE
);
rd_in_1 = rrddim_add(st, "InType1", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
diff --git a/src/freeipmi_plugin.c b/src/freeipmi_plugin.c
index 42a1ac01..9cd736bb 100644
--- a/src/freeipmi_plugin.c
+++ b/src/freeipmi_plugin.c
@@ -522,6 +522,49 @@ static void send_metrics_to_netdata() {
}
+static int *excluded_record_ids = NULL;
+size_t excluded_record_ids_length = 0;
+
+static void excluded_record_ids_parse(const char *s) {
+ if(!s) return;
+
+ while(*s) {
+ while(*s && !isdigit(*s)) s++;
+
+ if(isdigit(*s)) {
+ char *e;
+ unsigned long n = strtoul(s, &e, 10);
+ s = e;
+
+ if(n != 0) {
+ excluded_record_ids = realloc(excluded_record_ids, (excluded_record_ids_length + 1) * sizeof(int));
+ excluded_record_ids[excluded_record_ids_length++] = (int)n;
+ }
+ }
+ }
+
+ if(debug) {
+ fprintf(stderr, "freeipmi.plugin: excluded record ids:");
+ size_t i;
+ for(i = 0; i < excluded_record_ids_length; i++) {
+ fprintf(stderr, " %d", excluded_record_ids[i]);
+ }
+ fprintf(stderr, "\n");
+ }
+}
+
+
+static int excluded_record_ids_check(int record_id) {
+ size_t i;
+
+ for(i = 0; i < excluded_record_ids_length; i++) {
+ if(excluded_record_ids[i] == record_id)
+ return 1;
+ }
+
+ return 0;
+}
+
static void netdata_get_sensor(
int record_id
, int sensor_number
@@ -546,6 +589,10 @@ static void netdata_get_sensor(
if(!sn) {
// not found, create it
+ // check if it is excluded
+ if(excluded_record_ids_check(record_id))
+ return;
+
sn = calloc(1, sizeof(struct sensor));
if(!sn) {
fatal("cannot allocate %zu bytes of memory.", sizeof(struct sensor));
@@ -1482,6 +1529,9 @@ int main (int argc, char **argv) {
" sensor-config-file FILE filename to read sensor configuration\n"
" default: %s\n"
"\n"
+ " ignore N1,N2,N3,... sensor IDs to ignore\n"
+ " default: none\n"
+ "\n"
" -v\n"
" -V\n"
" version print version and exit\n"
@@ -1538,10 +1588,16 @@ int main (int argc, char **argv) {
if(debug) fprintf(stderr, "freeipmi.plugin: sensor config file set to '%s'\n", sensor_config_file);
continue;
}
+ else if(i < argc && strcmp("ignore", argv[i]) == 0) {
+ excluded_record_ids_parse(argv[++i]);
+ continue;
+ }
error("freeipmi.plugin: ignoring parameter '%s'", argv[i]);
}
+ errno = 0;
+
if(freq > netdata_update_every)
netdata_update_every = freq;
diff --git a/src/global_statistics.c b/src/global_statistics.c
index 88688908..c184b6d6 100644
--- a/src/global_statistics.c
+++ b/src/global_statistics.c
@@ -114,13 +114,13 @@ inline void global_statistics_copy(struct global_statistics *gs, uint8_t options
}
void global_statistics_charts(void) {
- static unsigned long long old_web_requests = 0, old_web_usec = 0,
- old_content_size = 0, old_compressed_content_size = 0;
+ static unsigned long long old_web_requests = 0,
+ old_web_usec = 0,
+ old_content_size = 0,
+ old_compressed_content_size = 0;
- static collected_number compression_ratio = -1, average_response_time = -1;
-
- static RRDSET *stcpu = NULL, *stcpu_thread = NULL, *stclients = NULL, *streqs = NULL, *stbytes = NULL, *stduration = NULL,
- *stcompression = NULL;
+ static collected_number compression_ratio = -1,
+ average_response_time = -1;
struct global_statistics gs;
struct rusage me, thread;
@@ -129,143 +129,280 @@ void global_statistics_charts(void) {
getrusage(RUSAGE_THREAD, &thread);
getrusage(RUSAGE_SELF, &me);
+ {
+ static RRDSET *st_cpu_thread = NULL;
+ static RRDDIM *rd_cpu_thread_user = NULL,
+ *rd_cpu_thread_system = NULL;
+
#ifdef __FreeBSD__
- if (!stcpu_thread) stcpu_thread = rrdset_find_localhost("netdata.plugin_freebsd_cpu");
- if (!stcpu_thread) {
- stcpu_thread = rrdset_create_localhost("netdata", "plugin_freebsd_cpu", NULL, "freebsd", NULL
- , "NetData FreeBSD Plugin CPU usage", "milliseconds/s", 132000
- , localhost->rrd_update_every, RRDSET_TYPE_STACKED);
+ if (unlikely(!st_cpu_thread)) {
+ st_cpu_thread = rrdset_create_localhost(
+ "netdata"
+ , "plugin_freebsd_cpu"
+ , NULL
+ , "freebsd"
+ , NULL
+ , "NetData FreeBSD Plugin CPU usage"
+ , "milliseconds/s"
+ , "netdata"
+ , "stats"
+ , 132000
+ , localhost->rrd_update_every
+ , RRDSET_TYPE_STACKED
+ );
#else
- if (!stcpu_thread) stcpu_thread = rrdset_find_localhost("netdata.plugin_proc_cpu");
- if (!stcpu_thread) {
- stcpu_thread = rrdset_create_localhost("netdata", "plugin_proc_cpu", NULL, "proc", NULL
- , "NetData Proc Plugin CPU usage", "milliseconds/s", 132000
- , localhost->rrd_update_every, RRDSET_TYPE_STACKED);
+ if (unlikely(!st_cpu_thread)) {
+ st_cpu_thread = rrdset_create_localhost(
+ "netdata"
+ , "plugin_proc_cpu"
+ , NULL
+ , "proc"
+ , NULL
+ , "NetData Proc Plugin CPU usage"
+ , "milliseconds/s"
+ , "netdata"
+ , "stats"
+ , 132000
+ , localhost->rrd_update_every
+ , RRDSET_TYPE_STACKED
+ );
#endif
- rrddim_add(stcpu_thread, "user", NULL, 1, 1000, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(stcpu_thread, "system", NULL, 1, 1000, RRD_ALGORITHM_INCREMENTAL);
- } else rrdset_next(stcpu_thread);
+ rd_cpu_thread_user = rrddim_add(st_cpu_thread, "user", NULL, 1, 1000, RRD_ALGORITHM_INCREMENTAL);
+ rd_cpu_thread_system = rrddim_add(st_cpu_thread, "system", NULL, 1, 1000, RRD_ALGORITHM_INCREMENTAL);
+ }
+ else
+ rrdset_next(st_cpu_thread);
- rrddim_set(stcpu_thread, "user", thread.ru_utime.tv_sec * 1000000ULL + thread.ru_utime.tv_usec);
- rrddim_set(stcpu_thread, "system", thread.ru_stime.tv_sec * 1000000ULL + thread.ru_stime.tv_usec);
- rrdset_done(stcpu_thread);
+ rrddim_set_by_pointer(st_cpu_thread, rd_cpu_thread_user, thread.ru_utime.tv_sec * 1000000ULL + thread.ru_utime.tv_usec);
+ rrddim_set_by_pointer(st_cpu_thread, rd_cpu_thread_system, thread.ru_stime.tv_sec * 1000000ULL + thread.ru_stime.tv_usec);
+ rrdset_done(st_cpu_thread);
+ }
// ----------------------------------------------------------------
- if (!stcpu) stcpu = rrdset_find_localhost("netdata.server_cpu");
- if (!stcpu) {
- stcpu = rrdset_create_localhost("netdata", "server_cpu", NULL, "netdata", NULL, "NetData CPU usage"
- , "milliseconds/s", 130000, localhost->rrd_update_every, RRDSET_TYPE_STACKED);
-
- rrddim_add(stcpu, "user", NULL, 1, 1000, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(stcpu, "system", NULL, 1, 1000, RRD_ALGORITHM_INCREMENTAL);
- } else rrdset_next(stcpu);
-
- rrddim_set(stcpu, "user", me.ru_utime.tv_sec * 1000000ULL + me.ru_utime.tv_usec);
- rrddim_set(stcpu, "system", me.ru_stime.tv_sec * 1000000ULL + me.ru_stime.tv_usec);
- rrdset_done(stcpu);
+ {
+ static RRDSET *st_cpu = NULL;
+ static RRDDIM *rd_cpu_user = NULL,
+ *rd_cpu_system = NULL;
+
+ if (unlikely(!st_cpu)) {
+ st_cpu = rrdset_create_localhost(
+ "netdata"
+ , "server_cpu"
+ , NULL
+ , "netdata"
+ , NULL
+ , "NetData CPU usage"
+ , "milliseconds/s"
+ , "netdata"
+ , "stats"
+ , 130000
+ , localhost->rrd_update_every
+ , RRDSET_TYPE_STACKED
+ );
+
+ rd_cpu_user = rrddim_add(st_cpu, "user", NULL, 1, 1000, RRD_ALGORITHM_INCREMENTAL);
+ rd_cpu_system = rrddim_add(st_cpu, "system", NULL, 1, 1000, RRD_ALGORITHM_INCREMENTAL);
+ }
+ else
+ rrdset_next(st_cpu);
+
+ rrddim_set_by_pointer(st_cpu, rd_cpu_user, me.ru_utime.tv_sec * 1000000ULL + me.ru_utime.tv_usec);
+ rrddim_set_by_pointer(st_cpu, rd_cpu_system, me.ru_stime.tv_sec * 1000000ULL + me.ru_stime.tv_usec);
+ rrdset_done(st_cpu);
+ }
// ----------------------------------------------------------------
- if (!stclients) stclients = rrdset_find_localhost("netdata.clients");
- if (!stclients) {
- stclients = rrdset_create_localhost("netdata", "clients", NULL, "netdata", NULL, "NetData Web Clients"
- , "connected clients", 130200, localhost->rrd_update_every, RRDSET_TYPE_LINE);
-
- rrddim_add(stclients, "clients", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
- } else rrdset_next(stclients);
-
- rrddim_set(stclients, "clients", gs.connected_clients);
- rrdset_done(stclients);
+ {
+ static RRDSET *st_clients = NULL;
+ static RRDDIM *rd_clients = NULL;
+
+ if (unlikely(!st_clients)) {
+ st_clients = rrdset_create_localhost(
+ "netdata"
+ , "clients"
+ , NULL
+ , "netdata"
+ , NULL
+ , "NetData Web Clients"
+ , "connected clients"
+ , "netdata"
+ , "stats"
+ , 130200
+ , localhost->rrd_update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rd_clients = rrddim_add(st_clients, "clients", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+ }
+ else
+ rrdset_next(st_clients);
+
+ rrddim_set_by_pointer(st_clients, rd_clients, gs.connected_clients);
+ rrdset_done(st_clients);
+ }
// ----------------------------------------------------------------
- if (!streqs) streqs = rrdset_find_localhost("netdata.requests");
- if (!streqs) {
- streqs = rrdset_create_localhost("netdata", "requests", NULL, "netdata", NULL, "NetData Web Requests"
- , "requests/s", 130300, localhost->rrd_update_every, RRDSET_TYPE_LINE);
-
- rrddim_add(streqs, "requests", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- } else rrdset_next(streqs);
-
- rrddim_set(streqs, "requests", (collected_number) gs.web_requests);
- rrdset_done(streqs);
+ {
+ static RRDSET *st_reqs = NULL;
+ static RRDDIM *rd_requests = NULL;
+
+ if (unlikely(!st_reqs)) {
+ st_reqs = rrdset_create_localhost(
+ "netdata"
+ , "requests"
+ , NULL
+ , "netdata"
+ , NULL
+ , "NetData Web Requests"
+ , "requests/s"
+ , "netdata"
+ , "stats"
+ , 130300
+ , localhost->rrd_update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rd_requests = rrddim_add(st_reqs, "requests", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ }
+ else
+ rrdset_next(st_reqs);
+
+ rrddim_set_by_pointer(st_reqs, rd_requests, (collected_number) gs.web_requests);
+ rrdset_done(st_reqs);
+ }
// ----------------------------------------------------------------
- if (!stbytes) stbytes = rrdset_find_localhost("netdata.net");
- if (!stbytes) {
- stbytes = rrdset_create_localhost("netdata", "net", NULL, "netdata", NULL, "NetData Network Traffic"
- , "kilobits/s", 130000, localhost->rrd_update_every, RRDSET_TYPE_AREA);
-
- rrddim_add(stbytes, "in", NULL, 8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(stbytes, "out", NULL, -8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
- } else rrdset_next(stbytes);
-
- rrddim_set(stbytes, "in", (collected_number) gs.bytes_received);
- rrddim_set(stbytes, "out", (collected_number) gs.bytes_sent);
- rrdset_done(stbytes);
+ {
+ static RRDSET *st_bytes = NULL;
+ static RRDDIM *rd_in = NULL,
+ *rd_out = NULL;
+
+ if (unlikely(!st_bytes)) {
+ st_bytes = rrdset_create_localhost(
+ "netdata"
+ , "net"
+ , NULL
+ , "netdata"
+ , NULL
+ , "NetData Network Traffic"
+ , "kilobits/s"
+ , "netdata"
+ , "stats"
+ , 130000
+ , localhost->rrd_update_every
+ , RRDSET_TYPE_AREA
+ );
+
+ rd_in = rrddim_add(st_bytes, "in", NULL, 8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
+ rd_out = rrddim_add(st_bytes, "out", NULL, -8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
+ }
+ else
+ rrdset_next(st_bytes);
+
+ rrddim_set_by_pointer(st_bytes, rd_in, (collected_number) gs.bytes_received);
+ rrddim_set_by_pointer(st_bytes, rd_out, (collected_number) gs.bytes_sent);
+ rrdset_done(st_bytes);
+ }
// ----------------------------------------------------------------
- if (!stduration) stduration = rrdset_find_localhost("netdata.response_time");
- if (!stduration) {
- stduration = rrdset_create_localhost("netdata", "response_time", NULL, "netdata", NULL
- , "NetData API Response Time", "ms/request", 130400, localhost->rrd_update_every
- , RRDSET_TYPE_LINE);
-
- rrddim_add(stduration, "average", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
- rrddim_add(stduration, "max", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
- } else rrdset_next(stduration);
-
- uint64_t gweb_usec = gs.web_usec;
- uint64_t gweb_requests = gs.web_requests;
-
- uint64_t web_usec = (gweb_usec >= old_web_usec) ? gweb_usec - old_web_usec : 0;
- uint64_t web_requests = (gweb_requests >= old_web_requests) ? gweb_requests - old_web_requests : 0;
-
- old_web_usec = gweb_usec;
- old_web_requests = gweb_requests;
-
- if (web_requests)
- average_response_time = (collected_number) (web_usec / web_requests);
-
- if (unlikely(average_response_time != -1))
- rrddim_set(stduration, "average", average_response_time);
- else
- rrddim_set(stduration, "average", 0);
-
- rrddim_set(stduration, "max", ((gs.web_usec_max)?(collected_number)gs.web_usec_max:average_response_time));
- rrdset_done(stduration);
+ {
+ static RRDSET *st_duration = NULL;
+ static RRDDIM *rd_average = NULL,
+ *rd_max = NULL;
+
+ if (unlikely(!st_duration)) {
+ st_duration = rrdset_create_localhost(
+ "netdata"
+ , "response_time"
+ , NULL
+ , "netdata"
+ , NULL
+ , "NetData API Response Time"
+ , "ms/request"
+ , "netdata"
+ , "stats"
+ , 130400
+ , localhost->rrd_update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rd_average = rrddim_add(st_duration, "average", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
+ rd_max = rrddim_add(st_duration, "max", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
+ }
+ else
+ rrdset_next(st_duration);
+
+ uint64_t gweb_usec = gs.web_usec;
+ uint64_t gweb_requests = gs.web_requests;
+
+ uint64_t web_usec = (gweb_usec >= old_web_usec) ? gweb_usec - old_web_usec : 0;
+ uint64_t web_requests = (gweb_requests >= old_web_requests) ? gweb_requests - old_web_requests : 0;
+
+ old_web_usec = gweb_usec;
+ old_web_requests = gweb_requests;
+
+ if (web_requests)
+ average_response_time = (collected_number) (web_usec / web_requests);
+
+ if (unlikely(average_response_time != -1))
+ rrddim_set_by_pointer(st_duration, rd_average, average_response_time);
+ else
+ rrddim_set_by_pointer(st_duration, rd_average, 0);
+
+ rrddim_set_by_pointer(st_duration, rd_max, ((gs.web_usec_max)?(collected_number)gs.web_usec_max:average_response_time));
+ rrdset_done(st_duration);
+ }
// ----------------------------------------------------------------
- if (!stcompression) stcompression = rrdset_find_localhost("netdata.compression_ratio");
- if (!stcompression) {
- stcompression = rrdset_create_localhost("netdata", "compression_ratio", NULL, "netdata", NULL
- , "NetData API Responses Compression Savings Ratio", "percentage"
- , 130500, localhost->rrd_update_every, RRDSET_TYPE_LINE);
-
- rrddim_add(stcompression, "savings", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
- } else rrdset_next(stcompression);
-
- // since we don't lock here to read the global statistics
- // read the smaller value first
- unsigned long long gcompressed_content_size = gs.compressed_content_size;
- unsigned long long gcontent_size = gs.content_size;
-
- unsigned long long compressed_content_size = gcompressed_content_size - old_compressed_content_size;
- unsigned long long content_size = gcontent_size - old_content_size;
-
- old_compressed_content_size = gcompressed_content_size;
- old_content_size = gcontent_size;
-
- if (content_size && content_size >= compressed_content_size)
- compression_ratio = ((content_size - compressed_content_size) * 100 * 1000) / content_size;
-
- if (compression_ratio != -1)
- rrddim_set(stcompression, "savings", compression_ratio);
-
- rrdset_done(stcompression);
+ {
+ static RRDSET *st_compression = NULL;
+ static RRDDIM *rd_savings = NULL;
+
+ if (unlikely(!st_compression)) {
+ st_compression = rrdset_create_localhost(
+ "netdata"
+ , "compression_ratio"
+ , NULL
+ , "netdata"
+ , NULL
+ , "NetData API Responses Compression Savings Ratio"
+ , "percentage"
+ , "netdata"
+ , "stats"
+ , 130500
+ , localhost->rrd_update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rd_savings = rrddim_add(st_compression, "savings", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
+ }
+ else
+ rrdset_next(st_compression);
+
+ // since we don't lock here to read the global statistics
+ // read the smaller value first
+ unsigned long long gcompressed_content_size = gs.compressed_content_size;
+ unsigned long long gcontent_size = gs.content_size;
+
+ unsigned long long compressed_content_size = gcompressed_content_size - old_compressed_content_size;
+ unsigned long long content_size = gcontent_size - old_content_size;
+
+ old_compressed_content_size = gcompressed_content_size;
+ old_content_size = gcontent_size;
+
+ if (content_size && content_size >= compressed_content_size)
+ compression_ratio = ((content_size - compressed_content_size) * 100 * 1000) / content_size;
+
+ if (compression_ratio != -1)
+ rrddim_set_by_pointer(st_compression, rd_savings, compression_ratio);
+
+ rrdset_done(st_compression);
+ }
}
diff --git a/src/health.c b/src/health.c
index 136a1ecd..dfa7007b 100644
--- a/src/health.c
+++ b/src/health.c
@@ -34,10 +34,10 @@ void health_reload_host(RRDHOST *host) {
rrdhost_wrlock(host);
while(host->templates)
- rrdcalctemplate_free(host, host->templates);
+ rrdcalctemplate_unlink_and_free(host, host->templates);
while(host->alarms)
- rrdcalc_free(host, host->alarms);
+ rrdcalc_unlink_and_free(host, host->alarms);
rrdhost_unlock(host);
@@ -84,7 +84,7 @@ void health_reload(void) {
// ----------------------------------------------------------------------------
// health main thread and friends
-static inline int rrdcalc_value2status(calculated_number n) {
+static inline RRDCALC_STATUS rrdcalc_value2status(calculated_number n) {
if(isnan(n) || isinf(n)) return RRDCALC_STATUS_UNDEFINED;
if(n) return RRDCALC_STATUS_RAISED;
return RRDCALC_STATUS_CLEAR;
@@ -189,7 +189,6 @@ static inline void health_alarm_execute(RRDHOST *host, ALARM_ENTRY *ae) {
done:
health_alarm_log_save(host, ae);
- return;
}
static inline void health_process_notifications(RRDHOST *host, ALARM_ENTRY *ae) {
@@ -537,8 +536,8 @@ void *health_main(void *ptr) {
if(unlikely(!(rc->rrdcalc_flags & RRDCALC_FLAG_RUNNABLE)))
continue;
- int warning_status = RRDCALC_STATUS_UNDEFINED;
- int critical_status = RRDCALC_STATUS_UNDEFINED;
+ RRDCALC_STATUS warning_status = RRDCALC_STATUS_UNDEFINED;
+ RRDCALC_STATUS critical_status = RRDCALC_STATUS_UNDEFINED;
// --------------------------------------------------------
// check the warning expression
@@ -605,7 +604,7 @@ void *health_main(void *ptr) {
// --------------------------------------------------------
// decide the final alarm status
- int status = RRDCALC_STATUS_UNDEFINED;
+ RRDCALC_STATUS status = RRDCALC_STATUS_UNDEFINED;
switch(warning_status) {
case RRDCALC_STATUS_CLEAR:
diff --git a/src/health.h b/src/health.h
index 7028a914..f4157180 100644
--- a/src/health.h
+++ b/src/health.h
@@ -5,26 +5,28 @@ extern int default_health_enabled;
extern int rrdvar_compare(void *a, void *b);
-#define RRDVAR_TYPE_CALCULATED 1
-#define RRDVAR_TYPE_TIME_T 2
-#define RRDVAR_TYPE_COLLECTED 3
-#define RRDVAR_TYPE_TOTAL 4
-#define RRDVAR_TYPE_INT 5
-#define RRDVAR_TYPE_CALCULATED_ALLOCATED 6
-
+typedef enum rrdvar_type {
+ RRDVAR_TYPE_CALCULATED = 1,
+ RRDVAR_TYPE_TIME_T = 2,
+ RRDVAR_TYPE_COLLECTED = 3,
+ RRDVAR_TYPE_TOTAL = 4,
+ RRDVAR_TYPE_INT = 5,
+ RRDVAR_TYPE_CALCULATED_ALLOCATED = 6 // a custom variable, allocated on purpose (ie. not inherited from charts)
+ // used only for custom host global variables
+} RRDVAR_TYPE;
// the variables as stored in the variables indexes
// there are 3 indexes:
-// 1. at each chart (RRDSET.variables_root_index)
-// 2. at each context (RRDFAMILY.variables_root_index)
-// 3. at each host (RRDHOST.variables_root_index)
+// 1. at each chart (RRDSET.rrdvar_root_index)
+// 2. at each context (RRDFAMILY.rrdvar_root_index)
+// 3. at each host (RRDHOST.rrdvar_root_index)
typedef struct rrdvar {
avl avl;
char *name;
uint32_t hash;
- int type;
+ RRDVAR_TYPE type;
void *value;
time_t last_updated;
@@ -35,15 +37,24 @@ typedef struct rrdvar {
// calculated / processed by the normal data collection process
// This means, there will be no speed penalty for using
// these variables
+
+typedef enum rrdvar_options {
+ RRDVAR_OPTION_DEFAULT = (0 << 0),
+ RRDVAR_OPTION_ALLOCATED = (1 << 0) // the value ptr is allocated (not a reference)
+ // future use
+} RRDVAR_OPTIONS;
+
typedef struct rrdsetvar {
+ char *variable; // variable name
+ uint32_t hash; // variable name hash
+
char *key_fullid; // chart type.chart id.variable
char *key_fullname; // chart type.chart name.variable
- char *variable; // variable
- int type;
+ RRDVAR_TYPE type;
void *value;
- uint32_t options;
+ RRDVAR_OPTIONS options;
RRDVAR *var_local;
RRDVAR *var_family;
@@ -75,10 +86,10 @@ typedef struct rrddimvar {
char *key_fullnameid; // chart type.chart name + dimension id
char *key_fullnamename; // chart type.chart name + dimension name
- int type;
+ RRDVAR_TYPE type;
void *value;
- uint32_t options;
+ RRDVAR_OPTIONS options;
RRDVAR *var_local_id;
RRDVAR *var_local_name;
@@ -101,7 +112,7 @@ typedef struct rrddimvar {
// calculated variables (defined in health configuration)
// These aggregate time-series data at fixed intervals
// (defined in their update_every member below)
-// These increase the overhead of netdata.
+// They increase the overhead of netdata.
//
// These calculations are allocated and linked (->next)
// under RRDHOST.
@@ -111,14 +122,6 @@ typedef struct rrddimvar {
// having as RRDSET.calculations the RRDCALC to be processed
// next.
-#define RRDCALC_STATUS_REMOVED -2
-#define RRDCALC_STATUS_UNDEFINED -1
-#define RRDCALC_STATUS_UNINITIALIZED 0
-#define RRDCALC_STATUS_CLEAR 1
-#define RRDCALC_STATUS_RAISED 2
-#define RRDCALC_STATUS_WARNING 3
-#define RRDCALC_STATUS_CRITICAL 4
-
#define RRDCALC_FLAG_DB_ERROR 0x00000001
#define RRDCALC_FLAG_DB_NAN 0x00000002
/* #define RRDCALC_FLAG_DB_STALE 0x00000004 */
@@ -179,7 +182,7 @@ typedef struct rrdcalc {
// ------------------------------------------------------------------------
// runtime information
- int status; // the current status of the alarm
+ RRDCALC_STATUS status; // the current status of the alarm
calculated_number value; // the current value of the alarm
calculated_number old_value; // the previous value of the alarm
@@ -314,8 +317,8 @@ typedef struct alarm_entry {
char *old_value_string;
char *new_value_string;
- int old_status;
- int new_status;
+ RRDCALC_STATUS old_status;
+ RRDCALC_STATUS new_status;
uint32_t flags;
@@ -340,11 +343,11 @@ typedef struct alarm_log {
#include "rrd.h"
extern void rrdsetvar_rename_all(RRDSET *st);
-extern RRDSETVAR *rrdsetvar_create(RRDSET *st, const char *variable, int type, void *value, uint32_t options);
+extern RRDSETVAR *rrdsetvar_create(RRDSET *st, const char *variable, RRDVAR_TYPE type, void *value, RRDVAR_OPTIONS options);
extern void rrdsetvar_free(RRDSETVAR *rs);
extern void rrddimvar_rename_all(RRDDIM *rd);
-extern RRDDIMVAR *rrddimvar_create(RRDDIM *rd, int type, const char *prefix, const char *suffix, void *value, uint32_t options);
+extern RRDDIMVAR *rrddimvar_create(RRDDIM *rd, RRDVAR_TYPE type, const char *prefix, const char *suffix, void *value, RRDVAR_OPTIONS options);
extern void rrddimvar_free(RRDDIMVAR *rs);
extern void rrdsetcalc_link_matching(RRDSET *st);
@@ -364,10 +367,14 @@ extern void health_alarm_log2json(RRDHOST *host, BUFFER *wb, uint32_t after);
void health_api_v1_chart_variables2json(RRDSET *st, BUFFER *buf);
extern RRDVAR *rrdvar_custom_host_variable_create(RRDHOST *host, const char *name);
-extern void rrdvar_custom_host_variable_destroy(RRDHOST *host, const char *name);
-extern void rrdvar_custom_host_variable_set(RRDVAR *rv, calculated_number value);
+extern void rrdvar_custom_host_variable_set(RRDHOST *host, RRDVAR *rv, calculated_number value);
-extern const char *rrdcalc_status2string(int status);
+extern RRDSETVAR *rrdsetvar_custom_chart_variable_create(RRDSET *st, const char *name);
+extern void rrdsetvar_custom_chart_variable_set(RRDSETVAR *rv, calculated_number value);
+
+extern void rrdvar_free_remaining_variables(RRDHOST *host, avl_tree_lock *tree_lock);
+
+extern const char *rrdcalc_status2string(RRDCALC_STATUS status);
extern int health_alarm_log_open(RRDHOST *host);
@@ -389,8 +396,8 @@ extern void health_alarm_log(
time_t duration,
calculated_number old_value,
calculated_number new_value,
- int old_status,
- int new_status,
+ RRDCALC_STATUS old_status,
+ RRDCALC_STATUS new_status,
const char *source,
const char *units,
const char *info,
@@ -403,8 +410,13 @@ extern char *health_config_dir(void);
extern void health_reload_host(RRDHOST *host);
extern void health_alarm_log_free(RRDHOST *host);
-extern void rrdcalc_free(RRDHOST *host, RRDCALC *rc);
-extern void rrdcalctemplate_free(RRDHOST *host, RRDCALCTEMPLATE *rt);
+extern void rrdcalc_free(RRDCALC *rc);
+extern void rrdcalc_unlink_and_free(RRDHOST *host, RRDCALC *rc);
+
+extern void rrdcalctemplate_free(RRDCALCTEMPLATE *rt);
+extern void rrdcalctemplate_unlink_and_free(RRDHOST *host, RRDCALCTEMPLATE *rt);
+
+extern int rrdvar_callback_for_all_host_variables(RRDHOST *host, int (*callback)(void *rrdvar, void *data), void *data);
#ifdef NETDATA_HEALTH_INTERNALS
#define RRDVAR_MAX_LENGTH 1024
@@ -416,7 +428,7 @@ extern int rrdvar_fix_name(char *variable);
extern RRDCALC *rrdcalc_create(RRDHOST *host, RRDCALCTEMPLATE *rt, const char *chart);
extern void rrdcalc_create_part2(RRDHOST *host, RRDCALC *rc);
-extern RRDVAR *rrdvar_create_and_index(const char *scope, avl_tree_lock *tree, const char *name, int type, void *value);
+extern RRDVAR *rrdvar_create_and_index(const char *scope, avl_tree_lock *tree, const char *name, RRDVAR_TYPE type, void *value);
extern void rrdvar_free(RRDHOST *host, avl_tree_lock *tree, RRDVAR *rv);
extern void health_alarm_log_free_one_nochecks_nounlink(ALARM_ENTRY *ae);
diff --git a/src/health_config.c b/src/health_config.c
index 2ead82ef..108eecc4 100644
--- a/src/health_config.c
+++ b/src/health_config.c
@@ -505,11 +505,12 @@ int health_readfile(RRDHOST *host, const char *path, const char *filename) {
if(hash == hash_alarm && !strcasecmp(key, HEALTH_ALARM_KEY)) {
if (rc && (ignore_this || !rrdcalc_add_alarm_from_config(host, rc)))
- rrdcalc_free(host, rc);
+ rrdcalc_free(rc);
if(rt) {
if (ignore_this || !rrdcalctemplate_add_template_from_config(host, rt))
- rrdcalctemplate_free(host, rt);
+ rrdcalctemplate_free(rt);
+
rt = NULL;
}
@@ -532,12 +533,13 @@ int health_readfile(RRDHOST *host, const char *path, const char *filename) {
else if(hash == hash_template && !strcasecmp(key, HEALTH_TEMPLATE_KEY)) {
if(rc) {
if(ignore_this || !rrdcalc_add_alarm_from_config(host, rc))
- rrdcalc_free(host, rc);
+ rrdcalc_free(rc);
+
rc = NULL;
}
if(rt && (ignore_this || !rrdcalctemplate_add_template_from_config(host, rt)))
- rrdcalctemplate_free(host, rt);
+ rrdcalctemplate_free(rt);
rt = callocz(1, sizeof(RRDCALCTEMPLATE));
rt->name = strdupz(value);
@@ -833,10 +835,10 @@ int health_readfile(RRDHOST *host, const char *path, const char *filename) {
}
if(rc && (ignore_this || !rrdcalc_add_alarm_from_config(host, rc)))
- rrdcalc_free(host, rc);
+ rrdcalc_free(rc);
if(rt && (ignore_this || !rrdcalctemplate_add_template_from_config(host, rt)))
- rrdcalctemplate_free(host, rt);
+ rrdcalctemplate_free(rt);
fclose(fp);
return 1;
diff --git a/src/health_log.c b/src/health_log.c
index 9881d35d..0314b086 100644
--- a/src/health_log.c
+++ b/src/health_log.c
@@ -351,8 +351,8 @@ inline void health_alarm_log(
time_t duration,
calculated_number old_value,
calculated_number new_value,
- int old_status,
- int new_status,
+ RRDCALC_STATUS old_status,
+ RRDCALC_STATUS new_status,
const char *source,
const char *units,
const char *info,
diff --git a/src/ipc.c b/src/ipc.c
index 1dabf5e1..a9076fca 100644
--- a/src/ipc.c
+++ b/src/ipc.c
@@ -163,11 +163,12 @@ static inline int ipc_sem_get_status(struct ipc_status *st) {
int do_ipc(int update_every, usec_t dt) {
(void)dt;
- static int initialized = 0, read_limits_next = 0;
+ static int initialized = 0, read_limits_next = -1;
static struct ipc_limits limits;
static struct ipc_status status;
- static RRDVAR *arrays_max = NULL, *semaphores_max = NULL;
- static RRDSET *semaphores = NULL, *arrays = NULL;
+ static RRDSETVAR *arrays_max = NULL, *semaphores_max = NULL;
+ static RRDSET *st_semaphores = NULL, *st_arrays = NULL;
+ static RRDDIM *rd_semaphores = NULL, *rd_arrays = NULL;
if(unlikely(!initialized)) {
initialized = 1;
@@ -184,28 +185,46 @@ int do_ipc(int update_every, usec_t dt) {
return 1;
}
- arrays_max = rrdvar_custom_host_variable_create(localhost, "ipc.semaphores.arrays.max");
- semaphores_max = rrdvar_custom_host_variable_create(localhost, "ipc.semaphores.max");
-
- if(arrays_max) rrdvar_custom_host_variable_set(arrays_max, limits.semmni);
- if(semaphores_max) rrdvar_custom_host_variable_set(semaphores_max, limits.semmns);
-
// create the charts
- semaphores = rrdset_find_localhost("system.ipc_semaphores");
- if(!semaphores) {
- semaphores = rrdset_create_localhost("system", "ipc_semaphores", NULL, "ipc semaphores", NULL
- , "IPC Semaphores", "semaphores", 1000, localhost->rrd_update_every
- , RRDSET_TYPE_AREA);
- rrddim_add(semaphores, "semaphores", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+ if(unlikely(!st_semaphores)) {
+ st_semaphores = rrdset_create_localhost(
+ "system"
+ , "ipc_semaphores"
+ , NULL
+ , "ipc semaphores"
+ , NULL
+ , "IPC Semaphores"
+ , "semaphores"
+ , "linux"
+ , "ipc"
+ , 1000
+ , localhost->rrd_update_every
+ , RRDSET_TYPE_AREA
+ );
+ rd_semaphores = rrddim_add(st_semaphores, "semaphores", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
}
- arrays = rrdset_find_localhost("system.ipc_semaphore_arrays");
- if(!arrays) {
- arrays = rrdset_create_localhost("system", "ipc_semaphore_arrays", NULL, "ipc semaphores", NULL
- , "IPC Semaphore Arrays", "arrays", 1000, localhost->rrd_update_every
- , RRDSET_TYPE_AREA);
- rrddim_add(arrays, "arrays", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+ if(unlikely(!st_arrays)) {
+ st_arrays = rrdset_create_localhost(
+ "system"
+ , "ipc_semaphore_arrays"
+ , NULL
+ , "ipc semaphores"
+ , NULL
+ , "IPC Semaphore Arrays"
+ , "arrays"
+ , "linux"
+ , "ipc"
+ , 1000
+ , localhost->rrd_update_every
+ , RRDSET_TYPE_AREA
+ );
+ rd_arrays = rrddim_add(st_arrays, "arrays", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
}
+
+ // variables
+ semaphores_max = rrdsetvar_custom_chart_variable_create(st_semaphores, "ipc.semaphores.max");
+ arrays_max = rrdsetvar_custom_chart_variable_create(st_arrays, "ipc.semaphores.arrays.max");
}
if(unlikely(read_limits_next < 0)) {
@@ -213,11 +232,11 @@ int do_ipc(int update_every, usec_t dt) {
error("Unable to fetch semaphore limits.");
}
else {
- if(arrays_max) rrdvar_custom_host_variable_set(arrays_max, limits.semmni);
- if(semaphores_max) rrdvar_custom_host_variable_set(semaphores_max, limits.semmns);
+ if(semaphores_max) rrdsetvar_custom_chart_variable_set(semaphores_max, limits.semmns);
+ if(arrays_max) rrdsetvar_custom_chart_variable_set(arrays_max, limits.semmni);
- arrays->red = limits.semmni;
- semaphores->red = limits.semmns;
+ st_arrays->red = limits.semmni;
+ st_semaphores->red = limits.semmns;
read_limits_next = 60 / update_every;
}
@@ -230,13 +249,13 @@ int do_ipc(int update_every, usec_t dt) {
return 0;
}
- if(semaphores->counter_done) rrdset_next(semaphores);
- rrddim_set(semaphores, "semaphores", status.semaem);
- rrdset_done(semaphores);
+ if(st_semaphores->counter_done) rrdset_next(st_semaphores);
+ rrddim_set_by_pointer(st_semaphores, rd_semaphores, status.semaem);
+ rrdset_done(st_semaphores);
- if(arrays->counter_done) rrdset_next(arrays);
- rrddim_set(arrays, "arrays", status.semusz);
- rrdset_done(arrays);
+ if(st_arrays->counter_done) rrdset_next(st_arrays);
+ rrddim_set_by_pointer(st_arrays, rd_arrays, status.semusz);
+ rrdset_done(st_arrays);
return 0;
}
diff --git a/src/macos_fw.c b/src/macos_fw.c
index fa103e11..5e8ce0ee 100644
--- a/src/macos_fw.c
+++ b/src/macos_fw.c
@@ -112,8 +112,14 @@ int do_macos_iokit(int update_every, usec_t dt) {
CFRelease(properties);
IOObjectRelease(drive_media);
+ if(unlikely(!diskstat.name || !*diskstat.name)) {
+ IOObjectRelease(drive);
+ continue;
+ }
+
/* Obtain the properties for this drive object. */
if (unlikely(IORegistryEntryCreateCFProperties(drive, (CFMutableDictionaryRef *)&properties, kCFAllocatorDefault, 0))) {
+ IOObjectRelease(drive);
error("MACOS: IORegistryEntryCreateCFProperties() failed");
do_io = 0;
error("DISABLED: system.io");
@@ -138,9 +144,20 @@ int do_macos_iokit(int update_every, usec_t dt) {
st = rrdset_find_bytype_localhost("disk", diskstat.name);
if (unlikely(!st)) {
- st = rrdset_create_localhost("disk", diskstat.name, NULL, diskstat.name, "disk.io"
- , "Disk I/O Bandwidth", "kilobytes/s", 2000, update_every
- , RRDSET_TYPE_AREA);
+ st = rrdset_create_localhost(
+ "disk"
+ , diskstat.name
+ , NULL
+ , diskstat.name
+ , "disk.io"
+ , "Disk I/O Bandwidth"
+ , "kilobytes/s"
+ , "macos"
+ , "iokit"
+ , 2000
+ , update_every
+ , RRDSET_TYPE_AREA
+ );
rrddim_add(st, "reads", NULL, 1, 1024, RRD_ALGORITHM_INCREMENTAL);
rrddim_add(st, "writes", NULL, -1, 1024, RRD_ALGORITHM_INCREMENTAL);
@@ -165,9 +182,20 @@ int do_macos_iokit(int update_every, usec_t dt) {
st = rrdset_find_bytype_localhost("disk_ops", diskstat.name);
if (unlikely(!st)) {
- st = rrdset_create_localhost("disk_ops", diskstat.name, NULL, diskstat.name, "disk.ops"
- , "Disk Completed I/O Operations", "operations/s", 2001
- , update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "disk_ops"
+ , diskstat.name
+ , NULL
+ , diskstat.name
+ , "disk.ops"
+ , "Disk Completed I/O Operations"
+ , "operations/s"
+ , "macos"
+ , "iokit"
+ , 2001
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
rrddim_add(st, "reads", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -193,9 +221,20 @@ int do_macos_iokit(int update_every, usec_t dt) {
st = rrdset_find_bytype_localhost("disk_util", diskstat.name);
if (unlikely(!st)) {
- st = rrdset_create_localhost("disk_util", diskstat.name, NULL, diskstat.name, "disk.util"
- , "Disk Utilization Time", "% of time working", 2004, update_every
- , RRDSET_TYPE_AREA);
+ st = rrdset_create_localhost(
+ "disk_util"
+ , diskstat.name
+ , NULL
+ , diskstat.name
+ , "disk.util"
+ , "Disk Utilization Time"
+ , "% of time working"
+ , "macos"
+ , "iokit"
+ , 2004
+ , update_every
+ , RRDSET_TYPE_AREA
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
rrddim_add(st, "utilization", NULL, 1, 10000000, RRD_ALGORITHM_INCREMENTAL);
@@ -220,9 +259,20 @@ int do_macos_iokit(int update_every, usec_t dt) {
st = rrdset_find_bytype_localhost("disk_iotime", diskstat.name);
if (unlikely(!st)) {
- st = rrdset_create_localhost("disk_iotime", diskstat.name, NULL, diskstat.name, "disk.iotime"
- , "Disk Total I/O Time", "milliseconds/s", 2022, update_every
- , RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "disk_iotime"
+ , diskstat.name
+ , NULL
+ , diskstat.name
+ , "disk.iotime"
+ , "Disk Total I/O Time"
+ , "milliseconds/s"
+ , "macos"
+ , "iokit"
+ , 2022
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
rrddim_add(st, "reads", NULL, 1, 1000000, RRD_ALGORITHM_INCREMENTAL);
@@ -246,9 +296,20 @@ int do_macos_iokit(int update_every, usec_t dt) {
st = rrdset_find_bytype_localhost("disk_await", diskstat.name);
if (unlikely(!st)) {
- st = rrdset_create_localhost("disk_await", diskstat.name, NULL, diskstat.name, "disk.await"
- , "Average Completed I/O Operation Time", "ms per operation"
- , 2005, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "disk_await"
+ , diskstat.name
+ , NULL
+ , diskstat.name
+ , "disk.await"
+ , "Average Completed I/O Operation Time"
+ , "ms per operation"
+ , "macos"
+ , "iokit"
+ , 2005
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
rrddim_add(st, "reads", NULL, 1, 1000000, RRD_ALGORITHM_ABSOLUTE);
@@ -266,10 +327,20 @@ int do_macos_iokit(int update_every, usec_t dt) {
st = rrdset_find_bytype_localhost("disk_avgsz", diskstat.name);
if (unlikely(!st)) {
- st = rrdset_create_localhost("disk_avgsz", diskstat.name, NULL, diskstat.name, "disk.avgsz"
- , "Average Completed I/O Operation Bandwidth"
- , "kilobytes per operation", 2006, update_every
- , RRDSET_TYPE_AREA);
+ st = rrdset_create_localhost(
+ "disk_avgsz"
+ , diskstat.name
+ , NULL
+ , diskstat.name
+ , "disk.avgsz"
+ , "Average Completed I/O Operation Bandwidth"
+ , "kilobytes per operation"
+ , "macos"
+ , "iokit"
+ , 2006
+ , update_every
+ , RRDSET_TYPE_AREA
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
rrddim_add(st, "reads", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
@@ -287,9 +358,20 @@ int do_macos_iokit(int update_every, usec_t dt) {
st = rrdset_find_bytype_localhost("disk_svctm", diskstat.name);
if (unlikely(!st)) {
- st = rrdset_create_localhost("disk_svctm", diskstat.name, NULL, diskstat.name, "disk.svctm"
- , "Average Service Time", "ms per operation", 2007
- , update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "disk_svctm"
+ , diskstat.name
+ , NULL
+ , diskstat.name
+ , "disk.svctm"
+ , "Average Service Time"
+ , "ms per operation"
+ , "macos"
+ , "iokit"
+ , 2007
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
rrddim_add(st, "svctm", NULL, 1, 1000000, RRD_ALGORITHM_ABSOLUTE);
@@ -318,8 +400,20 @@ int do_macos_iokit(int update_every, usec_t dt) {
if (likely(do_io)) {
st = rrdset_find_bytype_localhost("system", "io");
if (unlikely(!st)) {
- st = rrdset_create_localhost("system", "io", NULL, "disk", NULL, "Disk I/O", "kilobytes/s", 150
- , update_every, RRDSET_TYPE_AREA);
+ st = rrdset_create_localhost(
+ "system"
+ , "io"
+ , NULL
+ , "disk"
+ , NULL
+ , "Disk I/O"
+ , "kilobytes/s"
+ , "macos"
+ , "iokit"
+ , 150
+ , update_every
+ , RRDSET_TYPE_AREA
+ );
rrddim_add(st, "in", NULL, 1, 1024, RRD_ALGORITHM_INCREMENTAL);
rrddim_add(st, "out", NULL, -1, 1024, RRD_ALGORITHM_INCREMENTAL);
}
@@ -359,14 +453,24 @@ int do_macos_iokit(int update_every, usec_t dt) {
st = rrdset_find_bytype_localhost("disk_space", mntbuf[i].f_mntonname);
if (unlikely(!st)) {
snprintfz(title, 4096, "Disk Space Usage for %s [%s]", mntbuf[i].f_mntonname, mntbuf[i].f_mntfromname);
- st = rrdset_create_localhost("disk_space", mntbuf[i].f_mntonname, NULL, mntbuf[i].f_mntonname
- , "disk.space", title, "GB", 2023, update_every
- , RRDSET_TYPE_STACKED);
+ st = rrdset_create_localhost(
+ "disk_space"
+ , mntbuf[i].f_mntonname
+ , NULL
+ , mntbuf[i].f_mntonname
+ , "disk.space"
+ , title
+ , "GB"
+ , "macos"
+ , "iokit"
+ , 2023
+ , update_every
+ , RRDSET_TYPE_STACKED
+ );
rrddim_add(st, "avail", NULL, mntbuf[i].f_bsize, GIGA_FACTOR, RRD_ALGORITHM_ABSOLUTE);
rrddim_add(st, "used", NULL, mntbuf[i].f_bsize, GIGA_FACTOR, RRD_ALGORITHM_ABSOLUTE);
- rrddim_add(st, "reserved_for_root", "reserved for root", mntbuf[i].f_bsize, GIGA_FACTOR,
- RRD_ALGORITHM_ABSOLUTE);
+ rrddim_add(st, "reserved_for_root", "reserved for root", mntbuf[i].f_bsize, GIGA_FACTOR, RRD_ALGORITHM_ABSOLUTE);
} else
rrdset_next(st);
@@ -382,9 +486,20 @@ int do_macos_iokit(int update_every, usec_t dt) {
st = rrdset_find_bytype_localhost("disk_inodes", mntbuf[i].f_mntonname);
if (unlikely(!st)) {
snprintfz(title, 4096, "Disk Files (inodes) Usage for %s [%s]", mntbuf[i].f_mntonname, mntbuf[i].f_mntfromname);
- st = rrdset_create_localhost("disk_inodes", mntbuf[i].f_mntonname, NULL, mntbuf[i].f_mntonname
- , "disk.inodes", title, "Inodes", 2024, update_every
- , RRDSET_TYPE_STACKED);
+ st = rrdset_create_localhost(
+ "disk_inodes"
+ , mntbuf[i].f_mntonname
+ , NULL
+ , mntbuf[i].f_mntonname
+ , "disk.inodes"
+ , title
+ , "Inodes"
+ , "macos"
+ , "iokit"
+ , 2024
+ , update_every
+ , RRDSET_TYPE_STACKED
+ );
rrddim_add(st, "avail", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
rrddim_add(st, "used", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
@@ -417,8 +532,20 @@ int do_macos_iokit(int update_every, usec_t dt) {
st = rrdset_find_bytype_localhost("net", ifa->ifa_name);
if (unlikely(!st)) {
- st = rrdset_create_localhost("net", ifa->ifa_name, NULL, ifa->ifa_name, "net.net", "Bandwidth"
- , "kilobits/s", 7000, update_every, RRDSET_TYPE_AREA);
+ st = rrdset_create_localhost(
+ "net"
+ , ifa->ifa_name
+ , NULL
+ , ifa->ifa_name
+ , "net.net"
+ , "Bandwidth"
+ , "kilobits/s"
+ , "macos"
+ , "iokit"
+ , 7000
+ , update_every
+ , RRDSET_TYPE_AREA
+ );
rrddim_add(st, "received", NULL, 8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
rrddim_add(st, "sent", NULL, -8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
@@ -433,8 +560,20 @@ int do_macos_iokit(int update_every, usec_t dt) {
st = rrdset_find_bytype_localhost("net_packets", ifa->ifa_name);
if (unlikely(!st)) {
- st = rrdset_create_localhost("net_packets", ifa->ifa_name, NULL, ifa->ifa_name, "net.packets"
- , "Packets", "packets/s", 7001, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "net_packets"
+ , ifa->ifa_name
+ , NULL
+ , ifa->ifa_name
+ , "net.packets"
+ , "Packets"
+ , "packets/s"
+ , "macos"
+ , "iokit"
+ , 7001
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
rrddim_add(st, "received", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -454,8 +593,20 @@ int do_macos_iokit(int update_every, usec_t dt) {
st = rrdset_find_bytype_localhost("net_errors", ifa->ifa_name);
if (unlikely(!st)) {
- st = rrdset_create_localhost("net_errors", ifa->ifa_name, NULL, ifa->ifa_name, "net.errors"
- , "Interface Errors", "errors/s", 7002, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "net_errors"
+ , ifa->ifa_name
+ , NULL
+ , ifa->ifa_name
+ , "net.errors"
+ , "Interface Errors"
+ , "errors/s"
+ , "macos"
+ , "iokit"
+ , 7002
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
rrddim_add(st, "inbound", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -471,8 +622,20 @@ int do_macos_iokit(int update_every, usec_t dt) {
st = rrdset_find_bytype_localhost("net_drops", ifa->ifa_name);
if (unlikely(!st)) {
- st = rrdset_create_localhost("net_drops", ifa->ifa_name, NULL, ifa->ifa_name, "net.drops"
- , "Interface Drops", "drops/s", 7003, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "net_drops"
+ , ifa->ifa_name
+ , NULL
+ , ifa->ifa_name
+ , "net.drops"
+ , "Interface Drops"
+ , "drops/s"
+ , "macos"
+ , "iokit"
+ , 7003
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
rrddim_add(st, "inbound", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -486,9 +649,20 @@ int do_macos_iokit(int update_every, usec_t dt) {
st = rrdset_find_bytype_localhost("net_events", ifa->ifa_name);
if (unlikely(!st)) {
- st = rrdset_create_localhost("net_events", ifa->ifa_name, NULL, ifa->ifa_name, "net.events"
- , "Network Interface Events", "events/s", 7006, update_every
- , RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "net_events"
+ , ifa->ifa_name
+ , NULL
+ , ifa->ifa_name
+ , "net.events"
+ , "Network Interface Events"
+ , "events/s"
+ , "macos"
+ , "iokit"
+ , 7006
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
rrddim_add(st, "frames", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
diff --git a/src/macos_mach_smi.c b/src/macos_mach_smi.c
index da282551..bcde589f 100644
--- a/src/macos_mach_smi.c
+++ b/src/macos_mach_smi.c
@@ -25,7 +25,11 @@ int do_macos_mach_smi(int update_every, usec_t dt) {
natural_t cp_time[CPU_STATE_MAX];
// NEEDED BY: do_ram, do_swapio, do_pgfaults
+#if (defined __MAC_OS_X_VERSION_MIN_REQUIRED && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060)
vm_statistics64_data_t vm_statistics;
+#else
+ vm_statistics_data_t vm_statistics;
+#endif
host = mach_host_self();
kr = host_page_size(host, &system_pagesize);
@@ -50,8 +54,20 @@ int do_macos_mach_smi(int update_every, usec_t dt) {
st = rrdset_find_bytype_localhost("system", "cpu");
if (unlikely(!st)) {
- st = rrdset_create_localhost("system", "cpu", NULL, "cpu", "system.cpu", "Total CPU utilization"
- , "percentage", 100, update_every, RRDSET_TYPE_STACKED);
+ st = rrdset_create_localhost(
+ "system"
+ , "cpu"
+ , NULL
+ , "cpu"
+ , "system.cpu"
+ , "Total CPU utilization"
+ , "percentage"
+ , "macos"
+ , "mach_smi"
+ , 100
+ , update_every
+ , RRDSET_TYPE_STACKED
+ );
rrddim_add(st, "user", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
rrddim_add(st, "nice", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
@@ -73,8 +89,13 @@ int do_macos_mach_smi(int update_every, usec_t dt) {
// --------------------------------------------------------------------
if (likely(do_ram || do_swapio || do_pgfaults)) {
+#if (defined __MAC_OS_X_VERSION_MIN_REQUIRED && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060)
count = sizeof(vm_statistics64_data_t);
kr = host_statistics64(host, HOST_VM_INFO64, (host_info64_t)&vm_statistics, &count);
+#else
+ count = sizeof(vm_statistics_data_t);
+ kr = host_statistics(host, HOST_VM_INFO, (host_info_t)&vm_statistics, &count);
+#endif
if (unlikely(kr != KERN_SUCCESS)) {
error("MACOS: host_statistics64() failed: %s", mach_error_string(kr));
do_ram = 0;
@@ -87,13 +108,27 @@ int do_macos_mach_smi(int update_every, usec_t dt) {
if (likely(do_ram)) {
st = rrdset_find_localhost("system.ram");
if (unlikely(!st)) {
- st = rrdset_create_localhost("system", "ram", NULL, "ram", NULL, "System RAM", "MB", 200
- , update_every, RRDSET_TYPE_STACKED);
+ st = rrdset_create_localhost(
+ "system"
+ , "ram"
+ , NULL
+ , "ram"
+ , NULL
+ , "System RAM"
+ , "MB"
+ , "macos"
+ , "mach_smi"
+ , 200
+ , update_every
+ , RRDSET_TYPE_STACKED
+ );
rrddim_add(st, "active", NULL, system_pagesize, 1048576, RRD_ALGORITHM_ABSOLUTE);
rrddim_add(st, "wired", NULL, system_pagesize, 1048576, RRD_ALGORITHM_ABSOLUTE);
+#if (defined __MAC_OS_X_VERSION_MIN_REQUIRED && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090)
rrddim_add(st, "throttled", NULL, system_pagesize, 1048576, RRD_ALGORITHM_ABSOLUTE);
rrddim_add(st, "compressor", NULL, system_pagesize, 1048576, RRD_ALGORITHM_ABSOLUTE);
+#endif
rrddim_add(st, "inactive", NULL, system_pagesize, 1048576, RRD_ALGORITHM_ABSOLUTE);
rrddim_add(st, "purgeable", NULL, system_pagesize, 1048576, RRD_ALGORITHM_ABSOLUTE);
rrddim_add(st, "speculative", NULL, system_pagesize, 1048576, RRD_ALGORITHM_ABSOLUTE);
@@ -103,8 +138,10 @@ int do_macos_mach_smi(int update_every, usec_t dt) {
rrddim_set(st, "active", vm_statistics.active_count);
rrddim_set(st, "wired", vm_statistics.wire_count);
+#if (defined __MAC_OS_X_VERSION_MIN_REQUIRED && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090)
rrddim_set(st, "throttled", vm_statistics.throttled_count);
rrddim_set(st, "compressor", vm_statistics.compressor_page_count);
+#endif
rrddim_set(st, "inactive", vm_statistics.inactive_count);
rrddim_set(st, "purgeable", vm_statistics.purgeable_count);
rrddim_set(st, "speculative", vm_statistics.speculative_count);
@@ -112,13 +149,26 @@ int do_macos_mach_smi(int update_every, usec_t dt) {
rrdset_done(st);
}
+#if (defined __MAC_OS_X_VERSION_MIN_REQUIRED && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090)
// --------------------------------------------------------------------
if (likely(do_swapio)) {
st = rrdset_find_localhost("system.swapio");
if (unlikely(!st)) {
- st = rrdset_create_localhost("system", "swapio", NULL, "swap", NULL, "Swap I/O", "kilobytes/s", 250
- , update_every, RRDSET_TYPE_AREA);
+ st = rrdset_create_localhost(
+ "system"
+ , "swapio"
+ , NULL
+ , "swap"
+ , NULL
+ , "Swap I/O"
+ , "kilobytes/s"
+ , "macos"
+ , "mach_smi"
+ , 250
+ , update_every
+ , RRDSET_TYPE_AREA
+ );
rrddim_add(st, "in", NULL, system_pagesize, 1024, RRD_ALGORITHM_INCREMENTAL);
rrddim_add(st, "out", NULL, -system_pagesize, 1024, RRD_ALGORITHM_INCREMENTAL);
@@ -129,22 +179,37 @@ int do_macos_mach_smi(int update_every, usec_t dt) {
rrddim_set(st, "out", vm_statistics.swapouts);
rrdset_done(st);
}
+#endif
// --------------------------------------------------------------------
if (likely(do_pgfaults)) {
st = rrdset_find_localhost("mem.pgfaults");
if (unlikely(!st)) {
- st = rrdset_create_localhost("mem", "pgfaults", NULL, "system", NULL, "Memory Page Faults"
- , "page faults/s", 500, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "mem"
+ , "pgfaults"
+ , NULL
+ , "system"
+ , NULL
+ , "Memory Page Faults"
+ , "page faults/s"
+ , "macos"
+ , "mach_smi"
+ , 500
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
rrddim_add(st, "memory", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
rrddim_add(st, "cow", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
rrddim_add(st, "pagein", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
rrddim_add(st, "pageout", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+#if (defined __MAC_OS_X_VERSION_MIN_REQUIRED && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090)
rrddim_add(st, "compress", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
rrddim_add(st, "decompress", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+#endif
rrddim_add(st, "zero_fill", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
rrddim_add(st, "reactivate", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
rrddim_add(st, "purge", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -155,8 +220,10 @@ int do_macos_mach_smi(int update_every, usec_t dt) {
rrddim_set(st, "cow", vm_statistics.cow_faults);
rrddim_set(st, "pagein", vm_statistics.pageins);
rrddim_set(st, "pageout", vm_statistics.pageouts);
+#if (defined __MAC_OS_X_VERSION_MIN_REQUIRED && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090)
rrddim_set(st, "compress", vm_statistics.compressions);
rrddim_set(st, "decompress", vm_statistics.decompressions);
+#endif
rrddim_set(st, "zero_fill", vm_statistics.zero_fill_count);
rrddim_set(st, "reactivate", vm_statistics.reactivations);
rrddim_set(st, "purge", vm_statistics.purges);
diff --git a/src/macos_sysctl.c b/src/macos_sysctl.c
index 843aceae..cb6fa8af 100644
--- a/src/macos_sysctl.c
+++ b/src/macos_sysctl.c
@@ -1,4 +1,5 @@
#include "common.h"
+#include <Availability.h>
#include <sys/sysctl.h>
// NEEDED BY: do_bandwidth
#include <net/route.h>
@@ -112,9 +113,21 @@ int do_macos_sysctl(int update_every, usec_t dt) {
/*
* Dirty workaround for /usr/include/netinet6/ip6_var.h absence.
* Struct ip6stat was copied from bsd/netinet6/ip6_var.h from xnu sources.
+ * Do the same for previously missing scope6_var.h on OS X < 10.11.
*/
#define IP6S_SRCRULE_COUNT 16
+
+#if (defined __MAC_OS_X_VERSION_MIN_REQUIRED && __MAC_OS_X_VERSION_MIN_REQUIRED < 101100)
+#ifndef _NETINET6_SCOPE6_VAR_H_
+#define _NETINET6_SCOPE6_VAR_H_
+#include <sys/appleapiopts.h>
+
+#define SCOPE6_ID_MAX 16
+#endif
+#else
#include <netinet6/scope6_var.h>
+#endif
+
struct ip6stat {
u_quad_t ip6s_total; /* total packets received */
u_quad_t ip6s_tooshort; /* packet too short */
@@ -217,9 +230,20 @@ int do_macos_sysctl(int update_every, usec_t dt) {
st = rrdset_find_bytype_localhost("system", "load");
if (unlikely(!st)) {
- st = rrdset_create_localhost("system", "load", NULL, "load", NULL, "System Load Average", "load"
- , 100, (update_every < MIN_LOADAVG_UPDATE_EVERY)
- ? MIN_LOADAVG_UPDATE_EVERY : update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "system"
+ , "load"
+ , NULL
+ , "load"
+ , NULL
+ , "System Load Average"
+ , "load"
+ , "macos"
+ , "sysctl"
+ , 100
+ , (update_every < MIN_LOADAVG_UPDATE_EVERY) ? MIN_LOADAVG_UPDATE_EVERY : update_every
+ , RRDSET_TYPE_LINE
+ );
rrddim_add(st, "load1", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
rrddim_add(st, "load5", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
rrddim_add(st, "load15", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
@@ -246,8 +270,20 @@ int do_macos_sysctl(int update_every, usec_t dt) {
} else {
st = rrdset_find_localhost("system.swap");
if (unlikely(!st)) {
- st = rrdset_create_localhost("system", "swap", NULL, "swap", NULL, "System Swap", "MB", 201
- , update_every, RRDSET_TYPE_STACKED);
+ st = rrdset_create_localhost(
+ "system"
+ , "swap"
+ , NULL
+ , "swap"
+ , NULL
+ , "System Swap"
+ , "MB"
+ , "macos"
+ , "sysctl"
+ , 201
+ , update_every
+ , RRDSET_TYPE_STACKED
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
rrddim_add(st, "free", NULL, 1, 1048576, RRD_ALGORITHM_ABSOLUTE);
@@ -296,8 +332,20 @@ int do_macos_sysctl(int update_every, usec_t dt) {
}
st = rrdset_find_localhost("system.ipv4");
if (unlikely(!st)) {
- st = rrdset_create_localhost("system", "ipv4", NULL, "network", NULL, "IPv4 Bandwidth", "kilobits/s"
- , 500, update_every, RRDSET_TYPE_AREA);
+ st = rrdset_create_localhost(
+ "system"
+ , "ipv4"
+ , NULL
+ , "network"
+ , NULL
+ , "IPv4 Bandwidth"
+ , "kilobits/s"
+ , "macos"
+ , "sysctl"
+ , 500
+ , update_every
+ , RRDSET_TYPE_AREA
+ );
rrddim_add(st, "InOctets", "received", 8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
rrddim_add(st, "OutOctets", "sent", -8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
@@ -334,8 +382,20 @@ int do_macos_sysctl(int update_every, usec_t dt) {
if (likely(do_tcp_packets)) {
st = rrdset_find_localhost("ipv4.tcppackets");
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv4", "tcppackets", NULL, "tcp", NULL, "IPv4 TCP Packets"
- , "packets/s", 2600, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "ipv4"
+ , "tcppackets"
+ , NULL
+ , "tcp"
+ , NULL
+ , "IPv4 TCP Packets"
+ , "packets/s"
+ , "macos"
+ , "sysctl"
+ , 2600
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrddim_add(st, "InSegs", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
rrddim_add(st, "OutSegs", "sent", -1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -352,8 +412,20 @@ int do_macos_sysctl(int update_every, usec_t dt) {
if (likely(do_tcp_errors)) {
st = rrdset_find_localhost("ipv4.tcperrors");
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv4", "tcperrors", NULL, "tcp", NULL, "IPv4 TCP Errors", "packets/s"
- , 2700, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "ipv4"
+ , "tcperrors"
+ , NULL
+ , "tcp"
+ , NULL
+ , "IPv4 TCP Errors"
+ , "packets/s"
+ , "macos"
+ , "sysctl"
+ , 2700
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
rrddim_add(st, "InErrs", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -373,8 +445,20 @@ int do_macos_sysctl(int update_every, usec_t dt) {
if (likely(do_tcp_handshake)) {
st = rrdset_find_localhost("ipv4.tcphandshake");
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv4", "tcphandshake", NULL, "tcp", NULL, "IPv4 TCP Handshake Issues"
- , "events/s", 2900, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "ipv4"
+ , "tcphandshake"
+ , NULL
+ , "tcp"
+ , NULL
+ , "IPv4 TCP Handshake Issues"
+ , "events/s"
+ , "macos"
+ , "sysctl"
+ , 2900
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
rrddim_add(st, "EstabResets", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -397,8 +481,20 @@ int do_macos_sysctl(int update_every, usec_t dt) {
do_tcpext_connaborts = CONFIG_BOOLEAN_YES;
st = rrdset_find_localhost("ipv4.tcpconnaborts");
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv4", "tcpconnaborts", NULL, "tcp", NULL, "TCP Connection Aborts"
- , "connections/s", 3010, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "ipv4"
+ , "tcpconnaborts"
+ , NULL
+ , "tcp"
+ , NULL
+ , "TCP Connection Aborts"
+ , "connections/s"
+ , "macos"
+ , "sysctl"
+ , 3010
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrddim_add(st, "TCPAbortOnData", "baddata", 1, 1, RRD_ALGORITHM_INCREMENTAL);
rrddim_add(st, "TCPAbortOnClose", "userclosed", 1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -420,8 +516,20 @@ int do_macos_sysctl(int update_every, usec_t dt) {
do_tcpext_ofo = CONFIG_BOOLEAN_YES;
st = rrdset_find_localhost("ipv4.tcpofo");
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv4", "tcpofo", NULL, "tcp", NULL, "TCP Out-Of-Order Queue"
- , "packets/s", 3050, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "ipv4"
+ , "tcpofo"
+ , NULL
+ , "tcp"
+ , NULL
+ , "TCP Out-Of-Order Queue"
+ , "packets/s"
+ , "macos"
+ , "sysctl"
+ , 3050
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrddim_add(st, "TCPOFOQueue", "inqueue", 1, 1, RRD_ALGORITHM_INCREMENTAL);
}
@@ -438,8 +546,20 @@ int do_macos_sysctl(int update_every, usec_t dt) {
st = rrdset_find_localhost("ipv4.tcpsyncookies");
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv4", "tcpsyncookies", NULL, "tcp", NULL, "TCP SYN Cookies"
- , "packets/s", 3100, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "ipv4"
+ , "tcpsyncookies"
+ , NULL
+ , "tcp"
+ , NULL
+ , "TCP SYN Cookies"
+ , "packets/s"
+ , "macos"
+ , "sysctl"
+ , 3100
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrddim_add(st, "SyncookiesRecv", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
rrddim_add(st, "SyncookiesSent", "sent", -1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -455,12 +575,26 @@ int do_macos_sysctl(int update_every, usec_t dt) {
// --------------------------------------------------------------------
+
+#if (defined __MAC_OS_X_VERSION_MIN_REQUIRED && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101100)
if (do_ecn == CONFIG_BOOLEAN_YES || (do_ecn == CONFIG_BOOLEAN_AUTO && (tcpstat.tcps_ecn_recv_ce || tcpstat.tcps_ecn_not_supported))) {
do_ecn = CONFIG_BOOLEAN_YES;
st = rrdset_find_localhost("ipv4.ecnpkts");
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv4", "ecnpkts", NULL, "ecn", NULL, "IPv4 ECN Statistics"
- , "packets/s", 8700, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "ipv4"
+ , "ecnpkts"
+ , NULL
+ , "ecn"
+ , NULL
+ , "IPv4 ECN Statistics"
+ , "packets/s"
+ , "macos"
+ , "sysctl"
+ , 8700
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
rrddim_add(st, "InCEPkts", "CEP", 1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -472,6 +606,7 @@ int do_macos_sysctl(int update_every, usec_t dt) {
rrddim_set(st, "InNoECTPkts", tcpstat.tcps_ecn_not_supported);
rrdset_done(st);
}
+#endif
}
}
@@ -489,8 +624,20 @@ int do_macos_sysctl(int update_every, usec_t dt) {
if (likely(do_udp_packets)) {
st = rrdset_find_localhost("ipv4.udppackets");
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv4", "udppackets", NULL, "udp", NULL, "IPv4 UDP Packets"
- , "packets/s", 2601, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "ipv4"
+ , "udppackets"
+ , NULL
+ , "udp"
+ , NULL
+ , "IPv4 UDP Packets"
+ , "packets/s"
+ , "macos"
+ , "sysctl"
+ , 2601
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrddim_add(st, "InDatagrams", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
rrddim_add(st, "OutDatagrams", "sent", -1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -507,23 +654,41 @@ int do_macos_sysctl(int update_every, usec_t dt) {
if (likely(do_udp_errors)) {
st = rrdset_find_localhost("ipv4.udperrors");
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv4", "udperrors", NULL, "udp", NULL, "IPv4 UDP Errors", "events/s"
- , 2701, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "ipv4"
+ , "udperrors"
+ , NULL
+ , "udp"
+ , NULL
+ , "IPv4 UDP Errors"
+ , "events/s"
+ , "macos"
+ , "sysctl"
+ , 2701
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
rrddim_add(st, "RcvbufErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
rrddim_add(st, "InErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
rrddim_add(st, "NoPorts", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
rrddim_add(st, "InCsumErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+#if (defined __MAC_OS_X_VERSION_MIN_REQUIRED && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090)
rrddim_add(st, "IgnoredMulti", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+#endif
} else
rrdset_next(st);
rrddim_set(st, "InErrors", udpstat.udps_hdrops + udpstat.udps_badlen);
rrddim_set(st, "NoPorts", udpstat.udps_noport);
rrddim_set(st, "RcvbufErrors", udpstat.udps_fullsock);
+#if (defined __MAC_OS_X_VERSION_MIN_REQUIRED && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090)
rrddim_set(st, "InCsumErrors", udpstat.udps_badsum + udpstat.udps_nosum);
rrddim_set(st, "IgnoredMulti", udpstat.udps_filtermcast);
+#else
+ rrddim_set(st, "InCsumErrors", udpstat.udps_badsum);
+#endif
rrdset_done(st);
}
}
@@ -550,8 +715,20 @@ int do_macos_sysctl(int update_every, usec_t dt) {
if (likely(do_icmp_packets)) {
st = rrdset_find_localhost("ipv4.icmp");
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv4", "icmp", NULL, "icmp", NULL, "IPv4 ICMP Packets", "packets/s"
- , 2602, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "ipv4"
+ , "icmp"
+ , NULL
+ , "icmp"
+ , NULL
+ , "IPv4 ICMP Packets"
+ , "packets/s"
+ , "macos"
+ , "sysctl"
+ , 2602
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrddim_add(st, "InMsgs", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
rrddim_add(st, "OutMsgs", "sent", -1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -567,8 +744,20 @@ int do_macos_sysctl(int update_every, usec_t dt) {
st = rrdset_find_localhost("ipv4.icmp_errors");
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv4", "icmp_errors", NULL, "icmp", NULL, "IPv4 ICMP Errors"
- , "packets/s", 2603, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "ipv4"
+ , "icmp_errors"
+ , NULL
+ , "icmp"
+ , NULL
+ , "IPv4 ICMP Errors"
+ , "packets/s"
+ , "macos"
+ , "sysctl"
+ , 2603
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrddim_add(st, "InErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
rrddim_add(st, "OutErrors", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -588,8 +777,20 @@ int do_macos_sysctl(int update_every, usec_t dt) {
if (likely(do_icmpmsg)) {
st = rrdset_find_localhost("ipv4.icmpmsg");
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv4", "icmpmsg", NULL, "icmp", NULL, "IPv4 ICMP Messages"
- , "packets/s", 2604, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "ipv4"
+ , "icmpmsg"
+ , NULL
+ , "icmp"
+ , NULL
+ , "IPv4 ICMP Messages"
+ , "packets/s"
+ , "macos"
+ , "sysctl"
+ , 2604
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrddim_add(st, "InEchoReps", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
rrddim_add(st, "OutEchoReps", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -625,8 +826,20 @@ int do_macos_sysctl(int update_every, usec_t dt) {
if (likely(do_ip_packets)) {
st = rrdset_find_localhost("ipv4.packets");
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv4", "packets", NULL, "packets", NULL, "IPv4 Packets", "packets/s"
- , 3000, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "ipv4"
+ , "packets"
+ , NULL
+ , "packets"
+ , NULL
+ , "IPv4 Packets"
+ , "packets/s"
+ , "macos"
+ , "sysctl"
+ , 3000
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrddim_add(st, "InReceives", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
rrddim_add(st, "OutRequests", "sent", -1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -647,8 +860,20 @@ int do_macos_sysctl(int update_every, usec_t dt) {
if (likely(do_ip_fragsout)) {
st = rrdset_find_localhost("ipv4.fragsout");
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv4", "fragsout", NULL, "fragments", NULL, "IPv4 Fragments Sent"
- , "packets/s", 3010, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "ipv4"
+ , "fragsout"
+ , NULL
+ , "fragments"
+ , NULL
+ , "IPv4 Fragments Sent"
+ , "packets/s"
+ , "macos"
+ , "sysctl"
+ , 3010
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
rrddim_add(st, "FragOKs", "ok", 1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -668,8 +893,20 @@ int do_macos_sysctl(int update_every, usec_t dt) {
if (likely(do_ip_fragsin)) {
st = rrdset_find_localhost("ipv4.fragsin");
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv4", "fragsin", NULL, "fragments", NULL, "IPv4 Fragments Reassembly"
- , "packets/s", 3011, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "ipv4"
+ , "fragsin"
+ , NULL
+ , "fragments"
+ , NULL
+ , "IPv4 Fragments Reassembly"
+ , "packets/s"
+ , "macos"
+ , "sysctl"
+ , 3011
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
rrddim_add(st, "ReasmOKs", "ok", 1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -689,8 +926,20 @@ int do_macos_sysctl(int update_every, usec_t dt) {
if (likely(do_ip_errors)) {
st = rrdset_find_localhost("ipv4.errors");
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv4", "errors", NULL, "errors", NULL, "IPv4 Errors", "packets/s"
- , 3002, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "ipv4"
+ , "errors"
+ , NULL
+ , "errors"
+ , NULL
+ , "IPv4 Errors"
+ , "packets/s"
+ , "macos"
+ , "sysctl"
+ , 3002
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
rrddim_add(st, "InDiscards", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -734,8 +983,20 @@ int do_macos_sysctl(int update_every, usec_t dt) {
do_ip6_packets = CONFIG_BOOLEAN_YES;
st = rrdset_find_localhost("ipv6.packets");
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv6", "packets", NULL, "packets", NULL, "IPv6 Packets", "packets/s"
- , 3000, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "ipv6"
+ , "packets"
+ , NULL
+ , "packets"
+ , NULL
+ , "IPv6 Packets"
+ , "packets/s"
+ , "macos"
+ , "sysctl"
+ , 3000
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrddim_add(st, "received", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
rrddim_add(st, "sent", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -759,8 +1020,20 @@ int do_macos_sysctl(int update_every, usec_t dt) {
do_ip6_fragsout = CONFIG_BOOLEAN_YES;
st = rrdset_find_localhost("ipv6.fragsout");
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv6", "fragsout", NULL, "fragments", NULL, "IPv6 Fragments Sent"
- , "packets/s", 3010, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "ipv6"
+ , "fragsout"
+ , NULL
+ , "fragments"
+ , NULL
+ , "IPv6 Fragments Sent"
+ , "packets/s"
+ , "macos"
+ , "sysctl"
+ , 3010
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
rrddim_add(st, "ok", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -783,8 +1056,20 @@ int do_macos_sysctl(int update_every, usec_t dt) {
do_ip6_fragsin = CONFIG_BOOLEAN_YES;
st = rrdset_find_localhost("ipv6.fragsin");
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv6", "fragsin", NULL, "fragments", NULL, "IPv6 Fragments Reassembly"
- , "packets/s", 3011, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "ipv6"
+ , "fragsin"
+ , NULL
+ , "fragments"
+ , NULL
+ , "IPv6 Fragments Reassembly"
+ , "packets/s"
+ , "macos"
+ , "sysctl"
+ , 3011
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
rrddim_add(st, "ok", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -816,8 +1101,20 @@ int do_macos_sysctl(int update_every, usec_t dt) {
do_ip6_errors = CONFIG_BOOLEAN_YES;
st = rrdset_find_localhost("ipv6.errors");
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv6", "errors", NULL, "errors", NULL, "IPv6 Errors", "packets/s"
- , 3002, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "ipv6"
+ , "errors"
+ , NULL
+ , "errors"
+ , NULL
+ , "IPv6 Errors"
+ , "packets/s"
+ , "macos"
+ , "sysctl"
+ , 3002
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
rrddim_add(st, "InDiscards", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -863,8 +1160,20 @@ int do_macos_sysctl(int update_every, usec_t dt) {
do_icmp6 = CONFIG_BOOLEAN_YES;
st = rrdset_find_localhost("ipv6.icmp");
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv6", "icmp", NULL, "icmp", NULL, "IPv6 ICMP Messages", "messages/s"
- , 10000, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "ipv6"
+ , "icmp"
+ , NULL
+ , "icmp"
+ , NULL
+ , "IPv6 ICMP Messages"
+ , "messages/s"
+ , "macos"
+ , "sysctl"
+ , 10000
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrddim_add(st, "received", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
rrddim_add(st, "sent", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -882,8 +1191,20 @@ int do_macos_sysctl(int update_every, usec_t dt) {
do_icmp6_redir = CONFIG_BOOLEAN_YES;
st = rrdset_find_localhost("ipv6.icmpredir");
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv6", "icmpredir", NULL, "icmp", NULL, "IPv6 ICMP Redirects"
- , "redirects/s", 10050, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "ipv6"
+ , "icmpredir"
+ , NULL
+ , "icmp"
+ , NULL
+ , "IPv6 ICMP Redirects"
+ , "redirects/s"
+ , "macos"
+ , "sysctl"
+ , 10050
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrddim_add(st, "received", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
rrddim_add(st, "sent", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -912,8 +1233,20 @@ int do_macos_sysctl(int update_every, usec_t dt) {
do_icmp6_errors = CONFIG_BOOLEAN_YES;
st = rrdset_find_localhost("ipv6.icmperrors");
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv6", "icmperrors", NULL, "icmp", NULL, "IPv6 ICMP Errors"
- , "errors/s", 10100, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "ipv6"
+ , "icmperrors"
+ , NULL
+ , "icmp"
+ , NULL
+ , "IPv6 ICMP Errors"
+ , "errors/s"
+ , "macos"
+ , "sysctl"
+ , 10100
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrddim_add(st, "InErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
rrddim_add(st, "OutErrors", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -952,8 +1285,20 @@ int do_macos_sysctl(int update_every, usec_t dt) {
do_icmp6_echos = CONFIG_BOOLEAN_YES;
st = rrdset_find_localhost("ipv6.icmpechos");
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv6", "icmpechos", NULL, "icmp", NULL, "IPv6 ICMP Echo", "messages/s"
- , 10200, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "ipv6"
+ , "icmpechos"
+ , NULL
+ , "icmp"
+ , NULL
+ , "IPv6 ICMP Echo"
+ , "messages/s"
+ , "macos"
+ , "sysctl"
+ , 10200
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrddim_add(st, "InEchos", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
rrddim_add(st, "OutEchos", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -979,8 +1324,20 @@ int do_macos_sysctl(int update_every, usec_t dt) {
do_icmp6_router = CONFIG_BOOLEAN_YES;
st = rrdset_find_localhost("ipv6.icmprouter");
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv6", "icmprouter", NULL, "icmp", NULL, "IPv6 Router Messages"
- , "messages/s", 10400, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "ipv6"
+ , "icmprouter"
+ , NULL
+ , "icmp"
+ , NULL
+ , "IPv6 Router Messages"
+ , "messages/s"
+ , "macos"
+ , "sysctl"
+ , 10400
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrddim_add(st, "InSolicits", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
rrddim_add(st, "OutSolicits", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -1006,8 +1363,20 @@ int do_macos_sysctl(int update_every, usec_t dt) {
do_icmp6_neighbor = CONFIG_BOOLEAN_YES;
st = rrdset_find_localhost("ipv6.icmpneighbor");
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv6", "icmpneighbor", NULL, "icmp", NULL, "IPv6 Neighbor Messages"
- , "messages/s", 10500, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "ipv6"
+ , "icmpneighbor"
+ , NULL
+ , "icmp"
+ , NULL
+ , "IPv6 Neighbor Messages"
+ , "messages/s"
+ , "macos"
+ , "sysctl"
+ , 10500
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrddim_add(st, "InSolicits", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
rrddim_add(st, "OutSolicits", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -1039,8 +1408,20 @@ int do_macos_sysctl(int update_every, usec_t dt) {
do_icmp6_types = CONFIG_BOOLEAN_YES;
st = rrdset_find_localhost("ipv6.icmptypes");
if (unlikely(!st)) {
- st = rrdset_create_localhost("ipv6", "icmptypes", NULL, "icmp", NULL, "IPv6 ICMP Types"
- , "messages/s", 10700, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "ipv6"
+ , "icmptypes"
+ , NULL
+ , "icmp"
+ , NULL
+ , "IPv6 ICMP Types"
+ , "messages/s"
+ , "macos"
+ , "sysctl"
+ , 10700
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrddim_add(st, "InType1", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
rrddim_add(st, "InType128", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -1081,8 +1462,20 @@ int do_macos_sysctl(int update_every, usec_t dt) {
st = rrdset_find_localhost("system.uptime");
if(unlikely(!st)) {
- st = rrdset_create_localhost("system", "uptime", NULL, "uptime", NULL, "System Uptime", "seconds", 1000
- , update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "system"
+ , "uptime"
+ , NULL
+ , "uptime"
+ , NULL
+ , "System Uptime"
+ , "seconds"
+ , "macos"
+ , "sysctl"
+ , 1000
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrddim_add(st, "uptime", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
}
else rrdset_next(st);
diff --git a/src/main.c b/src/main.c
index 89ca828a..b14ebc0c 100644
--- a/src/main.c
+++ b/src/main.c
@@ -32,24 +32,34 @@ void netdata_cleanup_and_exit(int ret) {
}
struct netdata_static_thread static_threads[] = {
+
#ifdef INTERNAL_PLUGIN_NFACCT
-// nfacct requires root access
+ // nfacct requires root access
// so, we build it as an external plugin with setuid to root
{"nfacct", CONFIG_SECTION_PLUGINS, "nfacct", 1, NULL, NULL, nfacct_main},
#endif
- {"tc", CONFIG_SECTION_PLUGINS, "tc", 1, NULL, NULL, tc_main},
- {"idlejitter", CONFIG_SECTION_PLUGINS, "idlejitter", 1, NULL, NULL, cpuidlejitter_main},
+#ifdef NETDATA_INTERNAL_CHECKS
+ // debugging plugin
+ {"check", CONFIG_SECTION_PLUGINS, "checks", 0, NULL, NULL, checks_main},
+#endif
+
#if defined(__FreeBSD__)
+ // FreeBSD internal plugins
{"freebsd", CONFIG_SECTION_PLUGINS, "freebsd", 1, NULL, NULL, freebsd_main},
#elif defined(__APPLE__)
+ // macOS internal plugins
{"macos", CONFIG_SECTION_PLUGINS, "macos", 1, NULL, NULL, macos_main},
#else
+ // linux internal plugins
{"proc", CONFIG_SECTION_PLUGINS, "proc", 1, NULL, NULL, proc_main},
{"diskspace", CONFIG_SECTION_PLUGINS, "diskspace", 1, NULL, NULL, proc_diskspace_main},
{"cgroups", CONFIG_SECTION_PLUGINS, "cgroups", 1, NULL, NULL, cgroups_main},
+ {"tc", CONFIG_SECTION_PLUGINS, "tc", 1, NULL, NULL, tc_main},
#endif /* __FreeBSD__, __APPLE__*/
- {"check", CONFIG_SECTION_PLUGINS, "checks", 0, NULL, NULL, checks_main},
+
+ // common plugins for all systems
+ {"idlejitter", CONFIG_SECTION_PLUGINS, "idlejitter", 1, NULL, NULL, cpuidlejitter_main},
{"backends", NULL, NULL, 1, NULL, NULL, backends_main},
{"health", NULL, NULL, 1, NULL, NULL, health_main},
{"plugins.d", NULL, NULL, 1, NULL, NULL, pluginsd_main},
@@ -57,6 +67,7 @@ struct netdata_static_thread static_threads[] = {
{"web-single-threaded", NULL, NULL, 0, NULL, NULL, socket_listen_main_single_threaded},
{"push-metrics", NULL, NULL, 0, NULL, NULL, rrdpush_sender_thread},
{"statsd", NULL, NULL, 1, NULL, NULL, statsd_main},
+
{NULL, NULL, NULL, 0, NULL, NULL, NULL}
};
@@ -83,6 +94,13 @@ void web_server_config_options(void) {
web_x_frame_options = config_get(CONFIG_SECTION_WEB, "x-frame-options response header", "");
if(!*web_x_frame_options) web_x_frame_options = NULL;
+ web_allow_connections_from = simple_pattern_create(config_get(CONFIG_SECTION_WEB, "allow connections from", "localhost *"), SIMPLE_PATTERN_EXACT);
+ web_allow_dashboard_from = simple_pattern_create(config_get(CONFIG_SECTION_WEB, "allow dashboard from", "localhost *"), SIMPLE_PATTERN_EXACT);
+ web_allow_badges_from = simple_pattern_create(config_get(CONFIG_SECTION_WEB, "allow badges from", "*"), SIMPLE_PATTERN_EXACT);
+ web_allow_registry_from = simple_pattern_create(config_get(CONFIG_SECTION_REGISTRY, "allow from", "*"), SIMPLE_PATTERN_EXACT);
+ web_allow_streaming_from = simple_pattern_create(config_get(CONFIG_SECTION_WEB, "allow streaming from", "*"), SIMPLE_PATTERN_EXACT);
+ web_allow_netdataconf_from = simple_pattern_create(config_get(CONFIG_SECTION_WEB, "allow netdata.conf from", "localhost fd* 10.* 192.168.* 172.16.* 172.17.* 172.18.* 172.19.* 172.20.* 172.21.* 172.22.* 172.23.* 172.24.* 172.25.* 172.26.* 172.27.* 172.28.* 172.29.* 172.30.* 172.31.*"), SIMPLE_PATTERN_EXACT);
+
#ifdef NETDATA_WITH_ZLIB
web_enable_gzip = config_get_boolean(CONFIG_SECTION_WEB, "enable gzip compression", web_enable_gzip);
@@ -195,23 +213,8 @@ void kill_childs()
tc_child_pid = 0;
}
- struct plugind *cd;
- for(cd = pluginsd_root ; cd ; cd = cd->next) {
- if(cd->enabled && !cd->obsolete) {
- info("Stopping %s plugin thread", cd->id);
- pthread_cancel(cd->thread);
-
- if(cd->pid) {
- info("killing %s plugin child process pid %d", cd->id, cd->pid);
- if(killpid(cd->pid, SIGTERM) != -1)
- waitid(P_PID, (id_t) cd->pid, &info, WEXITED);
-
- cd->pid = 0;
- }
-
- cd->obsolete = 1;
- }
- }
+ // stop all running plugins
+ pluginsd_stop_all_external_plugins();
// if, for any reason there is any child exited
// catch it here
@@ -221,7 +224,7 @@ void kill_childs()
info("All threads/childs stopped.");
}
-struct option_def options[] = {
+struct option_def option_definitions[] = {
// opt description arg name default value
{ 'c', "Configuration file to load.", "filename", CONFIG_DIR "/" CONFIG_FILENAME},
{ 'D', "Do not fork. Run in the foreground.", NULL, "run in the background"},
@@ -237,21 +240,21 @@ struct option_def options[] = {
{ 'W', "See Advanced options below.", "options", NULL},
};
-void help(int exitcode) {
+int help(int exitcode) {
FILE *stream;
if(exitcode == 0)
stream = stdout;
else
stream = stderr;
- int num_opts = sizeof(options) / sizeof(struct option_def);
+ int num_opts = sizeof(option_definitions) / sizeof(struct option_def);
int i;
int max_len_arg = 0;
// Compute maximum argument length
for( i = 0; i < num_opts; i++ ) {
- if(options[i].arg_name) {
- int len_arg = (int)strlen(options[i].arg_name);
+ if(option_definitions[i].arg_name) {
+ int len_arg = (int)strlen(option_definitions[i].arg_name);
if(len_arg > max_len_arg) max_len_arg = len_arg;
}
}
@@ -289,9 +292,9 @@ void help(int exitcode) {
// Output options description.
for( i = 0; i < num_opts; i++ ) {
- fprintf(stream, " -%c %-*s %s", options[i].val, max_len_arg, options[i].arg_name ? options[i].arg_name : "", options[i].description);
- if(options[i].default_value) {
- fprintf(stream, "\n %c %-*s Default: %s\n", ' ', max_len_arg, "", options[i].default_value);
+ fprintf(stream, " -%c %-*s %s", option_definitions[i].val, max_len_arg, option_definitions[i].arg_name ? option_definitions[i].arg_name : "", option_definitions[i].description);
+ if(option_definitions[i].default_value) {
+ fprintf(stream, "\n %c %-*s Default: %s\n", ' ', max_len_arg, "", option_definitions[i].default_value);
} else {
fprintf(stream, "\n");
}
@@ -316,7 +319,7 @@ void help(int exitcode) {
);
fflush(stream);
- exit(exitcode);
+ return exitcode;
}
// TODO: Remove this function with the nix major release.
@@ -454,17 +457,23 @@ static void get_netdata_configured_variables() {
}
// ------------------------------------------------------------------------
- // let the plugins know the min update_every
-
// get system paths
+
netdata_configured_config_dir = config_get(CONFIG_SECTION_GLOBAL, "config directory", CONFIG_DIR);
netdata_configured_log_dir = config_get(CONFIG_SECTION_GLOBAL, "log directory", LOG_DIR);
- netdata_configured_plugins_dir = config_get(CONFIG_SECTION_GLOBAL, "plugins directory", PLUGINS_DIR);
netdata_configured_web_dir = config_get(CONFIG_SECTION_GLOBAL, "web files directory", WEB_DIR);
netdata_configured_cache_dir = config_get(CONFIG_SECTION_GLOBAL, "cache directory", CACHE_DIR);
netdata_configured_varlib_dir = config_get(CONFIG_SECTION_GLOBAL, "lib directory", VARLIB_DIR);
netdata_configured_home_dir = config_get(CONFIG_SECTION_GLOBAL, "home directory", CACHE_DIR);
+ {
+ char plugins_dirs[(FILENAME_MAX * 2) + 1];
+ snprintfz(plugins_dirs, FILENAME_MAX * 2, "\"%s\" \"%s/custom-plugins.d\"", PLUGINS_DIR, CONFIG_DIR);
+ netdata_configured_plugins_dir_base = strdupz(config_get(CONFIG_SECTION_GLOBAL, "plugins directory", plugins_dirs));
+ quoted_strings_splitter(netdata_configured_plugins_dir_base, plugin_directories, PLUGINSD_MAX_DIRECTORIES, config_isspace);
+ netdata_configured_plugins_dir = plugin_directories[0];
+ }
+
// ------------------------------------------------------------------------
// get default memory mode for the database
@@ -489,6 +498,95 @@ static void get_netdata_configured_variables() {
get_system_pid_max();
}
+static void get_system_timezone(void) {
+ // avoid flood calls to stat(/etc/localtime)
+ // http://stackoverflow.com/questions/4554271/how-to-avoid-excessive-stat-etc-localtime-calls-in-strftime-on-linux
+ const char *tz = getenv("TZ");
+ if(!tz || !*tz)
+ setenv("TZ", config_get(CONFIG_SECTION_GLOBAL, "TZ environment variable", ":/etc/localtime"), 0);
+
+ char buffer[FILENAME_MAX + 1] = "";
+ const char *timezone = NULL;
+ ssize_t ret;
+
+ // use the TZ variable
+ if(tz && *tz && *tz != ':') {
+ timezone = tz;
+ // info("TIMEZONE: using TZ variable '%s'", timezone);
+ }
+
+ // use the contents of /etc/timezone
+ if(!timezone && !read_file("/etc/timezone", buffer, FILENAME_MAX)) {
+ timezone = buffer;
+ // info("TIMEZONE: using the contents of /etc/timezone: '%s'", timezone);
+ }
+
+ // read the link /etc/localtime
+ if(!timezone) {
+ ret = readlink("/etc/localtime", buffer, FILENAME_MAX);
+
+ if(ret > 0) {
+ buffer[ret] = '\0';
+
+ char *cmp = "/usr/share/zoneinfo/";
+ size_t cmp_len = strlen(cmp);
+
+ char *s = strstr(buffer, cmp);
+ if (s && s[cmp_len]) {
+ timezone = &s[cmp_len];
+ // info("TIMEZONE: using the link of /etc/localtime: '%s'", timezone);
+ }
+ }
+ else
+ buffer[0] = '\0';
+ }
+
+ // find the timezone from strftime()
+ if(!timezone) {
+ time_t t;
+ struct tm *tmp, tmbuf;
+
+ t = now_realtime_sec();
+ tmp = localtime_r(&t, &tmbuf);
+
+ if (tmp != NULL) {
+ if(strftime(buffer, FILENAME_MAX, "%Z", tmp) == 0)
+ buffer[0] = '\0';
+ else {
+ buffer[FILENAME_MAX] = '\0';
+ timezone = buffer;
+ // info("TIMEZONE: using strftime(): '%s'", timezone);
+ }
+ }
+ }
+
+ if(timezone && *timezone) {
+ // make sure it does not have illegal characters
+ // info("TIMEZONE: fixing '%s'", timezone);
+
+ size_t len = strlen(timezone);
+ char tmp[len + 1];
+ char *d = tmp;
+ *d = '\0';
+
+ while(*timezone) {
+ if(isalnum(*timezone) || *timezone == '_' || *timezone == '/')
+ *d++ = *timezone++;
+ else
+ timezone++;
+ }
+ *d = '\0';
+ strncpyz(buffer, tmp, len);
+ timezone = buffer;
+ // info("TIMEZONE: fixed as '%s'", timezone);
+ }
+
+ if(!timezone || !*timezone)
+ timezone = "unknown";
+
+ netdata_configured_timezone = config_get(CONFIG_SECTION_GLOBAL, "timezone", timezone);
+}
+
void set_global_environment() {
{
char b[16];
@@ -506,11 +604,7 @@ void set_global_environment() {
setenv("HOME" , verify_required_directory(netdata_configured_home_dir), 1);
setenv("NETDATA_HOST_PREFIX", netdata_configured_host_prefix, 1);
- // avoid flood calls to stat(/etc/localtime)
- // http://stackoverflow.com/questions/4554271/how-to-avoid-excessive-stat-etc-localtime-calls-in-strftime-on-linux
- const char *tz = getenv("TZ");
- if(!tz || !*tz)
- setenv("TZ", config_get(CONFIG_SECTION_GLOBAL, "TZ environment variable", ":/etc/localtime"), 0);
+ get_system_timezone();
// set the path we need
char path[1024 + 1], *p = getenv("PATH");
@@ -571,14 +665,14 @@ int main(int argc, char **argv) {
// parse options
{
- int num_opts = sizeof(options) / sizeof(struct option_def);
+ int num_opts = sizeof(option_definitions) / sizeof(struct option_def);
char optstring[(num_opts * 2) + 1];
int string_i = 0;
for( i = 0; i < num_opts; i++ ) {
- optstring[string_i] = options[i].val;
+ optstring[string_i] = option_definitions[i].val;
string_i++;
- if(options[i].arg_name) {
+ if(option_definitions[i].arg_name) {
optstring[string_i] = ':';
string_i++;
}
@@ -593,7 +687,7 @@ int main(int argc, char **argv) {
case 'c':
if(config_load(optarg, 1) != 1) {
error("Cannot load configuration file %s.", optarg);
- exit(1);
+ return 1;
}
else {
debug(D_OPTIONS, "Configuration loaded from %s.", optarg);
@@ -604,8 +698,7 @@ int main(int argc, char **argv) {
dont_fork = 1;
break;
case 'h':
- help(0);
- break;
+ return help(0);
case 'i':
config_set(CONFIG_SECTION_WEB, "bind to", optarg);
break;
@@ -635,8 +728,8 @@ int main(int argc, char **argv) {
char* debug_flags_string = "debug_flags=";
if(strcmp(optarg, "unittest") == 0) {
- if(unit_test_buffer()) exit(1);
- if(unit_test_str2ld()) exit(1);
+ if(unit_test_buffer()) return 1;
+ if(unit_test_str2ld()) return 1;
//default_rrd_update_every = 1;
//default_rrd_memory_mode = RRD_MEMORY_MODE_RAM;
//if(!config_loaded) config_load(NULL, 0);
@@ -646,10 +739,10 @@ int main(int argc, char **argv) {
default_health_enabled = 0;
rrd_init("unittest");
default_rrdpush_enabled = 0;
- if(run_all_mockup_tests()) exit(1);
- if(unit_test_storage()) exit(1);
+ if(run_all_mockup_tests()) return 1;
+ if(unit_test_storage()) return 1;
fprintf(stderr, "\n\nALL TESTS PASSED\n\n");
- exit(0);
+ return 0;
}
else if(strcmp(optarg, "simple-pattern") == 0) {
if(optind + 2 > argc) {
@@ -673,24 +766,25 @@ int main(int argc, char **argv) {
" -W simple-pattern '!/path/*/*.ext /path/*.ext' '/path/test.ext'\n"
"\n"
);
- exit(1);
+ return 1;
}
const char *heystack = argv[optind];
const char *needle = argv[optind + 1];
+ size_t len = strlen(needle) + 1;
+ char wildcarded[len];
- SIMPLE_PATTERN *p = simple_pattern_create(heystack
- , SIMPLE_PATTERN_EXACT);
- int ret = simple_pattern_matches(p, needle);
+ SIMPLE_PATTERN *p = simple_pattern_create(heystack, SIMPLE_PATTERN_EXACT);
+ int ret = simple_pattern_matches_extract(p, needle, wildcarded, len);
simple_pattern_free(p);
if(ret) {
- fprintf(stdout, "RESULT: MATCHED - pattern '%s' matches '%s'\n", heystack, needle);
- exit(0);
+ fprintf(stdout, "RESULT: MATCHED - pattern '%s' matches '%s', wildcarded '%s'\n", heystack, needle, wildcarded);
+ return 0;
}
else {
- fprintf(stdout, "RESULT: NOT MATCHED - pattern '%s' does not match '%s'\n", heystack, needle);
- exit(1);
+ fprintf(stdout, "RESULT: NOT MATCHED - pattern '%s' does not match '%s', wildcarded '%s'\n", heystack, needle, wildcarded);
+ return 1;
}
}
else if(strncmp(optarg, stacksize_string, strlen(stacksize_string)) == 0) {
@@ -716,7 +810,7 @@ int main(int argc, char **argv) {
" parameters."
"\n"
);
- exit(1);
+ return 1;
}
const char *section = argv[optind];
const char *key = argv[optind + 1];
@@ -741,7 +835,7 @@ int main(int argc, char **argv) {
" -c netdata.conf has to be given before -W get.\n"
"\n"
);
- exit(1);
+ return 1;
}
if(!config_loaded) {
@@ -757,18 +851,18 @@ int main(int argc, char **argv) {
const char *def = argv[optind + 2];
const char *value = config_get(section, key, def);
printf("%s\n", value);
- exit(0);
+ return 0;
}
else {
fprintf(stderr, "Unknown -W parameter '%s'\n", optarg);
- help(1);
+ return help(1);
}
}
break;
+
default: /* ? */
fprintf(stderr, "Unknown parameter '%c'\n", opt);
- help(1);
- break;
+ return help(1);
}
}
}
@@ -906,6 +1000,7 @@ int main(int argc, char **argv) {
// --------------------------------------------------------------------
// create the listening sockets
+ web_client_api_v1_init();
web_server_threading_selection();
if(web_server_mode != WEB_SERVER_MODE_NONE)
@@ -997,4 +1092,8 @@ int main(int argc, char **argv) {
// Handle signals
signals_handle();
+
+ // should never reach this point
+ // but we need it for rpmlint #2752
+ return 1;
}
diff --git a/src/main.h b/src/main.h
index 38df0fea..09567bc7 100644
--- a/src/main.h
+++ b/src/main.h
@@ -16,12 +16,6 @@ struct option_def {
const char *default_value;
};
-/**
- * List of command line options.
- * This can be used to compute manpage, help messages, ect.
- */
-extern struct option_def options[];
-
struct netdata_static_thread {
char *name;
diff --git a/src/plugin_checks.c b/src/plugin_checks.c
index 3a0a83bd..9c1e42cc 100644
--- a/src/plugin_checks.c
+++ b/src/plugin_checks.c
@@ -1,5 +1,7 @@
#include "common.h"
+#ifdef NETDATA_INTERNAL_CHECKS
+
void *checks_main(void *ptr) {
struct netdata_static_thread *static_thread = (struct netdata_static_thread *)ptr;
@@ -16,18 +18,55 @@ void *checks_main(void *ptr) {
RRDSET *check1, *check2, *check3, *apps_cpu = NULL;
- check1 = rrdset_create_localhost("netdata", "check1", NULL, "netdata", NULL, "Caller gives microseconds"
- , "a million !", 99999, localhost->rrd_update_every, RRDSET_TYPE_LINE);
+ check1 = rrdset_create_localhost(
+ "netdata"
+ , "check1"
+ , NULL
+ , "netdata"
+ , NULL
+ , "Caller gives microseconds"
+ , "a million !"
+ , "netdata"
+ , "checks"
+ , 99999
+ , localhost->rrd_update_every
+ , RRDSET_TYPE_LINE
+ );
+
rrddim_add(check1, "absolute", NULL, -1, 1, RRD_ALGORITHM_ABSOLUTE);
rrddim_add(check1, "incremental", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- check2 = rrdset_create_localhost("netdata", "check2", NULL, "netdata", NULL, "Netdata calcs microseconds"
- , "a million !", 99999, localhost->rrd_update_every, RRDSET_TYPE_LINE);
+ check2 = rrdset_create_localhost(
+ "netdata"
+ , "check2"
+ , NULL
+ , "netdata"
+ , NULL
+ , "Netdata calcs microseconds"
+ , "a million !"
+ , "netdata"
+ , "checks"
+ , 99999
+ , localhost->rrd_update_every
+ , RRDSET_TYPE_LINE
+ );
rrddim_add(check2, "absolute", NULL, -1, 1, RRD_ALGORITHM_ABSOLUTE);
rrddim_add(check2, "incremental", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- check3 = rrdset_create_localhost("netdata", "checkdt", NULL, "netdata", NULL, "Clock difference"
- , "microseconds diff", 99999, localhost->rrd_update_every, RRDSET_TYPE_LINE);
+ check3 = rrdset_create_localhost(
+ "netdata"
+ , "checkdt"
+ , NULL
+ , "netdata"
+ , NULL
+ , "Clock difference"
+ , "microseconds diff"
+ , "netdata"
+ , "checks"
+ , 99999
+ , localhost->rrd_update_every
+ , RRDSET_TYPE_LINE
+ );
rrddim_add(check3, "caller", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
rrddim_add(check3, "netdata", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
rrddim_add(check3, "apps.plugin", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
@@ -87,3 +126,4 @@ void *checks_main(void *ptr) {
return NULL;
}
+#endif // NETDATA_INTERNAL_CHECKS
diff --git a/src/plugin_checks.h b/src/plugin_checks.h
index c27685b8..05a40bea 100644
--- a/src/plugin_checks.h
+++ b/src/plugin_checks.h
@@ -1,6 +1,8 @@
#ifndef NETDATA_PLUGIN_CHECKS_H
#define NETDATA_PLUGIN_CHECKS_H 1
+#ifdef NETDATA_INTERNAL_CHECKS
void *checks_main(void *ptr);
+#endif // NETDATA_INTERNAL_CHECKS
#endif /* NETDATA_PLUGIN_PROC_H */
diff --git a/src/plugin_freebsd.c b/src/plugin_freebsd.c
index c09b28a5..a7825d85 100644
--- a/src/plugin_freebsd.c
+++ b/src/plugin_freebsd.c
@@ -37,6 +37,7 @@ static struct freebsd_module {
// CPU metrics
{ .name = "kern.cp_times", .dim = "cp_times", .enabled = 1, .func = do_kern_cp_times },
{ .name = "dev.cpu.temperature", .dim = "cpu_temperature", .enabled = 1, .func = do_dev_cpu_temperature },
+ { .name = "dev.cpu.0.freq", .dim = "cpu_frequency", .enabled = 1, .func = do_dev_cpu_0_freq },
// disk metrics
{ .name = "kern.devstat", .dim = "kern_devstat", .enabled = 1, .func = do_kern_devstat },
@@ -56,6 +57,7 @@ static struct freebsd_module {
// ZFS metrics
{ .name = "kstat.zfs.misc.arcstats", .dim = "arcstats", .enabled = 1, .func = do_kstat_zfs_misc_arcstats },
+ { .name = "kstat.zfs.misc.zio_trim", .dim = "trim", .enabled = 1, .func = do_kstat_zfs_misc_zio_trim },
// ipfw metrics
{ .name = "ipfw", .dim = "ipfw", .enabled = 1, .func = do_ipfw },
@@ -127,9 +129,20 @@ void *freebsd_main(void *ptr) {
st = rrdset_find_bytype_localhost("netdata", "plugin_freebsd_modules");
if(!st) {
- st = rrdset_create_localhost("netdata", "plugin_freebsd_modules", NULL, "freebsd", NULL
- , "NetData FreeBSD Plugin Modules Durations", "milliseconds/run", 132001
- , localhost->rrd_update_every, RRDSET_TYPE_STACKED);
+ st = rrdset_create_localhost(
+ "netdata"
+ , "plugin_freebsd_modules"
+ , NULL
+ , "freebsd"
+ , NULL
+ , "NetData FreeBSD Plugin Modules Durations"
+ , "milliseconds/run"
+ , "netdata"
+ , "stats"
+ , 132001
+ , localhost->rrd_update_every
+ , RRDSET_TYPE_STACKED
+ );
for(i = 0 ; freebsd_modules[i].name ;i++) {
struct freebsd_module *pm = &freebsd_modules[i];
diff --git a/src/plugin_freebsd.h b/src/plugin_freebsd.h
index 78fe33d7..0a6f40c1 100644
--- a/src/plugin_freebsd.h
+++ b/src/plugin_freebsd.h
@@ -18,6 +18,7 @@ extern int do_vm_vmtotal(int update_every, usec_t dt);
extern int do_kern_cp_time(int update_every, usec_t dt);
extern int do_kern_cp_times(int update_every, usec_t dt);
extern int do_dev_cpu_temperature(int update_every, usec_t dt);
+extern int do_dev_cpu_0_freq(int update_every, usec_t dt);
extern int do_hw_intcnt(int update_every, usec_t dt);
extern int do_vm_stats_sys_v_intr(int update_every, usec_t dt);
extern int do_vm_stats_sys_v_soft(int update_every, usec_t dt);
@@ -43,6 +44,7 @@ extern int do_getifaddrs(int update_every, usec_t dt);
extern int do_getmntinfo(int update_every, usec_t dt);
extern int do_kern_devstat(int update_every, usec_t dt);
extern int do_kstat_zfs_misc_arcstats(int update_every, usec_t dt);
+extern int do_kstat_zfs_misc_zio_trim(int update_every, usec_t dt);
extern int do_ipfw(int update_every, usec_t dt);
#define GETSYSCTL_MIB(name, mib) getsysctl_mib(name, mib, sizeof(mib)/sizeof(int))
diff --git a/src/plugin_idlejitter.c b/src/plugin_idlejitter.c
index 89f49023..8d933683 100644
--- a/src/plugin_idlejitter.c
+++ b/src/plugin_idlejitter.c
@@ -27,6 +27,8 @@ void *cpuidlejitter_main(void *ptr) {
, NULL
, "CPU Idle Jitter"
, "microseconds lost/s"
+ , "idlejitter"
+ , NULL
, 9999
, localhost->rrd_update_every
, RRDSET_TYPE_AREA
diff --git a/src/plugin_nfacct.c b/src/plugin_nfacct.c
index 4c691be0..8319c672 100644
--- a/src/plugin_nfacct.c
+++ b/src/plugin_nfacct.c
@@ -302,6 +302,8 @@ static void nfstat_send_metrics() {
, NULL
, "Connection Tracker New Connections"
, "connections/s"
+ , "nfacct"
+ , NULL
, 3001
, nfstat_root.update_every
, RRDSET_TYPE_LINE
@@ -336,6 +338,8 @@ static void nfstat_send_metrics() {
, NULL
, "Connection Tracker Changes"
, "changes/s"
+ , "nfacct"
+ , NULL
, 3002
, nfstat_root.update_every
, RRDSET_TYPE_LINE
@@ -371,6 +375,8 @@ static void nfstat_send_metrics() {
, NULL
, "Connection Tracker Searches"
, "searches/s"
+ , "nfacct"
+ , NULL
, 3010
, nfstat_root.update_every
, RRDSET_TYPE_LINE
@@ -406,6 +412,8 @@ static void nfstat_send_metrics() {
, NULL
, "Connection Tracker Errors"
, "events/s"
+ , "nfacct"
+ , NULL
, 3005
, nfstat_root.update_every
, RRDSET_TYPE_LINE
@@ -443,6 +451,8 @@ static void nfstat_send_metrics() {
, NULL
, "Connection Tracker Expectations"
, "expectations/s"
+ , "nfacct"
+ , NULL
, 3003
, nfstat_root.update_every
, RRDSET_TYPE_LINE
@@ -661,6 +671,8 @@ static void nfacct_send_metrics() {
, NULL
, "Netfilter Accounting Packets"
, "packets/s"
+ , "nfacct"
+ , NULL
, 3206
, nfacct_root.update_every
, RRDSET_TYPE_STACKED
@@ -702,6 +714,8 @@ static void nfacct_send_metrics() {
, NULL
, "Netfilter Accounting Bandwidth"
, "kilobytes/s"
+ , "nfacct"
+ , NULL
, 3207
, nfacct_root.update_every
, RRDSET_TYPE_STACKED
diff --git a/src/plugin_proc.c b/src/plugin_proc.c
index e64f5739..c4249c84 100644
--- a/src/plugin_proc.c
+++ b/src/plugin_proc.c
@@ -32,6 +32,8 @@ static struct proc_module {
// network metrics
{ .name = "/proc/net/dev", .dim = "netdev", .func = do_proc_net_dev },
+ { .name = "/proc/net/sockstat", .dim = "sockstat", .func = do_proc_net_sockstat },
+ { .name = "/proc/net/sockstat6", .dim = "sockstat6", .func = do_proc_net_sockstat6 },
{ .name = "/proc/net/netstat", .dim = "netstat", .func = do_proc_net_netstat }, // this has to be before /proc/net/snmp, because there is a shared metric
{ .name = "/proc/net/snmp", .dim = "snmp", .func = do_proc_net_snmp },
{ .name = "/proc/net/snmp6", .dim = "snmp6", .func = do_proc_net_snmp6 },
@@ -118,9 +120,20 @@ void *proc_main(void *ptr) {
st = rrdset_find_bytype_localhost("netdata", "plugin_proc_modules");
if(!st) {
- st = rrdset_create_localhost("netdata", "plugin_proc_modules", NULL, "proc", NULL
- , "NetData Proc Plugin Modules Durations", "milliseconds/run", 132001
- , localhost->rrd_update_every, RRDSET_TYPE_STACKED);
+ st = rrdset_create_localhost(
+ "netdata"
+ , "plugin_proc_modules"
+ , NULL
+ , "proc"
+ , NULL
+ , "NetData Proc Plugin Modules Durations"
+ , "milliseconds/run"
+ , "netdata"
+ , "stats"
+ , 132001
+ , localhost->rrd_update_every
+ , RRDSET_TYPE_STACKED
+ );
for(i = 0 ; proc_modules[i].name ;i++) {
struct proc_module *pm = &proc_modules[i];
diff --git a/src/plugin_proc.h b/src/plugin_proc.h
index 72cfc6aa..fa567544 100644
--- a/src/plugin_proc.h
+++ b/src/plugin_proc.h
@@ -26,6 +26,8 @@ extern int do_proc_uptime(int update_every, usec_t dt);
extern int do_proc_sys_devices_system_edac_mc(int update_every, usec_t dt);
extern int do_proc_sys_devices_system_node(int update_every, usec_t dt);
extern int do_proc_spl_kstat_zfs_arcstats(int update_every, usec_t dt);
+extern int do_proc_net_sockstat(int update_every, usec_t dt);
+extern int do_proc_net_sockstat6(int update_every, usec_t dt);
extern int get_numa_node_count(void);
diff --git a/src/plugin_proc_diskspace.c b/src/plugin_proc_diskspace.c
index 52c1f5ae..e41e7618 100644
--- a/src/plugin_proc_diskspace.c
+++ b/src/plugin_proc_diskspace.c
@@ -227,6 +227,12 @@ static inline void do_disk_space_stats(struct mountinfo *mi, int update_every) {
fsfilcnt_t freserved_root = favail_root - favail;
fsfilcnt_t fused = ftotal - favail_root;
+ if(m->do_inodes == CONFIG_BOOLEAN_AUTO && favail == (fsfilcnt_t)-1) {
+ // this file system does not support inodes reporting
+ // eg. cephfs
+ m->do_inodes = CONFIG_BOOLEAN_NO;
+ }
+
#ifdef NETDATA_INTERNAL_CHECKS
if(unlikely(btotal != bavail + breserved_root + bused))
error("DISKSPACE: disk inode statistics for '%s' (disk '%s') do not sum up: total = %llu, available = %llu, reserved = %llu, used = %llu", mi->mount_point, disk, (unsigned long long)ftotal, (unsigned long long)favail, (unsigned long long)freserved_root, (unsigned long long)fused);
@@ -251,6 +257,8 @@ static inline void do_disk_space_stats(struct mountinfo *mi, int update_every) {
, "disk.space"
, title
, "GB"
+ , "diskspace"
+ , NULL
, 2023
, update_every
, RRDSET_TYPE_STACKED
@@ -289,6 +297,8 @@ static inline void do_disk_space_stats(struct mountinfo *mi, int update_every) {
, "disk.inodes"
, title
, "Inodes"
+ , "diskspace"
+ , NULL
, 2024
, update_every
, RRDSET_TYPE_STACKED
@@ -384,21 +394,21 @@ void *proc_diskspace_main(void *ptr) {
getrusage(RUSAGE_THREAD, &thread);
- if(!stcpu_thread) {
- stcpu_thread = rrdset_find_localhost("netdata.plugin_diskspace");
- if(!stcpu_thread)
- stcpu_thread = rrdset_create_localhost(
- "netdata"
- , "plugin_diskspace"
- , NULL
- , "diskspace"
- , NULL
- , "NetData Disk Space Plugin CPU usage"
- , "milliseconds/s"
- , 132020
- , update_every
- , RRDSET_TYPE_STACKED
- );
+ if(unlikely(!stcpu_thread)) {
+ stcpu_thread = rrdset_create_localhost(
+ "netdata"
+ , "plugin_diskspace"
+ , NULL
+ , "diskspace"
+ , NULL
+ , "NetData Disk Space Plugin CPU usage"
+ , "milliseconds/s"
+ , "diskspace"
+ , NULL
+ , 132020
+ , update_every
+ , RRDSET_TYPE_STACKED
+ );
rd_user = rrddim_add(stcpu_thread, "user", NULL, 1, 1000, RRD_ALGORITHM_INCREMENTAL);
rd_system = rrddim_add(stcpu_thread, "system", NULL, 1, 1000, RRD_ALGORITHM_INCREMENTAL);
@@ -412,21 +422,21 @@ void *proc_diskspace_main(void *ptr) {
// ----------------------------------------------------------------
- if(!st_duration) {
- st_duration = rrdset_find_localhost("netdata.plugin_diskspace_dt");
- if(!st_duration)
- st_duration = rrdset_create_localhost(
- "netdata"
- , "plugin_diskspace_dt"
- , NULL
- , "diskspace"
- , NULL
- , "NetData Disk Space Plugin Duration"
- , "milliseconds/run"
- , 132021
- , update_every
- , RRDSET_TYPE_AREA
- );
+ if(unlikely(!st_duration)) {
+ st_duration = rrdset_create_localhost(
+ "netdata"
+ , "plugin_diskspace_dt"
+ , NULL
+ , "diskspace"
+ , NULL
+ , "NetData Disk Space Plugin Duration"
+ , "milliseconds/run"
+ , "diskspace"
+ , NULL
+ , 132021
+ , update_every
+ , RRDSET_TYPE_AREA
+ );
rd_duration = rrddim_add(st_duration, "duration", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
}
diff --git a/src/plugin_tc.c b/src/plugin_tc.c
index c928e61b..0d8fd3d6 100644
--- a/src/plugin_tc.c
+++ b/src/plugin_tc.c
@@ -81,6 +81,7 @@ struct tc_device {
avl_tree classes_index;
struct tc_class *classes;
+ struct tc_class *last_class;
struct tc_device *next;
struct tc_device *prev;
@@ -139,11 +140,19 @@ static inline struct tc_class *tc_class_index_find(struct tc_device *st, const c
static inline void tc_class_free(struct tc_device *n, struct tc_class *c) {
if(c == n->classes) {
- if(c->next)
+ if(likely(c->next))
n->classes = c->next;
else
n->classes = c->prev;
}
+
+ if(c == n->last_class) {
+ if(unlikely(c->next))
+ n->last_class = c->next;
+ else
+ n->last_class = c->prev;
+ }
+
if(c->next) c->next->prev = c->prev;
if(c->prev) c->prev->next = c->next;
@@ -374,11 +383,20 @@ static inline void tc_device_commit(struct tc_device *d) {
d->enabled_bytes = CONFIG_BOOLEAN_YES;
if(unlikely(!d->st_bytes))
- d->st_bytes = rrdset_create_localhost(RRD_TYPE_TC, d->id, d->name ? d->name : d->id
- , d->family ? d->family : d->id, RRD_TYPE_TC ".qos", "Class Usage"
- , "kilobits/s", 7000, localhost->rrd_update_every
- , d->enabled_all_classes_qdiscs ? RRDSET_TYPE_LINE
- : RRDSET_TYPE_STACKED);
+ d->st_bytes = rrdset_create_localhost(
+ RRD_TYPE_TC
+ , d->id
+ , d->name ? d->name : d->id
+ , d->family ? d->family : d->id
+ , RRD_TYPE_TC ".qos"
+ , "Class Usage"
+ , "kilobits/s"
+ , "tc"
+ , NULL
+ , 7000
+ , localhost->rrd_update_every
+ , d->enabled_all_classes_qdiscs ? RRDSET_TYPE_LINE : RRDSET_TYPE_STACKED
+ );
else {
rrdset_next(d->st_bytes);
@@ -413,10 +431,20 @@ static inline void tc_device_commit(struct tc_device *d) {
snprintfz(id, RRD_ID_LENGTH_MAX, "%s_packets", d->id);
snprintfz(name, RRD_ID_LENGTH_MAX, "%s_packets", d->name?d->name:d->id);
- d->st_packets = rrdset_create_localhost(RRD_TYPE_TC, id, name, d->family ? d->family : d->id
- , RRD_TYPE_TC ".qos_packets", "Class Packets", "packets/s", 7010
- , localhost->rrd_update_every, d->enabled_all_classes_qdiscs ? RRDSET_TYPE_LINE
- : RRDSET_TYPE_STACKED);
+ d->st_packets = rrdset_create_localhost(
+ RRD_TYPE_TC
+ , id
+ , name
+ , d->family ? d->family : d->id
+ , RRD_TYPE_TC ".qos_packets"
+ , "Class Packets"
+ , "packets/s"
+ , "tc"
+ , NULL
+ , 7010
+ , localhost->rrd_update_every
+ , d->enabled_all_classes_qdiscs ? RRDSET_TYPE_LINE : RRDSET_TYPE_STACKED
+ );
}
else {
rrdset_next(d->st_packets);
@@ -456,11 +484,20 @@ static inline void tc_device_commit(struct tc_device *d) {
snprintfz(id, RRD_ID_LENGTH_MAX, "%s_dropped", d->id);
snprintfz(name, RRD_ID_LENGTH_MAX, "%s_dropped", d->name?d->name:d->id);
- d->st_dropped = rrdset_create_localhost(RRD_TYPE_TC, id, name, d->family ? d->family : d->id
- , RRD_TYPE_TC ".qos_dropped", "Class Dropped Packets", "packets/s"
- , 7020, localhost->rrd_update_every
- , d->enabled_all_classes_qdiscs ? RRDSET_TYPE_LINE
- : RRDSET_TYPE_STACKED);
+ d->st_dropped = rrdset_create_localhost(
+ RRD_TYPE_TC
+ , id
+ , name
+ , d->family ? d->family : d->id
+ , RRD_TYPE_TC ".qos_dropped"
+ , "Class Dropped Packets"
+ , "packets/s"
+ , "tc"
+ , NULL
+ , 7020
+ , localhost->rrd_update_every
+ , d->enabled_all_classes_qdiscs ? RRDSET_TYPE_LINE : RRDSET_TYPE_STACKED
+ );
}
else {
rrdset_next(d->st_dropped);
@@ -500,9 +537,20 @@ static inline void tc_device_commit(struct tc_device *d) {
snprintfz(id, RRD_ID_LENGTH_MAX, "%s_tokens", d->id);
snprintfz(name, RRD_ID_LENGTH_MAX, "%s_tokens", d->name?d->name:d->id);
- d->st_tokens = rrdset_create_localhost(RRD_TYPE_TC, id, name, d->family ? d->family : d->id
- , RRD_TYPE_TC ".qos_tokens", "Class Tokens", "tokens", 7030
- , localhost->rrd_update_every, RRDSET_TYPE_LINE);
+ d->st_tokens = rrdset_create_localhost(
+ RRD_TYPE_TC
+ , id
+ , name
+ , d->family ? d->family : d->id
+ , RRD_TYPE_TC ".qos_tokens"
+ , "Class Tokens"
+ , "tokens"
+ , "tc"
+ , NULL
+ , 7030
+ , localhost->rrd_update_every
+ , RRDSET_TYPE_LINE
+ );
}
else {
rrdset_next(d->st_tokens);
@@ -543,9 +591,20 @@ static inline void tc_device_commit(struct tc_device *d) {
snprintfz(id, RRD_ID_LENGTH_MAX, "%s_ctokens", d->id);
snprintfz(name, RRD_ID_LENGTH_MAX, "%s_ctokens", d->name?d->name:d->id);
- d->st_ctokens = rrdset_create_localhost(RRD_TYPE_TC, id, name, d->family ? d->family : d->id
- , RRD_TYPE_TC ".qos_ctokens", "Class cTokens", "ctokens", 7040
- , localhost->rrd_update_every, RRDSET_TYPE_LINE);
+ d->st_ctokens = rrdset_create_localhost(
+ RRD_TYPE_TC
+ , id
+ , name
+ , d->family ? d->family : d->id
+ , RRD_TYPE_TC ".qos_ctokens"
+ , "Class cTokens"
+ , "ctokens"
+ , "tc"
+ , NULL
+ , 7040
+ , localhost->rrd_update_every
+ , RRDSET_TYPE_LINE
+ );
}
else {
debug(D_TC_LOOP, "TC: Updating _ctokens chart for device '%s'", d->name?d->name:d->id);
@@ -605,7 +664,7 @@ static inline void tc_device_set_device_name(struct tc_device *d, char *name) {
d->name = NULL;
}
- if(likely(name && *name && strcmp(d->id, name))) {
+ if(likely(name && *name && strcmp(d->id, name) != 0)) {
debug(D_TC_LOOP, "TC: Setting device '%s' name to '%s'", d->id, name);
d->name = strdupz(name);
d->name_updated = 1;
@@ -663,9 +722,15 @@ static inline struct tc_class *tc_class_add(struct tc_device *n, char *id, char
c = callocz(1, sizeof(struct tc_class));
- if(n->classes) n->classes->prev = c;
- c->next = n->classes;
- n->classes = c;
+ if(unlikely(!n->classes))
+ n->classes = c;
+
+ else if(likely(n->last_class)) {
+ n->last_class->next = c;
+ c->prev = n->last_class;
+ }
+
+ n->last_class = c;
c->id = strdupz(id);
c->hash = simple_hash(c->id);
@@ -776,7 +841,6 @@ void *tc_main(void *ptr) {
error("Cannot set pthread cancel state to ENABLE.");
struct rusage thread;
- RRDSET *stcpu = NULL, *sttime = NULL;
char buffer[TC_LINE_MAX+1] = "";
char *words[PLUGINSD_MAX_WORDS] = { NULL };
@@ -989,30 +1053,56 @@ void *tc_main(void *ptr) {
// debug(D_TC_LOOP, "WORKTIME line '%s' '%s'", words[1], words[2]);
getrusage(RUSAGE_THREAD, &thread);
- if(unlikely(!stcpu)) stcpu = rrdset_find_localhost("netdata.plugin_tc_cpu");
+ static RRDSET *stcpu = NULL;
+ static RRDDIM *rd_user = NULL, *rd_system = NULL;
+
if(unlikely(!stcpu)) {
- stcpu = rrdset_create_localhost("netdata", "plugin_tc_cpu", NULL, "tc.helper", NULL
- , "NetData TC CPU usage", "milliseconds/s", 135000, localhost->rrd_update_every
- , RRDSET_TYPE_STACKED);
- rrddim_add(stcpu, "user", NULL, 1, 1000, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(stcpu, "system", NULL, 1, 1000, RRD_ALGORITHM_INCREMENTAL);
+ stcpu = rrdset_create_localhost(
+ "netdata"
+ , "plugin_tc_cpu"
+ , NULL
+ , "tc.helper"
+ , NULL
+ , "NetData TC CPU usage"
+ , "milliseconds/s"
+ , "tc"
+ , NULL
+ , 135000
+ , localhost->rrd_update_every
+ , RRDSET_TYPE_STACKED
+ );
+ rd_user = rrddim_add(stcpu, "user", NULL, 1, 1000, RRD_ALGORITHM_INCREMENTAL);
+ rd_system = rrddim_add(stcpu, "system", NULL, 1, 1000, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(stcpu);
- rrddim_set(stcpu, "user" , thread.ru_utime.tv_sec * 1000000ULL + thread.ru_utime.tv_usec);
- rrddim_set(stcpu, "system", thread.ru_stime.tv_sec * 1000000ULL + thread.ru_stime.tv_usec);
+ rrddim_set_by_pointer(stcpu, rd_user , thread.ru_utime.tv_sec * 1000000ULL + thread.ru_utime.tv_usec);
+ rrddim_set_by_pointer(stcpu, rd_system, thread.ru_stime.tv_sec * 1000000ULL + thread.ru_stime.tv_usec);
rrdset_done(stcpu);
- if(unlikely(!sttime)) sttime = rrdset_find_localhost("netdata.plugin_tc_time");
+ static RRDSET *sttime = NULL;
+ static RRDDIM *rd_run_time = NULL;
+
if(unlikely(!sttime)) {
- sttime = rrdset_create_localhost("netdata", "plugin_tc_time", NULL, "tc.helper", NULL
- , "NetData TC script execution", "milliseconds/run", 135001
- , localhost->rrd_update_every, RRDSET_TYPE_AREA);
- rrddim_add(sttime, "run_time", "run time", 1, 1, RRD_ALGORITHM_ABSOLUTE);
+ sttime = rrdset_create_localhost(
+ "netdata"
+ , "plugin_tc_time"
+ , NULL
+ , "tc.helper"
+ , NULL
+ , "NetData TC script execution"
+ , "milliseconds/run"
+ , "tc"
+ , NULL
+ , 135001
+ , localhost->rrd_update_every
+ , RRDSET_TYPE_AREA
+ );
+ rd_run_time = rrddim_add(sttime, "run_time", "run time", 1, 1, RRD_ALGORITHM_ABSOLUTE);
}
else rrdset_next(sttime);
- rrddim_set(sttime, "run_time", atoll(words[1]));
+ rrddim_set_by_pointer(sttime, rd_run_time, str2ll(words[1], NULL));
rrdset_done(sttime);
}
diff --git a/src/plugins_d.c b/src/plugins_d.c
index 42433b55..d0f29f4d 100644
--- a/src/plugins_d.c
+++ b/src/plugins_d.c
@@ -1,5 +1,8 @@
#include "common.h"
+char *plugin_directories[PLUGINSD_MAX_DIRECTORIES] = { NULL };
+char *netdata_configured_plugins_dir_base;
+
struct plugind *pluginsd_root = NULL;
static inline int pluginsd_space(char c) {
@@ -16,13 +19,27 @@ static inline int pluginsd_space(char c) {
}
}
+inline int config_isspace(char c) {
+ switch(c) {
+ case ' ':
+ case '\t':
+ case '\r':
+ case '\n':
+ case ',':
+ return 1;
+
+ default:
+ return 0;
+ }
+}
+
// split a text into words, respecting quotes
-inline int pluginsd_split_words(char *str, char **words, int max_words) {
+inline int quoted_strings_splitter(char *str, char **words, int max_words, int (*custom_isspace)(char)) {
char *s = str, quote = 0;
int i = 0, j;
// skip all white space
- while(unlikely(pluginsd_space(*s))) s++;
+ while(unlikely(custom_isspace(*s))) s++;
// check for quote
if(unlikely(*s == '\'' || *s == '"')) {
@@ -49,13 +66,13 @@ inline int pluginsd_split_words(char *str, char **words, int max_words) {
}
// if it is a space
- else if(unlikely(quote == 0 && pluginsd_space(*s))) {
+ else if(unlikely(quote == 0 && custom_isspace(*s))) {
// terminate the word
*s++ = '\0';
// skip all white space
- while(likely(pluginsd_space(*s))) s++;
+ while(likely(custom_isspace(*s))) s++;
// check for quote
if(unlikely(*s == '\'' || *s == '"')) {
@@ -82,6 +99,10 @@ inline int pluginsd_split_words(char *str, char **words, int max_words) {
return i;
}
+inline int pluginsd_split_words(char *str, char **words, int max_words) {
+ return quoted_strings_splitter(str, words, max_words, pluginsd_space);
+}
+
inline size_t pluginsd_process(RRDHOST *host, struct plugind *cd, FILE *fp, int trust_durations) {
int enabled = cd->enabled;
@@ -101,6 +122,7 @@ inline size_t pluginsd_process(RRDHOST *host, struct plugind *cd, FILE *fp, int
uint32_t CHART_HASH = simple_hash(PLUGINSD_KEYWORD_CHART);
uint32_t DIMENSION_HASH = simple_hash(PLUGINSD_KEYWORD_DIMENSION);
uint32_t DISABLE_HASH = simple_hash(PLUGINSD_KEYWORD_DISABLE);
+ uint32_t VARIABLE_HASH = simple_hash(PLUGINSD_KEYWORD_VARIABLE);
RRDSET *st = NULL;
uint32_t hash;
@@ -212,10 +234,6 @@ inline size_t pluginsd_process(RRDHOST *host, struct plugind *cd, FILE *fp, int
count++;
}
- else if(likely(hash == FLUSH_HASH && !strcmp(s, PLUGINSD_KEYWORD_FLUSH))) {
- debug(D_PLUGINSD, "PLUGINSD: '%s' is requesting a FLUSH", cd->fullfilename);
- st = NULL;
- }
else if(likely(hash == CHART_HASH && !strcmp(s, PLUGINSD_KEYWORD_CHART))) {
st = NULL;
@@ -229,6 +247,8 @@ inline size_t pluginsd_process(RRDHOST *host, struct plugind *cd, FILE *fp, int
char *priority_s = words[8];
char *update_every_s = words[9];
char *options = words[10];
+ char *plugin = words[11];
+ char *module = words[12];
// parse the id from type
char *id = NULL;
@@ -275,22 +295,31 @@ inline size_t pluginsd_process(RRDHOST *host, struct plugind *cd, FILE *fp, int
if(unlikely(!title)) title = "";
if(unlikely(!units)) units = "unknown";
- st = rrdset_find_bytype(host, type, id);
- if(unlikely(!st)) {
- debug(D_PLUGINSD, "PLUGINSD: Creating chart type='%s', id='%s', name='%s', family='%s', context='%s', chart='%s', priority=%d, update_every=%d"
- , type, id
- , name?name:""
- , family?family:""
- , context?context:""
- , rrdset_type_name(chart_type)
- , priority
- , update_every
- );
-
- st = rrdset_create(host, type, id, name, family, context, title, units, priority, update_every, chart_type);
- cd->update_every = update_every;
- }
- else debug(D_PLUGINSD, "PLUGINSD: Chart '%s' already exists. Not adding it again.", st->id);
+ debug(D_PLUGINSD, "PLUGINSD: Creating chart type='%s', id='%s', name='%s', family='%s', context='%s', chart='%s', priority=%d, update_every=%d"
+ , type, id
+ , name?name:""
+ , family?family:""
+ , context?context:""
+ , rrdset_type_name(chart_type)
+ , priority
+ , update_every
+ );
+
+ st = rrdset_create(
+ host
+ , type
+ , id
+ , name
+ , family
+ , context
+ , title
+ , units
+ , (plugin && *plugin)?plugin:cd->filename
+ , module
+ , priority
+ , update_every
+ , chart_type
+ );
if(options && *options) {
if(strstr(options, "obsolete"))
@@ -308,6 +337,11 @@ inline size_t pluginsd_process(RRDHOST *host, struct plugind *cd, FILE *fp, int
else
rrdset_flag_clear(st, RRDSET_FLAG_STORE_FIRST);
}
+ else {
+ rrdset_isnot_obsolete(st);
+ rrdset_flag_clear(st, RRDSET_FLAG_DETAIL);
+ rrdset_flag_clear(st, RRDSET_FLAG_STORE_FIRST);
+ }
}
else if(likely(hash == DIMENSION_HASH && !strcmp(s, PLUGINSD_KEYWORD_DIMENSION))) {
char *id = words[1];
@@ -359,6 +393,64 @@ inline size_t pluginsd_process(RRDHOST *host, struct plugind *cd, FILE *fp, int
if(strstr(options, "nooverflow") != NULL) rrddim_flag_set(rd, RRDDIM_FLAG_DONT_DETECT_RESETS_OR_OVERFLOWS);
}
}
+ else if(likely(hash == VARIABLE_HASH && !strcmp(s, PLUGINSD_KEYWORD_VARIABLE))) {
+ char *name = words[1];
+ char *value = words[2];
+ int global = (st)?0:1;
+
+ if(name && *name) {
+ if((strcmp(name, "GLOBAL") == 0 || strcmp(name, "HOST") == 0)) {
+ global = 1;
+ name = words[2];
+ value = words[3];
+ }
+ else if((strcmp(name, "LOCAL") == 0 || strcmp(name, "CHART") == 0)) {
+ global = 0;
+ name = words[2];
+ value = words[3];
+ }
+ }
+
+ if(unlikely(!name || !*name)) {
+ error("PLUGINSD: '%s' is requesting a VARIABLE on host '%s', without a variable name. Disabling it.", cd->fullfilename, host->hostname);
+ enabled = 0;
+ break;
+ }
+
+ if(unlikely(!value || !*value))
+ value = NULL;
+
+ if(value) {
+ char *endptr = NULL;
+ calculated_number v = (calculated_number)str2ld(value, &endptr);
+
+ if(unlikely(endptr && *endptr)) {
+ if(endptr == value)
+ error("PLUGINSD: '%s': the value '%s' of VARIABLE '%s' on host '%s' cannot be parsed as a number", cd->fullfilename, value, name, host->hostname);
+ else
+ error("PLUGINSD: '%s': the value '%s' of VARIABLE '%s' on host '%s' has leftovers: '%s'", cd->fullfilename, value, name, host->hostname, endptr);
+ }
+
+ if(global) {
+ RRDVAR *rv = rrdvar_custom_host_variable_create(host, name);
+ if (rv) rrdvar_custom_host_variable_set(host, rv, v);
+ else error("PLUGINSD: '%s': cannot find/create HOST VARIABLE '%s' on host '%s'", cd->fullfilename, name, host->hostname);
+ }
+ else if(st) {
+ RRDSETVAR *rs = rrdsetvar_custom_chart_variable_create(st, name);
+ if (rs) rrdsetvar_custom_chart_variable_set(rs, v);
+ else error("PLUGINSD: '%s': cannot find/create CHART VARIABLE '%s' on host '%s', chart '%s'", cd->fullfilename, name, host->hostname, st->id);
+ }
+ else
+ error("PLUGINSD: '%s': cannot find/create CHART VARIABLE '%s' on host '%s' without a chart", cd->fullfilename, name, host->hostname);
+ }
+ else
+ error("PLUGINSD: '%s': cannot set %s VARIABLE '%s' on host '%s' to an empty value", cd->fullfilename, (global)?"HOST":"CHART", name, host->hostname);
+ }
+ else if(likely(hash == FLUSH_HASH && !strcmp(s, PLUGINSD_KEYWORD_FLUSH))) {
+ debug(D_PLUGINSD, "PLUGINSD: '%s' is requesting a FLUSH", cd->fullfilename);
+ st = NULL;
+ }
else if(unlikely(hash == DISABLE_HASH && !strcmp(s, PLUGINSD_KEYWORD_DISABLE))) {
info("PLUGINSD: '%s' called DISABLE. Disabling it.", cd->fullfilename);
enabled = 0;
@@ -476,99 +568,131 @@ void *pluginsd_main(void *ptr) {
int automatic_run = config_get_boolean(CONFIG_SECTION_PLUGINS, "enable running new plugins", 1);
int scan_frequency = (int) config_get_number(CONFIG_SECTION_PLUGINS, "check for new plugins every", 60);
- DIR *dir = NULL;
- struct dirent *file = NULL;
- struct plugind *cd;
-
- // enable the apps plugin by default
- // config_get_boolean(CONFIG_SECTION_PLUGINS, "apps", 1);
-
if(scan_frequency < 1) scan_frequency = 1;
+ // store the errno for each plugins directory
+ // so that we don't log broken directories on each loop
+ int directory_errors[PLUGINSD_MAX_DIRECTORIES] = { 0 };
+
for(;;) {
if(unlikely(netdata_exit)) break;
- dir = opendir(netdata_configured_plugins_dir);
- if(unlikely(!dir)) {
- error("Cannot open directory '%s'.", netdata_configured_plugins_dir);
- goto cleanup;
- }
+ int idx;
+ const char *directory_name;
- while(likely((file = readdir(dir)))) {
+ for( idx = 0; idx < PLUGINSD_MAX_DIRECTORIES && (directory_name = plugin_directories[idx]) ; idx++ ) {
if(unlikely(netdata_exit)) break;
- debug(D_PLUGINSD, "PLUGINSD: Examining file '%s'", file->d_name);
-
- if(unlikely(strcmp(file->d_name, ".") == 0 || strcmp(file->d_name, "..") == 0)) continue;
-
- int len = (int) strlen(file->d_name);
- if(unlikely(len <= (int)PLUGINSD_FILE_SUFFIX_LEN)) continue;
- if(unlikely(strcmp(PLUGINSD_FILE_SUFFIX, &file->d_name[len - (int)PLUGINSD_FILE_SUFFIX_LEN]) != 0)) {
- debug(D_PLUGINSD, "PLUGINSD: File '%s' does not end in '%s'.", file->d_name, PLUGINSD_FILE_SUFFIX);
+ errno = 0;
+ DIR *dir = opendir(directory_name);
+ if(unlikely(!dir)) {
+ if(directory_errors[idx] != errno) {
+ directory_errors[idx] = errno;
+ error("PLUGINSD: Cannot open plugins directory '%s'.", directory_name);
+ }
continue;
}
- char pluginname[CONFIG_MAX_NAME + 1];
- snprintfz(pluginname, CONFIG_MAX_NAME, "%.*s", (int)(len - PLUGINSD_FILE_SUFFIX_LEN), file->d_name);
- int enabled = config_get_boolean(CONFIG_SECTION_PLUGINS, pluginname, automatic_run);
+ struct dirent *file = NULL;
+ while(likely((file = readdir(dir)))) {
+ if(unlikely(netdata_exit)) break;
- if(unlikely(!enabled)) {
- debug(D_PLUGINSD, "PLUGINSD: plugin '%s' is not enabled", file->d_name);
- continue;
- }
+ debug(D_PLUGINSD, "PLUGINSD: Examining file '%s'", file->d_name);
- // check if it runs already
- for(cd = pluginsd_root ; cd ; cd = cd->next)
- if(unlikely(strcmp(cd->filename, file->d_name) == 0)) break;
+ if(unlikely(strcmp(file->d_name, ".") == 0 || strcmp(file->d_name, "..") == 0)) continue;
- if(likely(cd && !cd->obsolete)) {
- debug(D_PLUGINSD, "PLUGINSD: plugin '%s' is already running", cd->filename);
- continue;
- }
+ int len = (int) strlen(file->d_name);
+ if(unlikely(len <= (int)PLUGINSD_FILE_SUFFIX_LEN)) continue;
+ if(unlikely(strcmp(PLUGINSD_FILE_SUFFIX, &file->d_name[len - (int)PLUGINSD_FILE_SUFFIX_LEN]) != 0)) {
+ debug(D_PLUGINSD, "PLUGINSD: File '%s' does not end in '%s'.", file->d_name, PLUGINSD_FILE_SUFFIX);
+ continue;
+ }
+
+ char pluginname[CONFIG_MAX_NAME + 1];
+ snprintfz(pluginname, CONFIG_MAX_NAME, "%.*s", (int)(len - PLUGINSD_FILE_SUFFIX_LEN), file->d_name);
+ int enabled = config_get_boolean(CONFIG_SECTION_PLUGINS, pluginname, automatic_run);
+
+ if(unlikely(!enabled)) {
+ debug(D_PLUGINSD, "PLUGINSD: plugin '%s' is not enabled", file->d_name);
+ continue;
+ }
+
+ // check if it runs already
+ struct plugind *cd;
+ for(cd = pluginsd_root ; cd ; cd = cd->next)
+ if(unlikely(strcmp(cd->filename, file->d_name) == 0)) break;
- // it is not running
- // allocate a new one, or use the obsolete one
- if(unlikely(!cd)) {
- cd = callocz(sizeof(struct plugind), 1);
+ if(likely(cd && !cd->obsolete)) {
+ debug(D_PLUGINSD, "PLUGINSD: plugin '%s' is already running", cd->filename);
+ continue;
+ }
+
+ // it is not running
+ // allocate a new one, or use the obsolete one
+ if(unlikely(!cd)) {
+ cd = callocz(sizeof(struct plugind), 1);
- snprintfz(cd->id, CONFIG_MAX_NAME, "plugin:%s", pluginname);
+ snprintfz(cd->id, CONFIG_MAX_NAME, "plugin:%s", pluginname);
- strncpyz(cd->filename, file->d_name, FILENAME_MAX);
- snprintfz(cd->fullfilename, FILENAME_MAX, "%s/%s", netdata_configured_plugins_dir, cd->filename);
+ strncpyz(cd->filename, file->d_name, FILENAME_MAX);
+ snprintfz(cd->fullfilename, FILENAME_MAX, "%s/%s", directory_name, cd->filename);
- cd->enabled = enabled;
- cd->update_every = (int) config_get_number(cd->id, "update every", localhost->rrd_update_every);
- cd->started_t = now_realtime_sec();
+ cd->enabled = enabled;
+ cd->update_every = (int) config_get_number(cd->id, "update every", localhost->rrd_update_every);
+ cd->started_t = now_realtime_sec();
- char *def = "";
- snprintfz(cd->cmd, PLUGINSD_CMD_MAX, "exec %s %d %s", cd->fullfilename, cd->update_every, config_get(cd->id, "command options", def));
+ char *def = "";
+ snprintfz(cd->cmd, PLUGINSD_CMD_MAX, "exec %s %d %s", cd->fullfilename, cd->update_every, config_get(cd->id, "command options", def));
- // link it
- if(likely(pluginsd_root)) cd->next = pluginsd_root;
- pluginsd_root = cd;
+ // link it
+ if(likely(pluginsd_root)) cd->next = pluginsd_root;
+ pluginsd_root = cd;
- // it is not currently running
- cd->obsolete = 1;
+ // it is not currently running
+ cd->obsolete = 1;
- if(cd->enabled) {
- // spawn a new thread for it
- if(unlikely(pthread_create(&cd->thread, NULL, pluginsd_worker_thread, cd) != 0))
- error("PLUGINSD: failed to create new thread for plugin '%s'.", cd->filename);
+ if(cd->enabled) {
+ // spawn a new thread for it
+ if(unlikely(pthread_create(&cd->thread, NULL, pluginsd_worker_thread, cd) != 0))
+ error("PLUGINSD: failed to create new thread for plugin '%s'.", cd->filename);
- else if(unlikely(pthread_detach(cd->thread) != 0))
- error("PLUGINSD: Cannot request detach of newly created thread for plugin '%s'.", cd->filename);
+ else if(unlikely(pthread_detach(cd->thread) != 0))
+ error("PLUGINSD: Cannot request detach of newly created thread for plugin '%s'.", cd->filename);
+ }
}
}
+
+ closedir(dir);
}
- closedir(dir);
sleep((unsigned int) scan_frequency);
}
-cleanup:
info("PLUGINS.D thread exiting");
static_thread->enabled = 0;
pthread_exit(NULL);
return NULL;
}
+
+
+void pluginsd_stop_all_external_plugins() {
+ siginfo_t info;
+ struct plugind *cd;
+ for(cd = pluginsd_root ; cd ; cd = cd->next) {
+ if(cd->enabled && !cd->obsolete) {
+ info("Stopping %s plugin thread", cd->id);
+ pthread_cancel(cd->thread);
+
+ if(cd->pid) {
+ info("killing %s plugin child process pid %d", cd->id, cd->pid);
+ if(killpid(cd->pid, SIGTERM) != -1)
+ waitid(P_PID, (id_t) cd->pid, &info, WEXITED);
+
+ cd->pid = 0;
+ }
+
+ cd->obsolete = 1;
+ }
+ }
+}
diff --git a/src/plugins_d.h b/src/plugins_d.h
index 595a515c..4d708386 100644
--- a/src/plugins_d.h
+++ b/src/plugins_d.h
@@ -11,10 +11,14 @@
#define PLUGINSD_KEYWORD_END "END"
#define PLUGINSD_KEYWORD_FLUSH "FLUSH"
#define PLUGINSD_KEYWORD_DISABLE "DISABLE"
+#define PLUGINSD_KEYWORD_VARIABLE "VARIABLE"
#define PLUGINSD_LINE_MAX 1024
#define PLUGINSD_MAX_WORDS 20
+#define PLUGINSD_MAX_DIRECTORIES 20
+extern char *plugin_directories[PLUGINSD_MAX_DIRECTORIES];
+
struct plugind {
char id[CONFIG_MAX_NAME+1]; // config node id
@@ -43,7 +47,12 @@ struct plugind {
extern struct plugind *pluginsd_root;
extern void *pluginsd_main(void *ptr);
+extern void pluginsd_stop_all_external_plugins(void);
+
extern size_t pluginsd_process(RRDHOST *host, struct plugind *cd, FILE *fp, int trust_durations);
extern int pluginsd_split_words(char *str, char **words, int max_words);
+extern int quoted_strings_splitter(char *str, char **words, int max_words, int (*custom_isspace)(char));
+extern int config_isspace(char c);
+
#endif /* NETDATA_PLUGINS_D_H */
diff --git a/src/proc_diskstats.c b/src/proc_diskstats.c
index 4a32ec94..866e49c7 100644
--- a/src/proc_diskstats.c
+++ b/src/proc_diskstats.c
@@ -2,12 +2,13 @@
#define RRD_TYPE_DISK "disk"
+#define DISK_TYPE_UNKNOWN 0
#define DISK_TYPE_PHYSICAL 1
#define DISK_TYPE_PARTITION 2
-#define DISK_TYPE_CONTAINER 3
+#define DISK_TYPE_VIRTUAL 3
#define CONFIG_SECTION_DISKSTATS "plugin:proc:/proc/diskstats"
-#define DELAULT_EXLUDED_DISKS "loop* ram*"
+#define DEFAULT_EXCLUDED_DISKS "loop* ram*"
static struct disk {
char *disk; // the name of the disk (sda, sdb, etc, after being looked up)
@@ -31,16 +32,41 @@ static struct disk {
int updated;
- RRDSET *st_avgsz;
- RRDSET *st_await;
- RRDSET *st_backlog;
RRDSET *st_io;
- RRDSET *st_iotime;
- RRDSET *st_mops;
+ RRDDIM *rd_io_reads;
+ RRDDIM *rd_io_writes;
+
RRDSET *st_ops;
+ RRDDIM *rd_ops_reads;
+ RRDDIM *rd_ops_writes;
+
RRDSET *st_qops;
- RRDSET *st_svctm;
+ RRDDIM *rd_qops_operations;
+
+ RRDSET *st_backlog;
+ RRDDIM *rd_backlog_backlog;
+
RRDSET *st_util;
+ RRDDIM *rd_util_utilization;
+
+ RRDSET *st_mops;
+ RRDDIM *rd_mops_reads;
+ RRDDIM *rd_mops_writes;
+
+ RRDSET *st_iotime;
+ RRDDIM *rd_iotime_reads;
+ RRDDIM *rd_iotime_writes;
+
+ RRDSET *st_await;
+ RRDDIM *rd_await_reads;
+ RRDDIM *rd_await_writes;
+
+ RRDSET *st_avgsz;
+ RRDDIM *rd_avgsz_reads;
+ RRDDIM *rd_avgsz_writes;
+
+ RRDSET *st_svctm;
+ RRDDIM *rd_svctm_svctm;
struct disk *next;
} *disk_root = NULL;
@@ -49,21 +75,23 @@ static struct disk {
static char *path_to_get_hw_sector_size = NULL;
static char *path_to_get_hw_sector_size_partitions = NULL;
-static char *path_to_find_block_device = NULL;
+static char *path_to_sys_dev_block_major_minor_string = NULL;
+static char *path_to_sys_block_device = NULL;
+static char *path_to_sys_devices_virtual_block_device = NULL;
static char *path_to_device_mapper = NULL;
+static char *path_to_device_label = NULL;
+static char *path_to_device_id = NULL;
+static int name_disks_by_id = CONFIG_BOOLEAN_NO;
-static inline char *get_disk_name(unsigned long major, unsigned long minor, char *disk) {
- static int enabled = 1;
-
- if(!enabled) goto cleanup;
-
+static inline int get_disk_name_from_path(const char *path, char *result, size_t result_size, unsigned long major, unsigned long minor, char *disk) {
char filename[FILENAME_MAX + 1];
- char link[FILENAME_MAX + 1];
+ int found = 0;
- DIR *dir = opendir(path_to_device_mapper);
+ result_size--;
+
+ DIR *dir = opendir(path);
if (!dir) {
- error("DEVICE-MAPPER ('%s', %lu:%lu): Cannot open directory '%s'. Disabling device-mapper support.", disk, major, minor, path_to_device_mapper);
- enabled = 0;
+ error("DEVICE-MAPPER ('%s', %lu:%lu): Cannot open directory '%s'. Disabling device-mapper support.", disk, major, minor, path);
goto cleanup;
}
@@ -71,18 +99,18 @@ static inline char *get_disk_name(unsigned long major, unsigned long minor, char
while ((de = readdir(dir))) {
if(de->d_type != DT_LNK) continue;
- snprintfz(filename, FILENAME_MAX, "%s/%s", path_to_device_mapper, de->d_name);
- ssize_t len = readlink(filename, link, FILENAME_MAX);
+ snprintfz(filename, FILENAME_MAX, "%s/%s", path, de->d_name);
+ ssize_t len = readlink(filename, result, result_size);
if(len <= 0) {
error("DEVICE-MAPPER ('%s', %lu:%lu): Cannot read link '%s'.", disk, major, minor, filename);
continue;
}
- link[len] = '\0';
- if(link[0] != '/')
- snprintfz(filename, FILENAME_MAX, "%s/%s", path_to_device_mapper, link);
+ result[len] = '\0';
+ if(result[0] != '/')
+ snprintfz(filename, FILENAME_MAX, "%s/%s", path, result);
else
- strncpyz(filename, link, FILENAME_MAX);
+ strncpyz(filename, result, FILENAME_MAX);
struct stat sb;
if(stat(filename, &sb) == -1) {
@@ -102,17 +130,37 @@ static inline char *get_disk_name(unsigned long major, unsigned long minor, char
// info("DEVICE-MAPPER ('%s', %lu:%lu): filename '%s' matches.", disk, major, minor, filename);
- strncpy(link, de->d_name, FILENAME_MAX);
- netdata_fix_chart_name(link);
- disk = link;
+ strncpy(result, de->d_name, result_size);
+ found = 1;
break;
}
closedir(dir);
+
cleanup:
- return strdupz(disk);
+
+ if(!found)
+ result[0] = '\0';
+
+ return found;
}
+static inline char *get_disk_name(unsigned long major, unsigned long minor, char *disk) {
+ char result[FILENAME_MAX + 1] = "";
+
+ if(!path_to_device_mapper || !*path_to_device_mapper || !get_disk_name_from_path(path_to_device_mapper, result, FILENAME_MAX + 1, major, minor, disk))
+ if(!path_to_device_label || !*path_to_device_label || !get_disk_name_from_path(path_to_device_label, result, FILENAME_MAX + 1, major, minor, disk))
+ if(name_disks_by_id != CONFIG_BOOLEAN_YES || !path_to_device_id || !*path_to_device_id || !get_disk_name_from_path(path_to_device_id, result, FILENAME_MAX + 1, major, minor, disk))
+ strncpy(result, disk, FILENAME_MAX);
+
+ if(!result[0])
+ strncpy(result, disk, FILENAME_MAX);
+
+ netdata_fix_chart_name(result);
+ return strdup(result);
+}
+
+
static struct disk *get_disk(unsigned long major, unsigned long minor, char *disk) {
static struct mountinfo *disk_mountinfo_root = NULL;
@@ -134,7 +182,7 @@ static struct disk *get_disk(unsigned long major, unsigned long minor, char *dis
d->device = strdupz(disk);
d->major = major;
d->minor = minor;
- d->type = DISK_TYPE_PHYSICAL; // Default type. Changed later if not correct.
+ d->type = DISK_TYPE_UNKNOWN; // Default type. Changed later if not correct.
d->configured = 0;
d->sector_size = 512; // the default, will be changed below
d->next = NULL;
@@ -148,33 +196,50 @@ static struct disk *get_disk(unsigned long major, unsigned long minor, char *dis
last->next = d;
}
+ char buffer[FILENAME_MAX + 1];
+
+ // find if it is a physical disk
+ // by checking if /sys/block/DISK is readable.
+ snprintfz(buffer, FILENAME_MAX, path_to_sys_block_device, disk);
+ if(likely(access(buffer, R_OK) == 0)) {
+ // assign it here, but it will be overwritten if it is not a physical disk
+ d->type = DISK_TYPE_PHYSICAL;
+ }
+
// find if it is a partition
// by checking if /sys/dev/block/MAJOR:MINOR/partition is readable.
- char buffer[FILENAME_MAX + 1];
- snprintfz(buffer, FILENAME_MAX, path_to_find_block_device, major, minor, "partition");
+ snprintfz(buffer, FILENAME_MAX, path_to_sys_dev_block_major_minor_string, major, minor, "partition");
if(likely(access(buffer, R_OK) == 0)) {
d->type = DISK_TYPE_PARTITION;
}
else {
- // find if it is a container
- // by checking if /sys/dev/block/MAJOR:MINOR/slaves has entries
- snprintfz(buffer, FILENAME_MAX, path_to_find_block_device, major, minor, "slaves/");
- DIR *dirp = opendir(buffer);
- if(likely(dirp != NULL)) {
- struct dirent *dp;
- while( (dp = readdir(dirp)) ) {
- // . and .. are also files in empty folders.
- if(unlikely(strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0)) {
- continue;
+ // find if it is a virtual disk
+ // by checking if /sys/devices/virtual/block/DISK is readable.
+ snprintfz(buffer, FILENAME_MAX, path_to_sys_devices_virtual_block_device, disk);
+ if(likely(access(buffer, R_OK) == 0)) {
+ d->type = DISK_TYPE_VIRTUAL;
+ }
+ else {
+ // find if it is a virtual device
+ // by checking if /sys/dev/block/MAJOR:MINOR/slaves has entries
+ snprintfz(buffer, FILENAME_MAX, path_to_sys_dev_block_major_minor_string, major, minor, "slaves/");
+ DIR *dirp = opendir(buffer);
+ if (likely(dirp != NULL)) {
+ struct dirent *dp;
+ while ((dp = readdir(dirp))) {
+ // . and .. are also files in empty folders.
+ if (unlikely(strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0)) {
+ continue;
+ }
+
+ d->type = DISK_TYPE_VIRTUAL;
+
+ // Stop the loop after we found one file.
+ break;
}
-
- d->type = DISK_TYPE_CONTAINER;
-
- // Stop the loop after we found one file.
- break;
+ if (unlikely(closedir(dirp) == -1))
+ error("Unable to close dir %s", buffer);
}
- if(unlikely(closedir(dirp) == -1))
- error("Unable to close dir %s", buffer);
}
}
@@ -296,8 +361,14 @@ int do_proc_diskstats(int update_every, usec_t dt) {
char buffer[FILENAME_MAX + 1];
+ snprintfz(buffer, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/sys/block/%s");
+ path_to_sys_block_device = config_get(CONFIG_SECTION_DISKSTATS, "path to get block device", buffer);
+
+ snprintfz(buffer, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/sys/devices/virtual/block/%s");
+ path_to_sys_devices_virtual_block_device = config_get(CONFIG_SECTION_DISKSTATS, "path to get virtual block device", buffer);
+
snprintfz(buffer, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/sys/dev/block/%lu:%lu/%s");
- path_to_find_block_device = config_get(CONFIG_SECTION_DISKSTATS, "path to get block device infos", buffer);
+ path_to_sys_dev_block_major_minor_string = config_get(CONFIG_SECTION_DISKSTATS, "path to get block device infos", buffer);
snprintfz(buffer, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/sys/block/%s/queue/hw_sector_size");
path_to_get_hw_sector_size = config_get(CONFIG_SECTION_DISKSTATS, "path to get h/w sector size", buffer);
@@ -307,6 +378,14 @@ int do_proc_diskstats(int update_every, usec_t dt) {
snprintfz(buffer, FILENAME_MAX, "%s/dev/mapper", netdata_configured_host_prefix);
path_to_device_mapper = config_get(CONFIG_SECTION_DISKSTATS, "path to device mapper", buffer);
+
+ snprintfz(buffer, FILENAME_MAX, "%s/dev/disk/by-label", netdata_configured_host_prefix);
+ path_to_device_label = config_get(CONFIG_SECTION_DISKSTATS, "path to /dev/disk/by-label", buffer);
+
+ snprintfz(buffer, FILENAME_MAX, "%s/dev/disk/by-id", netdata_configured_host_prefix);
+ path_to_device_id = config_get(CONFIG_SECTION_DISKSTATS, "path to /dev/disk/by-id", buffer);
+
+ name_disks_by_id = config_get_boolean(CONFIG_SECTION_DISKSTATS, "name disks by id", name_disks_by_id);
}
// --------------------------------------------------------------------------
@@ -323,6 +402,8 @@ int do_proc_diskstats(int update_every, usec_t dt) {
size_t lines = procfile_lines(ff), l;
+ collected_number system_read_kb = 0, system_write_kb = 0;
+
for(l = 0; l < lines ;l++) {
// --------------------------------------------------------------------------
// Read parameters
@@ -398,6 +479,11 @@ int do_proc_diskstats(int update_every, usec_t dt) {
struct disk *d = get_disk(major, minor, disk);
d->updated = 1;
+ if(unlikely(d->type == DISK_TYPE_PHYSICAL)) {
+ system_read_kb += readsectors * d->sector_size / 1024;
+ system_write_kb += writesectors * d->sector_size / 1024;
+ }
+
// --------------------------------------------------------------------------
// Set its family based on mount point
@@ -415,7 +501,7 @@ int do_proc_diskstats(int update_every, usec_t dt) {
if(unlikely(!excluded_disks)) {
excluded_disks = simple_pattern_create(
- config_get(CONFIG_SECTION_DISKSTATS, "exclude disks", DELAULT_EXLUDED_DISKS),
+ config_get(CONFIG_SECTION_DISKSTATS, "exclude disks", DEFAULT_EXCLUDED_DISKS),
SIMPLE_PATTERN_EXACT
);
}
@@ -449,6 +535,10 @@ int do_proc_diskstats(int update_every, usec_t dt) {
// based on the type of disk
switch(d->type) {
+ default:
+ case DISK_TYPE_UNKNOWN:
+ break;
+
case DISK_TYPE_PHYSICAL:
def_performance = global_enable_performance_for_physical_disks;
break;
@@ -457,7 +547,7 @@ int do_proc_diskstats(int update_every, usec_t dt) {
def_performance = global_enable_performance_for_partitions;
break;
- case DISK_TYPE_CONTAINER:
+ case DISK_TYPE_VIRTUAL:
def_performance = global_enable_performance_for_virtual_disks;
break;
}
@@ -518,18 +608,20 @@ int do_proc_diskstats(int update_every, usec_t dt) {
, "disk.io"
, "Disk I/O Bandwidth"
, "kilobytes/s"
+ , "proc"
+ , "diskstats"
, 2000
, update_every
, RRDSET_TYPE_AREA
);
- rrddim_add(d->st_io, "reads", NULL, d->sector_size, 1024, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(d->st_io, "writes", NULL, d->sector_size * -1, 1024, RRD_ALGORITHM_INCREMENTAL);
+ d->rd_io_reads = rrddim_add(d->st_io, "reads", NULL, d->sector_size, 1024, RRD_ALGORITHM_INCREMENTAL);
+ d->rd_io_writes = rrddim_add(d->st_io, "writes", NULL, d->sector_size * -1, 1024, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(d->st_io);
- last_readsectors = rrddim_set(d->st_io, "reads", readsectors);
- last_writesectors = rrddim_set(d->st_io, "writes", writesectors);
+ last_readsectors = rrddim_set_by_pointer(d->st_io, d->rd_io_reads, readsectors);
+ last_writesectors = rrddim_set_by_pointer(d->st_io, d->rd_io_writes, writesectors);
rrdset_done(d->st_io);
}
@@ -547,6 +639,8 @@ int do_proc_diskstats(int update_every, usec_t dt) {
, "disk.ops"
, "Disk Completed I/O Operations"
, "operations/s"
+ , "proc"
+ , "diskstats"
, 2001
, update_every
, RRDSET_TYPE_LINE
@@ -554,13 +648,13 @@ int do_proc_diskstats(int update_every, usec_t dt) {
rrdset_flag_set(d->st_ops, RRDSET_FLAG_DETAIL);
- rrddim_add(d->st_ops, "reads", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(d->st_ops, "writes", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ d->rd_ops_reads = rrddim_add(d->st_ops, "reads", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ d->rd_ops_writes = rrddim_add(d->st_ops, "writes", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(d->st_ops);
- last_reads = rrddim_set(d->st_ops, "reads", reads);
- last_writes = rrddim_set(d->st_ops, "writes", writes);
+ last_reads = rrddim_set_by_pointer(d->st_ops, d->rd_ops_reads, reads);
+ last_writes = rrddim_set_by_pointer(d->st_ops, d->rd_ops_writes, writes);
rrdset_done(d->st_ops);
}
@@ -578,6 +672,8 @@ int do_proc_diskstats(int update_every, usec_t dt) {
, "disk.qops"
, "Disk Current I/O Operations"
, "operations"
+ , "proc"
+ , "diskstats"
, 2002
, update_every
, RRDSET_TYPE_LINE
@@ -585,11 +681,11 @@ int do_proc_diskstats(int update_every, usec_t dt) {
rrdset_flag_set(d->st_qops, RRDSET_FLAG_DETAIL);
- rrddim_add(d->st_qops, "operations", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+ d->rd_qops_operations = rrddim_add(d->st_qops, "operations", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
}
else rrdset_next(d->st_qops);
- rrddim_set(d->st_qops, "operations", queued_ios);
+ rrddim_set_by_pointer(d->st_qops, d->rd_qops_operations, queued_ios);
rrdset_done(d->st_qops);
}
@@ -607,6 +703,8 @@ int do_proc_diskstats(int update_every, usec_t dt) {
, "disk.backlog"
, "Disk Backlog"
, "backlog (ms)"
+ , "proc"
+ , "diskstats"
, 2003
, update_every
, RRDSET_TYPE_AREA
@@ -614,11 +712,11 @@ int do_proc_diskstats(int update_every, usec_t dt) {
rrdset_flag_set(d->st_backlog, RRDSET_FLAG_DETAIL);
- rrddim_add(d->st_backlog, "backlog", NULL, 1, 10, RRD_ALGORITHM_INCREMENTAL);
+ d->rd_backlog_backlog = rrddim_add(d->st_backlog, "backlog", NULL, 1, 10, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(d->st_backlog);
- rrddim_set(d->st_backlog, "backlog", backlog_ms);
+ rrddim_set_by_pointer(d->st_backlog, d->rd_backlog_backlog, backlog_ms);
rrdset_done(d->st_backlog);
}
@@ -636,6 +734,8 @@ int do_proc_diskstats(int update_every, usec_t dt) {
, "disk.util"
, "Disk Utilization Time"
, "% of time working"
+ , "proc"
+ , "diskstats"
, 2004
, update_every
, RRDSET_TYPE_AREA
@@ -643,11 +743,11 @@ int do_proc_diskstats(int update_every, usec_t dt) {
rrdset_flag_set(d->st_util, RRDSET_FLAG_DETAIL);
- rrddim_add(d->st_util, "utilization", NULL, 1, 10, RRD_ALGORITHM_INCREMENTAL);
+ d->rd_util_utilization = rrddim_add(d->st_util, "utilization", NULL, 1, 10, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(d->st_util);
- last_busy_ms = rrddim_set(d->st_util, "utilization", busy_ms);
+ last_busy_ms = rrddim_set_by_pointer(d->st_util, d->rd_util_utilization, busy_ms);
rrdset_done(d->st_util);
}
@@ -665,6 +765,8 @@ int do_proc_diskstats(int update_every, usec_t dt) {
, "disk.mops"
, "Disk Merged Operations"
, "merged operations/s"
+ , "proc"
+ , "diskstats"
, 2021
, update_every
, RRDSET_TYPE_LINE
@@ -672,13 +774,13 @@ int do_proc_diskstats(int update_every, usec_t dt) {
rrdset_flag_set(d->st_mops, RRDSET_FLAG_DETAIL);
- rrddim_add(d->st_mops, "reads", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(d->st_mops, "writes", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ d->rd_mops_reads = rrddim_add(d->st_mops, "reads", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ d->rd_mops_writes = rrddim_add(d->st_mops, "writes", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(d->st_mops);
- rrddim_set(d->st_mops, "reads", mreads);
- rrddim_set(d->st_mops, "writes", mwrites);
+ rrddim_set_by_pointer(d->st_mops, d->rd_mops_reads, mreads);
+ rrddim_set_by_pointer(d->st_mops, d->rd_mops_writes, mwrites);
rrdset_done(d->st_mops);
}
@@ -696,6 +798,8 @@ int do_proc_diskstats(int update_every, usec_t dt) {
, "disk.iotime"
, "Disk Total I/O Time"
, "milliseconds/s"
+ , "proc"
+ , "diskstats"
, 2022
, update_every
, RRDSET_TYPE_LINE
@@ -703,13 +807,13 @@ int do_proc_diskstats(int update_every, usec_t dt) {
rrdset_flag_set(d->st_iotime, RRDSET_FLAG_DETAIL);
- rrddim_add(d->st_iotime, "reads", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(d->st_iotime, "writes", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ d->rd_iotime_reads = rrddim_add(d->st_iotime, "reads", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ d->rd_iotime_writes = rrddim_add(d->st_iotime, "writes", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(d->st_iotime);
- last_readms = rrddim_set(d->st_iotime, "reads", readms);
- last_writems = rrddim_set(d->st_iotime, "writes", writems);
+ last_readms = rrddim_set_by_pointer(d->st_iotime, d->rd_iotime_reads, readms);
+ last_writems = rrddim_set_by_pointer(d->st_iotime, d->rd_iotime_writes, writems);
rrdset_done(d->st_iotime);
}
@@ -730,6 +834,8 @@ int do_proc_diskstats(int update_every, usec_t dt) {
, "disk.await"
, "Average Completed I/O Operation Time"
, "ms per operation"
+ , "proc"
+ , "diskstats"
, 2005
, update_every
, RRDSET_TYPE_LINE
@@ -737,13 +843,13 @@ int do_proc_diskstats(int update_every, usec_t dt) {
rrdset_flag_set(d->st_await, RRDSET_FLAG_DETAIL);
- rrddim_add(d->st_await, "reads", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
- rrddim_add(d->st_await, "writes", NULL, -1, 1, RRD_ALGORITHM_ABSOLUTE);
+ d->rd_await_reads = rrddim_add(d->st_await, "reads", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+ d->rd_await_writes = rrddim_add(d->st_await, "writes", NULL, -1, 1, RRD_ALGORITHM_ABSOLUTE);
}
else rrdset_next(d->st_await);
- rrddim_set(d->st_await, "reads", (reads - last_reads) ? (readms - last_readms) / (reads - last_reads) : 0);
- rrddim_set(d->st_await, "writes", (writes - last_writes) ? (writems - last_writems) / (writes - last_writes) : 0);
+ rrddim_set_by_pointer(d->st_await, d->rd_await_reads, (reads - last_reads) ? (readms - last_readms) / (reads - last_reads) : 0);
+ rrddim_set_by_pointer(d->st_await, d->rd_await_writes, (writes - last_writes) ? (writems - last_writems) / (writes - last_writes) : 0);
rrdset_done(d->st_await);
}
@@ -759,6 +865,8 @@ int do_proc_diskstats(int update_every, usec_t dt) {
, "disk.avgsz"
, "Average Completed I/O Operation Bandwidth"
, "kilobytes per operation"
+ , "proc"
+ , "diskstats"
, 2006
, update_every
, RRDSET_TYPE_AREA
@@ -766,13 +874,13 @@ int do_proc_diskstats(int update_every, usec_t dt) {
rrdset_flag_set(d->st_avgsz, RRDSET_FLAG_DETAIL);
- rrddim_add(d->st_avgsz, "reads", NULL, d->sector_size, 1024, RRD_ALGORITHM_ABSOLUTE);
- rrddim_add(d->st_avgsz, "writes", NULL, d->sector_size * -1, 1024, RRD_ALGORITHM_ABSOLUTE);
+ d->rd_avgsz_reads = rrddim_add(d->st_avgsz, "reads", NULL, d->sector_size, 1024, RRD_ALGORITHM_ABSOLUTE);
+ d->rd_avgsz_writes = rrddim_add(d->st_avgsz, "writes", NULL, d->sector_size * -1, 1024, RRD_ALGORITHM_ABSOLUTE);
}
else rrdset_next(d->st_avgsz);
- rrddim_set(d->st_avgsz, "reads", (reads - last_reads) ? (readsectors - last_readsectors) / (reads - last_reads) : 0);
- rrddim_set(d->st_avgsz, "writes", (writes - last_writes) ? (writesectors - last_writesectors) / (writes - last_writes) : 0);
+ rrddim_set_by_pointer(d->st_avgsz, d->rd_avgsz_reads, (reads - last_reads) ? (readsectors - last_readsectors) / (reads - last_reads) : 0);
+ rrddim_set_by_pointer(d->st_avgsz, d->rd_avgsz_writes, (writes - last_writes) ? (writesectors - last_writesectors) / (writes - last_writes) : 0);
rrdset_done(d->st_avgsz);
}
@@ -788,6 +896,8 @@ int do_proc_diskstats(int update_every, usec_t dt) {
, "disk.svctm"
, "Average Service Time"
, "ms per operation"
+ , "proc"
+ , "diskstats"
, 2007
, update_every
, RRDSET_TYPE_LINE
@@ -795,16 +905,52 @@ int do_proc_diskstats(int update_every, usec_t dt) {
rrdset_flag_set(d->st_svctm, RRDSET_FLAG_DETAIL);
- rrddim_add(d->st_svctm, "svctm", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+ d->rd_svctm_svctm = rrddim_add(d->st_svctm, "svctm", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
}
else rrdset_next(d->st_svctm);
- rrddim_set(d->st_svctm, "svctm", ((reads - last_reads) + (writes - last_writes)) ? (busy_ms - last_busy_ms) / ((reads - last_reads) + (writes - last_writes)) : 0);
+ rrddim_set_by_pointer(d->st_svctm, d->rd_svctm_svctm, ((reads - last_reads) + (writes - last_writes)) ? (busy_ms - last_busy_ms) / ((reads - last_reads) + (writes - last_writes)) : 0);
rrdset_done(d->st_svctm);
}
}
}
+
+ // ------------------------------------------------------------------------
+ // update the system total I/O
+
+ if(global_do_io == CONFIG_BOOLEAN_YES || (global_do_io == CONFIG_BOOLEAN_AUTO && (system_read_kb || system_write_kb))) {
+ static RRDSET *st_io = NULL;
+ static RRDDIM *rd_in = NULL, *rd_out = NULL;
+
+ if(unlikely(!st_io)) {
+ st_io = rrdset_create_localhost(
+ "system"
+ , "io"
+ , NULL
+ , "disk"
+ , NULL
+ , "Disk I/O"
+ , "kilobytes/s"
+ , "proc"
+ , "diskstats"
+ , 150
+ , update_every
+ , RRDSET_TYPE_AREA
+ );
+
+ rd_in = rrddim_add(st_io, "in", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_out = rrddim_add(st_io, "out", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ }
+ else rrdset_next(st_io);
+
+ rrddim_set_by_pointer(st_io, rd_in, system_read_kb);
+ rrddim_set_by_pointer(st_io, rd_out, system_write_kb);
+ rrdset_done(st_io);
+ }
+
+
+ // ------------------------------------------------------------------------
// cleanup removed disks
struct disk *d = disk_root, *last = NULL;
diff --git a/src/proc_interrupts.c b/src/proc_interrupts.c
index b9f3941d..867f39eb 100644
--- a/src/proc_interrupts.c
+++ b/src/proc_interrupts.c
@@ -154,6 +154,8 @@ int do_proc_interrupts(int update_every, usec_t dt) {
, NULL
, "System interrupts"
, "interrupts/s"
+ , "proc"
+ , "interrupts"
, 1000
, update_every
, RRDSET_TYPE_STACKED
@@ -217,6 +219,8 @@ int do_proc_interrupts(int update_every, usec_t dt) {
, "cpu.interrupts"
, title
, "interrupts/s"
+ , "proc"
+ , "interrupts"
, 1100 + c
, update_every
, RRDSET_TYPE_STACKED
diff --git a/src/proc_loadavg.c b/src/proc_loadavg.c
index 54fc545a..868f7d50 100644
--- a/src/proc_loadavg.c
+++ b/src/proc_loadavg.c
@@ -60,6 +60,8 @@ int do_proc_loadavg(int update_every, usec_t dt) {
, NULL
, "System Load Average"
, "load"
+ , "proc"
+ , "loadavg"
, 100
, (update_every < MIN_LOADAVG_UPDATE_EVERY) ? MIN_LOADAVG_UPDATE_EVERY : update_every
, RRDSET_TYPE_LINE
@@ -98,6 +100,8 @@ int do_proc_loadavg(int update_every, usec_t dt) {
, NULL
, "System Active Processes"
, "processes"
+ , "proc"
+ , "loadavg"
, 750
, update_every
, RRDSET_TYPE_LINE
diff --git a/src/proc_meminfo.c b/src/proc_meminfo.c
index 152a6366..085850c2 100644
--- a/src/proc_meminfo.c
+++ b/src/proc_meminfo.c
@@ -150,6 +150,8 @@ int do_proc_meminfo(int update_every, usec_t dt) {
, NULL
, "System RAM"
, "MB"
+ , "proc"
+ , "meminfo"
, 200
, update_every
, RRDSET_TYPE_STACKED
@@ -189,6 +191,8 @@ int do_proc_meminfo(int update_every, usec_t dt) {
, NULL
, "System Swap"
, "MB"
+ , "proc"
+ , "meminfo"
, 201
, update_every
, RRDSET_TYPE_STACKED
@@ -224,6 +228,8 @@ int do_proc_meminfo(int update_every, usec_t dt) {
, NULL
, "Corrupted Memory, detected by ECC"
, "MB"
+ , "proc"
+ , "meminfo"
, 9000
, update_every
, RRDSET_TYPE_LINE
@@ -255,6 +261,8 @@ int do_proc_meminfo(int update_every, usec_t dt) {
, NULL
, "Committed (Allocated) Memory"
, "MB"
+ , "proc"
+ , "meminfo"
, 5000
, update_every
, RRDSET_TYPE_AREA
@@ -286,6 +294,8 @@ int do_proc_meminfo(int update_every, usec_t dt) {
, NULL
, "Writeback Memory"
, "MB"
+ , "proc"
+ , "meminfo"
, 4000
, update_every
, RRDSET_TYPE_LINE
@@ -324,6 +334,8 @@ int do_proc_meminfo(int update_every, usec_t dt) {
, NULL
, "Memory Used by Kernel"
, "MB"
+ , "proc"
+ , "meminfo"
, 6000
, update_every
, RRDSET_TYPE_STACKED
@@ -361,6 +373,8 @@ int do_proc_meminfo(int update_every, usec_t dt) {
, NULL
, "Reclaimable Kernel Memory"
, "MB"
+ , "proc"
+ , "meminfo"
, 6500
, update_every
, RRDSET_TYPE_STACKED
diff --git a/src/proc_net_dev.c b/src/proc_net_dev.c
index 6e12fc5d..32bb5bab 100644
--- a/src/proc_net_dev.c
+++ b/src/proc_net_dev.c
@@ -9,6 +9,7 @@ static struct netdev {
size_t len;
// flags
+ int virtual;
int configured;
int enabled;
int updated;
@@ -428,8 +429,14 @@ int do_proc_net_dev(int update_every, usec_t dt) {
static procfile *ff = NULL;
static int enable_new_interfaces = -1;
static int do_bandwidth = -1, do_packets = -1, do_errors = -1, do_drops = -1, do_fifo = -1, do_compressed = -1, do_events = -1;
+ static char *path_to_sys_devices_virtual_net = NULL;
if(unlikely(enable_new_interfaces == -1)) {
+ char filename[FILENAME_MAX + 1];
+
+ snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/sys/devices/virtual/net/%s");
+ path_to_sys_devices_virtual_net = config_get("plugin:proc:/proc/net/dev", "path to get virtual interfaces", filename);
+
enable_new_interfaces = config_get_boolean_ondemand("plugin:proc:/proc/net/dev", "enable new interfaces detected at runtime", CONFIG_BOOLEAN_AUTO);
do_bandwidth = config_get_boolean_ondemand("plugin:proc:/proc/net/dev", "bandwidth for all interfaces", CONFIG_BOOLEAN_AUTO);
@@ -459,6 +466,9 @@ int do_proc_net_dev(int update_every, usec_t dt) {
netdev_found = 0;
+ kernel_uint_t system_rbytes = 0;
+ kernel_uint_t system_tbytes = 0;
+
size_t lines = procfile_lines(ff), l;
for(l = 2; l < lines ;l++) {
// require 17 words on each line
@@ -479,28 +489,42 @@ int do_proc_net_dev(int update_every, usec_t dt) {
if(d->enabled)
d->enabled = !simple_pattern_matches(disabled_list, d->name);
- char var_name[512 + 1];
- snprintfz(var_name, 512, "plugin:proc:/proc/net/dev:%s", d->name);
- d->enabled = config_get_boolean_ondemand(var_name, "enabled", d->enabled);
+ char buffer[FILENAME_MAX + 1];
+
+ snprintfz(buffer, FILENAME_MAX, path_to_sys_devices_virtual_net, d->name);
+ if(likely(access(buffer, R_OK) == 0)) {
+ d->virtual = 1;
+ }
+ else
+ d->virtual = 0;
+
+ snprintfz(buffer, FILENAME_MAX, "plugin:proc:/proc/net/dev:%s", d->name);
+ d->enabled = config_get_boolean_ondemand(buffer, "enabled", d->enabled);
+ d->virtual = config_get_boolean(buffer, "virtual", d->virtual);
if(d->enabled == CONFIG_BOOLEAN_NO)
continue;
- d->do_bandwidth = config_get_boolean_ondemand(var_name, "bandwidth", do_bandwidth);
- d->do_packets = config_get_boolean_ondemand(var_name, "packets", do_packets);
- d->do_errors = config_get_boolean_ondemand(var_name, "errors", do_errors);
- d->do_drops = config_get_boolean_ondemand(var_name, "drops", do_drops);
- d->do_fifo = config_get_boolean_ondemand(var_name, "fifo", do_fifo);
- d->do_compressed = config_get_boolean_ondemand(var_name, "compressed", do_compressed);
- d->do_events = config_get_boolean_ondemand(var_name, "events", do_events);
+ d->do_bandwidth = config_get_boolean_ondemand(buffer, "bandwidth", do_bandwidth);
+ d->do_packets = config_get_boolean_ondemand(buffer, "packets", do_packets);
+ d->do_errors = config_get_boolean_ondemand(buffer, "errors", do_errors);
+ d->do_drops = config_get_boolean_ondemand(buffer, "drops", do_drops);
+ d->do_fifo = config_get_boolean_ondemand(buffer, "fifo", do_fifo);
+ d->do_compressed = config_get_boolean_ondemand(buffer, "compressed", do_compressed);
+ d->do_events = config_get_boolean_ondemand(buffer, "events", do_events);
}
if(unlikely(!d->enabled))
continue;
- if(likely(d->do_bandwidth != CONFIG_BOOLEAN_NO)) {
+ if(likely(d->do_bandwidth != CONFIG_BOOLEAN_NO || !d->virtual)) {
d->rbytes = str2kernel_uint_t(procfile_lineword(ff, l, 1));
d->tbytes = str2kernel_uint_t(procfile_lineword(ff, l, 9));
+
+ if(likely(!d->virtual)) {
+ system_rbytes += d->rbytes;
+ system_tbytes += d->tbytes;
+ }
}
if(likely(d->do_packets != CONFIG_BOOLEAN_NO)) {
@@ -551,6 +575,8 @@ int do_proc_net_dev(int update_every, usec_t dt) {
, "net.net"
, "Bandwidth"
, "kilobits/s"
+ , "proc"
+ , "net/dev"
, d->priority
, update_every
, RRDSET_TYPE_AREA
@@ -590,6 +616,8 @@ int do_proc_net_dev(int update_every, usec_t dt) {
, "net.packets"
, "Packets"
, "packets/s"
+ , "proc"
+ , "net/dev"
, d->priority + 1
, update_every
, RRDSET_TYPE_LINE
@@ -633,6 +661,8 @@ int do_proc_net_dev(int update_every, usec_t dt) {
, "net.errors"
, "Interface Errors"
, "errors/s"
+ , "proc"
+ , "net/dev"
, d->priority + 2
, update_every
, RRDSET_TYPE_LINE
@@ -674,6 +704,8 @@ int do_proc_net_dev(int update_every, usec_t dt) {
, "net.drops"
, "Interface Drops"
, "drops/s"
+ , "proc"
+ , "net/dev"
, d->priority + 3
, update_every
, RRDSET_TYPE_LINE
@@ -715,6 +747,8 @@ int do_proc_net_dev(int update_every, usec_t dt) {
, "net.fifo"
, "Interface FIFO Buffer Errors"
, "errors"
+ , "proc"
+ , "net/dev"
, d->priority + 4
, update_every
, RRDSET_TYPE_LINE
@@ -756,6 +790,8 @@ int do_proc_net_dev(int update_every, usec_t dt) {
, "net.compressed"
, "Compressed Packets"
, "packets/s"
+ , "proc"
+ , "net/dev"
, d->priority + 5
, update_every
, RRDSET_TYPE_LINE
@@ -797,6 +833,8 @@ int do_proc_net_dev(int update_every, usec_t dt) {
, "net.events"
, "Network Interface Events"
, "events/s"
+ , "proc"
+ , "net/dev"
, d->priority + 6
, update_every
, RRDSET_TYPE_LINE
@@ -817,6 +855,39 @@ int do_proc_net_dev(int update_every, usec_t dt) {
}
}
+ if(do_bandwidth == CONFIG_BOOLEAN_YES || (do_bandwidth == CONFIG_BOOLEAN_AUTO && (system_rbytes || system_tbytes))) {
+ do_bandwidth = CONFIG_BOOLEAN_YES;
+ static RRDSET *st_system_net = NULL;
+ static RRDDIM *rd_in = NULL, *rd_out = NULL;
+
+ if(unlikely(!st_system_net)) {
+ st_system_net = rrdset_create_localhost(
+ "system"
+ , "net"
+ , NULL
+ , "network"
+ , NULL
+ , "Physical Network Interfaces Aggregated Bandwidth"
+ , "kilobits/s"
+ , "proc"
+ , "net/dev"
+ , 500
+ , update_every
+ , RRDSET_TYPE_AREA
+ );
+
+ rd_in = rrddim_add(st_system_net, "InOctets", "received", 8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
+ rd_out = rrddim_add(st_system_net, "OutOctets", "sent", -8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
+ }
+ else
+ rrdset_next(st_system_net);
+
+ rrddim_set_by_pointer(st_system_net, rd_in, (collected_number)system_rbytes);
+ rrddim_set_by_pointer(st_system_net, rd_out, (collected_number)system_tbytes);
+
+ rrdset_done(st_system_net);
+ }
+
netdev_cleanup();
return 0;
diff --git a/src/proc_net_ip_vs_stats.c b/src/proc_net_ip_vs_stats.c
index aa806b46..d76972f3 100644
--- a/src/proc_net_ip_vs_stats.c
+++ b/src/proc_net_ip_vs_stats.c
@@ -35,16 +35,27 @@ int do_proc_net_ip_vs_stats(int update_every, usec_t dt) {
InBytes = strtoull(procfile_lineword(ff, 2, 3), NULL, 16);
OutBytes = strtoull(procfile_lineword(ff, 2, 4), NULL, 16);
- RRDSET *st;
// --------------------------------------------------------------------
if(do_sockets) {
- st = rrdset_find_localhost(RRD_TYPE_NET_IPVS ".sockets");
- if(!st) {
- st = rrdset_create_localhost(RRD_TYPE_NET_IPVS, "sockets", NULL, RRD_TYPE_NET_IPVS, NULL
- , "IPVS New Connections", "connections/s", 3101, update_every
- , RRDSET_TYPE_LINE);
+ static RRDSET *st = NULL;
+
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_IPVS
+ , "sockets"
+ , NULL
+ , RRD_TYPE_NET_IPVS
+ , NULL
+ , "IPVS New Connections"
+ , "connections/s"
+ , "proc"
+ , "net/ip_vs_stats"
+ , 3101
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrddim_add(st, "connections", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
}
@@ -57,10 +68,22 @@ int do_proc_net_ip_vs_stats(int update_every, usec_t dt) {
// --------------------------------------------------------------------
if(do_packets) {
- st = rrdset_find_localhost(RRD_TYPE_NET_IPVS ".packets");
- if(!st) {
- st = rrdset_create_localhost(RRD_TYPE_NET_IPVS, "packets", NULL, RRD_TYPE_NET_IPVS, NULL, "IPVS Packets"
- , "packets/s", 3102, update_every, RRDSET_TYPE_LINE);
+ static RRDSET *st = NULL;
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_IPVS
+ , "packets"
+ , NULL
+ , RRD_TYPE_NET_IPVS
+ , NULL
+ , "IPVS Packets"
+ , "packets/s"
+ , "proc"
+ , "net/ip_vs_stats"
+ , 3102
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrddim_add(st, "received", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
rrddim_add(st, "sent", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -75,10 +98,22 @@ int do_proc_net_ip_vs_stats(int update_every, usec_t dt) {
// --------------------------------------------------------------------
if(do_bandwidth) {
- st = rrdset_find_localhost(RRD_TYPE_NET_IPVS ".net");
- if(!st) {
- st = rrdset_create_localhost(RRD_TYPE_NET_IPVS, "net", NULL, RRD_TYPE_NET_IPVS, NULL, "IPVS Bandwidth"
- , "kilobits/s", 3100, update_every, RRDSET_TYPE_AREA);
+ static RRDSET *st = NULL;
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_IPVS
+ , "net"
+ , NULL
+ , RRD_TYPE_NET_IPVS
+ , NULL
+ , "IPVS Bandwidth"
+ , "kilobits/s"
+ , "proc"
+ , "net/ip_vs_stats"
+ , 3100
+ , update_every
+ , RRDSET_TYPE_AREA
+ );
rrddim_add(st, "received", NULL, 8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
rrddim_add(st, "sent", NULL, -8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
diff --git a/src/proc_net_netstat.c b/src/proc_net_netstat.c
index e01b81d2..dd070e4c 100644
--- a/src/proc_net_netstat.c
+++ b/src/proc_net_netstat.c
@@ -22,7 +22,9 @@ int do_proc_net_netstat(int update_every, usec_t dt) {
(void)dt;
static int do_bandwidth = -1, do_inerrors = -1, do_mcast = -1, do_bcast = -1, do_mcast_p = -1, do_bcast_p = -1, do_ecn = -1, \
- do_tcpext_reorder = -1, do_tcpext_syscookies = -1, do_tcpext_ofo = -1, do_tcpext_connaborts = -1, do_tcpext_memory = -1;
+ do_tcpext_reorder = -1, do_tcpext_syscookies = -1, do_tcpext_ofo = -1, do_tcpext_connaborts = -1, do_tcpext_memory = -1,
+ do_tcpext_listen = -1;
+
static uint32_t hash_ipext = 0, hash_tcpext = 0;
static procfile *ff = NULL;
@@ -93,6 +95,10 @@ int do_proc_net_netstat(int update_every, usec_t dt) {
static unsigned long long tcpext_TCPAbortOnLinger = 0; // connections aborted after user close in linger timeout
static unsigned long long tcpext_TCPAbortFailed = 0; // times unable to send RST due to no memory
+ // https://perfchron.com/2015/12/26/investigating-linux-network-issues-with-netstat-and-nstat/
+ static unsigned long long tcpext_ListenOverflows = 0; // times the listen queue of a socket overflowed
+ static unsigned long long tcpext_ListenDrops = 0; // SYNs to LISTEN sockets ignored
+
// IPv4 TCP memory pressures
static unsigned long long tcpext_TCPMemoryPressures = 0;
@@ -116,6 +122,7 @@ int do_proc_net_netstat(int update_every, usec_t dt) {
do_tcpext_ofo = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "TCP out-of-order queue", CONFIG_BOOLEAN_AUTO);
do_tcpext_connaborts = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "TCP connection aborts", CONFIG_BOOLEAN_AUTO);
do_tcpext_memory = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "TCP memory pressures", CONFIG_BOOLEAN_AUTO);
+ do_tcpext_listen = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "TCP listen issues", CONFIG_BOOLEAN_AUTO);
arl_ipext = arl_create("netstat/ipext", NULL, 60);
arl_tcpext = arl_create("netstat/tcpext", NULL, 60);
@@ -197,6 +204,11 @@ int do_proc_net_netstat(int update_every, usec_t dt) {
arl_expect(arl_tcpext, "TCPMemoryPressures", &tcpext_TCPMemoryPressures);
}
+ if(do_tcpext_listen != CONFIG_BOOLEAN_NO) {
+ arl_expect(arl_tcpext, "ListenOverflows", &tcpext_ListenOverflows);
+ arl_expect(arl_tcpext, "ListenDrops", &tcpext_ListenDrops);
+ }
+
// shared metrics
arl_expect(arl_tcpext, "TCPSynRetrans", &tcpext_TCPSynRetrans);
}
@@ -248,7 +260,9 @@ int do_proc_net_netstat(int update_every, usec_t dt) {
, NULL
, "IPv4 Bandwidth"
, "kilobits/s"
- , 500
+ , "proc"
+ , "net/netstat"
+ , 501
, update_every
, RRDSET_TYPE_AREA
);
@@ -281,6 +295,8 @@ int do_proc_net_netstat(int update_every, usec_t dt) {
, NULL
, "IPv4 Input Errors"
, "packets/s"
+ , "proc"
+ , "net/netstat"
, 4000
, update_every
, RRDSET_TYPE_LINE
@@ -318,6 +334,8 @@ int do_proc_net_netstat(int update_every, usec_t dt) {
, NULL
, "IPv4 Multicast Bandwidth"
, "kilobits/s"
+ , "proc"
+ , "net/netstat"
, 9000
, update_every
, RRDSET_TYPE_AREA
@@ -354,6 +372,8 @@ int do_proc_net_netstat(int update_every, usec_t dt) {
, NULL
, "IPv4 Broadcast Bandwidth"
, "kilobits/s"
+ , "proc"
+ , "net/netstat"
, 8000
, update_every
, RRDSET_TYPE_AREA
@@ -390,6 +410,8 @@ int do_proc_net_netstat(int update_every, usec_t dt) {
, NULL
, "IPv4 Multicast Packets"
, "packets/s"
+ , "proc"
+ , "net/netstat"
, 8600
, update_every
, RRDSET_TYPE_LINE
@@ -425,6 +447,8 @@ int do_proc_net_netstat(int update_every, usec_t dt) {
, NULL
, "IPv4 Broadcast Packets"
, "packets/s"
+ , "proc"
+ , "net/netstat"
, 8500
, update_every
, RRDSET_TYPE_LINE
@@ -461,6 +485,8 @@ int do_proc_net_netstat(int update_every, usec_t dt) {
, NULL
, "IPv4 ECN Statistics"
, "packets/s"
+ , "proc"
+ , "net/netstat"
, 8700
, update_every
, RRDSET_TYPE_LINE
@@ -511,6 +537,8 @@ int do_proc_net_netstat(int update_every, usec_t dt) {
, NULL
, "TCP Memory Pressures"
, "events/s"
+ , "proc"
+ , "net/netstat"
, 3000
, update_every
, RRDSET_TYPE_LINE
@@ -543,6 +571,8 @@ int do_proc_net_netstat(int update_every, usec_t dt) {
, NULL
, "TCP Connection Aborts"
, "connections/s"
+ , "proc"
+ , "net/netstat"
, 3010
, update_every
, RRDSET_TYPE_LINE
@@ -585,6 +615,8 @@ int do_proc_net_netstat(int update_every, usec_t dt) {
, NULL
, "TCP Reordered Packets by Detection Method"
, "packets/s"
+ , "proc"
+ , "net/netstat"
, 3020
, update_every
, RRDSET_TYPE_LINE
@@ -624,6 +656,8 @@ int do_proc_net_netstat(int update_every, usec_t dt) {
, NULL
, "TCP Out-Of-Order Queue"
, "packets/s"
+ , "proc"
+ , "net/netstat"
, 3050
, update_every
, RRDSET_TYPE_LINE
@@ -663,6 +697,8 @@ int do_proc_net_netstat(int update_every, usec_t dt) {
, NULL
, "TCP SYN Cookies"
, "packets/s"
+ , "proc"
+ , "net/netstat"
, 3100
, update_every
, RRDSET_TYPE_LINE
@@ -682,6 +718,42 @@ int do_proc_net_netstat(int update_every, usec_t dt) {
rrdset_done(st_syncookies);
}
+ // --------------------------------------------------------------------
+
+ if(do_tcpext_listen == CONFIG_BOOLEAN_YES || (do_tcpext_listen == CONFIG_BOOLEAN_AUTO && (tcpext_ListenOverflows || tcpext_ListenDrops))) {
+ do_tcpext_listen = CONFIG_BOOLEAN_YES;
+
+ static RRDSET *st_listen = NULL;
+ static RRDDIM *rd_overflows = NULL, *rd_drops = NULL;
+
+ if(unlikely(!st_listen)) {
+
+ st_listen = rrdset_create_localhost(
+ "ipv4"
+ , "tcplistenissues"
+ , NULL
+ , "tcp"
+ , NULL
+ , "TCP Listen Socket Issues"
+ , "packets/s"
+ , "proc"
+ , "net/netstat"
+ , 3015
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rd_overflows = rrddim_add(st_listen, "ListenOverflows", "overflows", 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_drops = rrddim_add(st_listen, "ListenDrops", "drops", 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ }
+ else
+ rrdset_next(st_listen);
+
+ rrddim_set_by_pointer(st_listen, rd_overflows, tcpext_ListenOverflows);
+ rrddim_set_by_pointer(st_listen, rd_drops, tcpext_ListenDrops);
+
+ rrdset_done(st_listen);
+ }
}
}
diff --git a/src/proc_net_rpc_nfs.c b/src/proc_net_rpc_nfs.c
index 0df91963..126216e0 100644
--- a/src/proc_net_rpc_nfs.c
+++ b/src/proc_net_rpc_nfs.c
@@ -4,127 +4,133 @@ struct nfs_procs {
char name[30];
unsigned long long value;
int present;
+ RRDDIM *rd;
};
struct nfs_procs nfs_proc2_values[] = {
- { "null", 0ULL, 0 },
- { "getattr", 0ULL, 0 },
- { "setattr", 0ULL, 0 },
- { "root", 0ULL, 0 },
- { "lookup", 0ULL, 0 },
- { "readlink", 0ULL, 0 },
- { "read", 0ULL, 0 },
- { "wrcache", 0ULL, 0 },
- { "write", 0ULL, 0 },
- { "create", 0ULL, 0 },
- { "remove", 0ULL, 0 },
- { "rename", 0ULL, 0 },
- { "link", 0ULL, 0 },
- { "symlink", 0ULL, 0 },
- { "mkdir", 0ULL, 0 },
- { "rmdir", 0ULL, 0 },
- { "readdir", 0ULL, 0 },
- { "fsstat", 0ULL, 0 },
-
- /* termination */
- { "", 0ULL, 0 }
+ { "null" , 0ULL, 0, NULL}
+ , {"getattr" , 0ULL, 0, NULL}
+ , {"setattr" , 0ULL, 0, NULL}
+ , {"root" , 0ULL, 0, NULL}
+ , {"lookup" , 0ULL, 0, NULL}
+ , {"readlink", 0ULL, 0, NULL}
+ , {"read" , 0ULL, 0, NULL}
+ , {"wrcache" , 0ULL, 0, NULL}
+ , {"write" , 0ULL, 0, NULL}
+ , {"create" , 0ULL, 0, NULL}
+ , {"remove" , 0ULL, 0, NULL}
+ , {"rename" , 0ULL, 0, NULL}
+ , {"link" , 0ULL, 0, NULL}
+ , {"symlink" , 0ULL, 0, NULL}
+ , {"mkdir" , 0ULL, 0, NULL}
+ , {"rmdir" , 0ULL, 0, NULL}
+ , {"readdir" , 0ULL, 0, NULL}
+ , {"fsstat" , 0ULL, 0, NULL}
+ ,
+
+ /* termination */
+ { "" , 0ULL, 0, NULL}
};
struct nfs_procs nfs_proc3_values[] = {
- { "null", 0ULL, 0 },
- { "getattr", 0ULL, 0 },
- { "setattr", 0ULL, 0 },
- { "lookup", 0ULL, 0 },
- { "access", 0ULL, 0 },
- { "readlink", 0ULL, 0 },
- { "read", 0ULL, 0 },
- { "write", 0ULL, 0 },
- { "create", 0ULL, 0 },
- { "mkdir", 0ULL, 0 },
- { "symlink", 0ULL, 0 },
- { "mknod", 0ULL, 0 },
- { "remove", 0ULL, 0 },
- { "rmdir", 0ULL, 0 },
- { "rename", 0ULL, 0 },
- { "link", 0ULL, 0 },
- { "readdir", 0ULL, 0 },
- { "readdirplus", 0ULL, 0 },
- { "fsstat", 0ULL, 0 },
- { "fsinfo", 0ULL, 0 },
- { "pathconf", 0ULL, 0 },
- { "commit", 0ULL, 0 },
-
- /* termination */
- { "", 0ULL, 0 }
+ { "null" , 0ULL, 0, NULL}
+ , {"getattr" , 0ULL, 0, NULL}
+ , {"setattr" , 0ULL, 0, NULL}
+ , {"lookup" , 0ULL, 0, NULL}
+ , {"access" , 0ULL, 0, NULL}
+ , {"readlink" , 0ULL, 0, NULL}
+ , {"read" , 0ULL, 0, NULL}
+ , {"write" , 0ULL, 0, NULL}
+ , {"create" , 0ULL, 0, NULL}
+ , {"mkdir" , 0ULL, 0, NULL}
+ , {"symlink" , 0ULL, 0, NULL}
+ , {"mknod" , 0ULL, 0, NULL}
+ , {"remove" , 0ULL, 0, NULL}
+ , {"rmdir" , 0ULL, 0, NULL}
+ , {"rename" , 0ULL, 0, NULL}
+ , {"link" , 0ULL, 0, NULL}
+ , {"readdir" , 0ULL, 0, NULL}
+ , {"readdirplus", 0ULL, 0, NULL}
+ , {"fsstat" , 0ULL, 0, NULL}
+ , {"fsinfo" , 0ULL, 0, NULL}
+ , {"pathconf" , 0ULL, 0, NULL}
+ , {"commit" , 0ULL, 0, NULL}
+ ,
+
+ /* termination */
+ { "" , 0ULL, 0, NULL}
};
struct nfs_procs nfs_proc4_values[] = {
- { "null", 0ULL, 0 },
- { "read", 0ULL, 0 },
- { "write", 0ULL, 0 },
- { "commit", 0ULL, 0 },
- { "open", 0ULL, 0 },
- { "open_conf", 0ULL, 0 },
- { "open_noat", 0ULL, 0 },
- { "open_dgrd", 0ULL, 0 },
- { "close", 0ULL, 0 },
- { "setattr", 0ULL, 0 },
- { "fsinfo", 0ULL, 0 },
- { "renew", 0ULL, 0 },
- { "setclntid", 0ULL, 0 },
- { "confirm", 0ULL, 0 },
- { "lock", 0ULL, 0 },
- { "lockt", 0ULL, 0 },
- { "locku", 0ULL, 0 },
- { "access", 0ULL, 0 },
- { "getattr", 0ULL, 0 },
- { "lookup", 0ULL, 0 },
- { "lookup_root", 0ULL, 0 },
- { "remove", 0ULL, 0 },
- { "rename", 0ULL, 0 },
- { "link", 0ULL, 0 },
- { "symlink", 0ULL, 0 },
- { "create", 0ULL, 0 },
- { "pathconf", 0ULL, 0 },
- { "statfs", 0ULL, 0 },
- { "readlink", 0ULL, 0 },
- { "readdir", 0ULL, 0 },
- { "server_caps", 0ULL, 0 },
- { "delegreturn", 0ULL, 0 },
- { "getacl", 0ULL, 0 },
- { "setacl", 0ULL, 0 },
- { "fs_locations", 0ULL, 0 },
- { "rel_lkowner", 0ULL, 0 },
- { "secinfo", 0ULL, 0 },
- { "fsid_present", 0ULL, 0 },
-
- /* nfsv4.1 client ops */
- { "exchange_id", 0ULL, 0 },
- { "create_session", 0ULL, 0 },
- { "destroy_session", 0ULL, 0 },
- { "sequence", 0ULL, 0 },
- { "get_lease_time", 0ULL, 0 },
- { "reclaim_comp", 0ULL, 0 },
- { "layoutget", 0ULL, 0 },
- { "getdevinfo", 0ULL, 0 },
- { "layoutcommit", 0ULL, 0 },
- { "layoutreturn", 0ULL, 0 },
- { "secinfo_no", 0ULL, 0 },
- { "test_stateid", 0ULL, 0 },
- { "free_stateid", 0ULL, 0 },
- { "getdevicelist", 0ULL, 0 },
- { "bind_conn_to_ses", 0ULL, 0 },
- { "destroy_clientid", 0ULL, 0 },
-
- /* nfsv4.2 client ops */
- { "seek", 0ULL, 0 },
- { "allocate", 0ULL, 0 },
- { "deallocate", 0ULL, 0 },
- { "layoutstats", 0ULL, 0 },
- { "clone", 0ULL, 0 },
-
- /* termination */
- { "", 0ULL, 0 }
+ { "null" , 0ULL, 0, NULL}
+ , {"read" , 0ULL, 0, NULL}
+ , {"write" , 0ULL, 0, NULL}
+ , {"commit" , 0ULL, 0, NULL}
+ , {"open" , 0ULL, 0, NULL}
+ , {"open_conf" , 0ULL, 0, NULL}
+ , {"open_noat" , 0ULL, 0, NULL}
+ , {"open_dgrd" , 0ULL, 0, NULL}
+ , {"close" , 0ULL, 0, NULL}
+ , {"setattr" , 0ULL, 0, NULL}
+ , {"fsinfo" , 0ULL, 0, NULL}
+ , {"renew" , 0ULL, 0, NULL}
+ , {"setclntid" , 0ULL, 0, NULL}
+ , {"confirm" , 0ULL, 0, NULL}
+ , {"lock" , 0ULL, 0, NULL}
+ , {"lockt" , 0ULL, 0, NULL}
+ , {"locku" , 0ULL, 0, NULL}
+ , {"access" , 0ULL, 0, NULL}
+ , {"getattr" , 0ULL, 0, NULL}
+ , {"lookup" , 0ULL, 0, NULL}
+ , {"lookup_root" , 0ULL, 0, NULL}
+ , {"remove" , 0ULL, 0, NULL}
+ , {"rename" , 0ULL, 0, NULL}
+ , {"link" , 0ULL, 0, NULL}
+ , {"symlink" , 0ULL, 0, NULL}
+ , {"create" , 0ULL, 0, NULL}
+ , {"pathconf" , 0ULL, 0, NULL}
+ , {"statfs" , 0ULL, 0, NULL}
+ , {"readlink" , 0ULL, 0, NULL}
+ , {"readdir" , 0ULL, 0, NULL}
+ , {"server_caps" , 0ULL, 0, NULL}
+ , {"delegreturn" , 0ULL, 0, NULL}
+ , {"getacl" , 0ULL, 0, NULL}
+ , {"setacl" , 0ULL, 0, NULL}
+ , {"fs_locations" , 0ULL, 0, NULL}
+ , {"rel_lkowner" , 0ULL, 0, NULL}
+ , {"secinfo" , 0ULL, 0, NULL}
+ , {"fsid_present" , 0ULL, 0, NULL}
+ ,
+
+ /* nfsv4.1 client ops */
+ { "exchange_id" , 0ULL, 0, NULL}
+ , {"create_session" , 0ULL, 0, NULL}
+ , {"destroy_session" , 0ULL, 0, NULL}
+ , {"sequence" , 0ULL, 0, NULL}
+ , {"get_lease_time" , 0ULL, 0, NULL}
+ , {"reclaim_comp" , 0ULL, 0, NULL}
+ , {"layoutget" , 0ULL, 0, NULL}
+ , {"getdevinfo" , 0ULL, 0, NULL}
+ , {"layoutcommit" , 0ULL, 0, NULL}
+ , {"layoutreturn" , 0ULL, 0, NULL}
+ , {"secinfo_no" , 0ULL, 0, NULL}
+ , {"test_stateid" , 0ULL, 0, NULL}
+ , {"free_stateid" , 0ULL, 0, NULL}
+ , {"getdevicelist" , 0ULL, 0, NULL}
+ , {"bind_conn_to_ses", 0ULL, 0, NULL}
+ , {"destroy_clientid", 0ULL, 0, NULL}
+ ,
+
+ /* nfsv4.2 client ops */
+ { "seek" , 0ULL, 0, NULL}
+ , {"allocate" , 0ULL, 0, NULL}
+ , {"deallocate" , 0ULL, 0, NULL}
+ , {"layoutstats" , 0ULL, 0, NULL}
+ , {"clone" , 0ULL, 0, NULL}
+ ,
+
+ /* termination */
+ { "" , 0ULL, 0, NULL}
};
int do_proc_net_rpc_nfs(int update_every, usec_t dt) {
@@ -264,68 +270,111 @@ int do_proc_net_rpc_nfs(int update_every, usec_t dt) {
}
}
- RRDSET *st;
-
// --------------------------------------------------------------------
if(do_net == 2) {
- st = rrdset_find_bytype_localhost("nfs", "net");
- if(!st) {
- st = rrdset_create_localhost("nfs", "net", NULL, "network", NULL, "NFS Client Network", "operations/s", 5007
- , update_every, RRDSET_TYPE_STACKED);
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_udp = NULL,
+ *rd_tcp = NULL;
+
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "nfs"
+ , "net"
+ , NULL
+ , "network"
+ , NULL
+ , "NFS Client Network"
+ , "operations/s"
+ , "proc"
+ , "net/rpc/nfs"
+ , 5007
+ , update_every
+ , RRDSET_TYPE_STACKED
+ );
+
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
- rrddim_add(st, "udp", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "tcp", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_udp = rrddim_add(st, "udp", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_tcp = rrddim_add(st, "tcp", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
// ignore net_count, net_tcp_connections
- if(net_count) {};
- if(net_tcp_connections) {};
+ (void)net_count;
+ (void)net_tcp_connections;
- rrddim_set(st, "udp", net_udp_count);
- rrddim_set(st, "tcp", net_tcp_count);
+ rrddim_set_by_pointer(st, rd_udp, net_udp_count);
+ rrddim_set_by_pointer(st, rd_tcp, net_tcp_count);
rrdset_done(st);
}
// --------------------------------------------------------------------
if(do_rpc == 2) {
- st = rrdset_find_bytype_localhost("nfs", "rpc");
- if(!st) {
- st = rrdset_create_localhost("nfs", "rpc", NULL, "rpc", NULL, "NFS Client Remote Procedure Calls Statistics"
- , "calls/s", 5008, update_every, RRDSET_TYPE_LINE);
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_calls = NULL,
+ *rd_retransmits = NULL,
+ *rd_auth_refresh = NULL;
+
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "nfs"
+ , "rpc"
+ , NULL
+ , "rpc"
+ , NULL
+ , "NFS Client Remote Procedure Calls Statistics"
+ , "calls/s"
+ , "proc"
+ , "net/rpc/nfs"
+ , 5008
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
- rrddim_add(st, "calls", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "retransmits", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "auth_refresh", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_calls = rrddim_add(st, "calls", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_retransmits = rrddim_add(st, "retransmits", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_auth_refresh = rrddim_add(st, "auth_refresh", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "calls", rpc_calls);
- rrddim_set(st, "retransmits", rpc_retransmits);
- rrddim_set(st, "auth_refresh", rpc_auth_refresh);
+ rrddim_set_by_pointer(st, rd_calls, rpc_calls);
+ rrddim_set_by_pointer(st, rd_retransmits, rpc_retransmits);
+ rrddim_set_by_pointer(st, rd_auth_refresh, rpc_auth_refresh);
rrdset_done(st);
}
// --------------------------------------------------------------------
if(do_proc2 == 2) {
- unsigned int i;
- st = rrdset_find_bytype_localhost("nfs", "proc2");
- if(!st) {
- st = rrdset_create_localhost("nfs", "proc2", NULL, "nfsv2rpc", NULL, "NFS v2 Client Remote Procedure Calls"
- , "calls/s", 5009, update_every, RRDSET_TYPE_STACKED);
-
- for(i = 0; nfs_proc2_values[i].present ; i++)
- rrddim_add(st, nfs_proc2_values[i].name, NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ static RRDSET *st = NULL;
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "nfs"
+ , "proc2"
+ , NULL
+ , "nfsv2rpc"
+ , NULL
+ , "NFS v2 Client Remote Procedure Calls"
+ , "calls/s"
+ , "proc"
+ , "net/rpc/nfs"
+ , 5009
+ , update_every
+ , RRDSET_TYPE_STACKED
+ );
}
else rrdset_next(st);
- for(i = 0; nfs_proc2_values[i].present ; i++)
- rrddim_set(st, nfs_proc2_values[i].name, nfs_proc2_values[i].value);
+ size_t i;
+ for(i = 0; nfs_proc2_values[i].present ; i++) {
+ if(unlikely(!nfs_proc2_values[i].rd))
+ nfs_proc2_values[i].rd = rrddim_add(st, nfs_proc2_values[i].name, NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+
+ rrddim_set_by_pointer(st, nfs_proc2_values[i].rd, nfs_proc2_values[i].value);
+ }
rrdset_done(st);
}
@@ -333,19 +382,32 @@ int do_proc_net_rpc_nfs(int update_every, usec_t dt) {
// --------------------------------------------------------------------
if(do_proc3 == 2) {
- unsigned int i;
- st = rrdset_find_bytype_localhost("nfs", "proc3");
- if(!st) {
- st = rrdset_create_localhost("nfs", "proc3", NULL, "nfsv3rpc", NULL, "NFS v3 Client Remote Procedure Calls"
- , "calls/s", 5010, update_every, RRDSET_TYPE_STACKED);
-
- for(i = 0; nfs_proc3_values[i].present ; i++)
- rrddim_add(st, nfs_proc3_values[i].name, NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ static RRDSET *st = NULL;
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "nfs"
+ , "proc3"
+ , NULL
+ , "nfsv3rpc"
+ , NULL
+ , "NFS v3 Client Remote Procedure Calls"
+ , "calls/s"
+ , "proc"
+ , "net/rpc/nfs"
+ , 5010
+ , update_every
+ , RRDSET_TYPE_STACKED
+ );
}
else rrdset_next(st);
- for(i = 0; nfs_proc3_values[i].present ; i++)
- rrddim_set(st, nfs_proc3_values[i].name, nfs_proc3_values[i].value);
+ size_t i;
+ for(i = 0; nfs_proc3_values[i].present ; i++) {
+ if(unlikely(!nfs_proc3_values[i].rd))
+ nfs_proc3_values[i].rd = rrddim_add(st, nfs_proc3_values[i].name, NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+
+ rrddim_set_by_pointer(st, nfs_proc3_values[i].rd, nfs_proc3_values[i].value);
+ }
rrdset_done(st);
}
@@ -353,19 +415,32 @@ int do_proc_net_rpc_nfs(int update_every, usec_t dt) {
// --------------------------------------------------------------------
if(do_proc4 == 2) {
- unsigned int i;
- st = rrdset_find_bytype_localhost("nfs", "proc4");
- if(!st) {
- st = rrdset_create_localhost("nfs", "proc4", NULL, "nfsv4rpc", NULL, "NFS v4 Client Remote Procedure Calls"
- , "calls/s", 5011, update_every, RRDSET_TYPE_STACKED);
-
- for(i = 0; nfs_proc4_values[i].present ; i++)
- rrddim_add(st, nfs_proc4_values[i].name, NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ static RRDSET *st = NULL;
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "nfs"
+ , "proc4"
+ , NULL
+ , "nfsv4rpc"
+ , NULL
+ , "NFS v4 Client Remote Procedure Calls"
+ , "calls/s"
+ , "proc"
+ , "net/rpc/nfs"
+ , 5011
+ , update_every
+ , RRDSET_TYPE_STACKED
+ );
}
else rrdset_next(st);
- for(i = 0; nfs_proc4_values[i].present ; i++)
- rrddim_set(st, nfs_proc4_values[i].name, nfs_proc4_values[i].value);
+ size_t i;
+ for(i = 0; nfs_proc4_values[i].present ; i++) {
+ if(unlikely(!nfs_proc4_values[i].rd))
+ nfs_proc4_values[i].rd = rrddim_add(st, nfs_proc4_values[i].name, NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+
+ rrddim_set_by_pointer(st, nfs_proc4_values[i].rd, nfs_proc4_values[i].value);
+ }
rrdset_done(st);
}
diff --git a/src/proc_net_rpc_nfsd.c b/src/proc_net_rpc_nfsd.c
index b0ed58d1..f0c9a20c 100644
--- a/src/proc_net_rpc_nfsd.c
+++ b/src/proc_net_rpc_nfsd.c
@@ -4,208 +4,217 @@ struct nfsd_procs {
char name[30];
unsigned long long value;
int present;
+ RRDDIM *rd;
};
struct nfsd_procs nfsd_proc2_values[] = {
- { "null", 0ULL, 0 },
- { "getattr", 0ULL, 0 },
- { "setattr", 0ULL, 0 },
- { "root", 0ULL, 0 },
- { "lookup", 0ULL, 0 },
- { "readlink", 0ULL, 0 },
- { "read", 0ULL, 0 },
- { "wrcache", 0ULL, 0 },
- { "write", 0ULL, 0 },
- { "create", 0ULL, 0 },
- { "remove", 0ULL, 0 },
- { "rename", 0ULL, 0 },
- { "link", 0ULL, 0 },
- { "symlink", 0ULL, 0 },
- { "mkdir", 0ULL, 0 },
- { "rmdir", 0ULL, 0 },
- { "readdir", 0ULL, 0 },
- { "fsstat", 0ULL, 0 },
-
- /* termination */
- { "", 0ULL, 0 }
+ { "null" , 0ULL, 0, NULL}
+ , {"getattr" , 0ULL, 0, NULL}
+ , {"setattr" , 0ULL, 0, NULL}
+ , {"root" , 0ULL, 0, NULL}
+ , {"lookup" , 0ULL, 0, NULL}
+ , {"readlink", 0ULL, 0, NULL}
+ , {"read" , 0ULL, 0, NULL}
+ , {"wrcache" , 0ULL, 0, NULL}
+ , {"write" , 0ULL, 0, NULL}
+ , {"create" , 0ULL, 0, NULL}
+ , {"remove" , 0ULL, 0, NULL}
+ , {"rename" , 0ULL, 0, NULL}
+ , {"link" , 0ULL, 0, NULL}
+ , {"symlink" , 0ULL, 0, NULL}
+ , {"mkdir" , 0ULL, 0, NULL}
+ , {"rmdir" , 0ULL, 0, NULL}
+ , {"readdir" , 0ULL, 0, NULL}
+ , {"fsstat" , 0ULL, 0, NULL}
+ ,
+
+ /* termination */
+ { "" , 0ULL, 0, NULL}
};
struct nfsd_procs nfsd_proc3_values[] = {
- { "null", 0ULL, 0 },
- { "getattr", 0ULL, 0 },
- { "setattr", 0ULL, 0 },
- { "lookup", 0ULL, 0 },
- { "access", 0ULL, 0 },
- { "readlink", 0ULL, 0 },
- { "read", 0ULL, 0 },
- { "write", 0ULL, 0 },
- { "create", 0ULL, 0 },
- { "mkdir", 0ULL, 0 },
- { "symlink", 0ULL, 0 },
- { "mknod", 0ULL, 0 },
- { "remove", 0ULL, 0 },
- { "rmdir", 0ULL, 0 },
- { "rename", 0ULL, 0 },
- { "link", 0ULL, 0 },
- { "readdir", 0ULL, 0 },
- { "readdirplus", 0ULL, 0 },
- { "fsstat", 0ULL, 0 },
- { "fsinfo", 0ULL, 0 },
- { "pathconf", 0ULL, 0 },
- { "commit", 0ULL, 0 },
-
- /* termination */
- { "", 0ULL, 0 }
+ { "null" , 0ULL, 0, NULL}
+ , {"getattr" , 0ULL, 0, NULL}
+ , {"setattr" , 0ULL, 0, NULL}
+ , {"lookup" , 0ULL, 0, NULL}
+ , {"access" , 0ULL, 0, NULL}
+ , {"readlink" , 0ULL, 0, NULL}
+ , {"read" , 0ULL, 0, NULL}
+ , {"write" , 0ULL, 0, NULL}
+ , {"create" , 0ULL, 0, NULL}
+ , {"mkdir" , 0ULL, 0, NULL}
+ , {"symlink" , 0ULL, 0, NULL}
+ , {"mknod" , 0ULL, 0, NULL}
+ , {"remove" , 0ULL, 0, NULL}
+ , {"rmdir" , 0ULL, 0, NULL}
+ , {"rename" , 0ULL, 0, NULL}
+ , {"link" , 0ULL, 0, NULL}
+ , {"readdir" , 0ULL, 0, NULL}
+ , {"readdirplus", 0ULL, 0, NULL}
+ , {"fsstat" , 0ULL, 0, NULL}
+ , {"fsinfo" , 0ULL, 0, NULL}
+ , {"pathconf" , 0ULL, 0, NULL}
+ , {"commit" , 0ULL, 0, NULL}
+ ,
+
+ /* termination */
+ { "" , 0ULL, 0, NULL}
};
struct nfsd_procs nfsd_proc4_values[] = {
- { "null", 0ULL, 0 },
- { "read", 0ULL, 0 },
- { "write", 0ULL, 0 },
- { "commit", 0ULL, 0 },
- { "open", 0ULL, 0 },
- { "open_conf", 0ULL, 0 },
- { "open_noat", 0ULL, 0 },
- { "open_dgrd", 0ULL, 0 },
- { "close", 0ULL, 0 },
- { "setattr", 0ULL, 0 },
- { "fsinfo", 0ULL, 0 },
- { "renew", 0ULL, 0 },
- { "setclntid", 0ULL, 0 },
- { "confirm", 0ULL, 0 },
- { "lock", 0ULL, 0 },
- { "lockt", 0ULL, 0 },
- { "locku", 0ULL, 0 },
- { "access", 0ULL, 0 },
- { "getattr", 0ULL, 0 },
- { "lookup", 0ULL, 0 },
- { "lookup_root", 0ULL, 0 },
- { "remove", 0ULL, 0 },
- { "rename", 0ULL, 0 },
- { "link", 0ULL, 0 },
- { "symlink", 0ULL, 0 },
- { "create", 0ULL, 0 },
- { "pathconf", 0ULL, 0 },
- { "statfs", 0ULL, 0 },
- { "readlink", 0ULL, 0 },
- { "readdir", 0ULL, 0 },
- { "server_caps", 0ULL, 0 },
- { "delegreturn", 0ULL, 0 },
- { "getacl", 0ULL, 0 },
- { "setacl", 0ULL, 0 },
- { "fs_locations", 0ULL, 0 },
- { "rel_lkowner", 0ULL, 0 },
- { "secinfo", 0ULL, 0 },
- { "fsid_present", 0ULL, 0 },
-
- /* nfsv4.1 client ops */
- { "exchange_id", 0ULL, 0 },
- { "create_session", 0ULL, 0 },
- { "destroy_session", 0ULL, 0 },
- { "sequence", 0ULL, 0 },
- { "get_lease_time", 0ULL, 0 },
- { "reclaim_comp", 0ULL, 0 },
- { "layoutget", 0ULL, 0 },
- { "getdevinfo", 0ULL, 0 },
- { "layoutcommit", 0ULL, 0 },
- { "layoutreturn", 0ULL, 0 },
- { "secinfo_no", 0ULL, 0 },
- { "test_stateid", 0ULL, 0 },
- { "free_stateid", 0ULL, 0 },
- { "getdevicelist", 0ULL, 0 },
- { "bind_conn_to_ses", 0ULL, 0 },
- { "destroy_clientid", 0ULL, 0 },
-
- /* nfsv4.2 client ops */
- { "seek", 0ULL, 0 },
- { "allocate", 0ULL, 0 },
- { "deallocate", 0ULL, 0 },
- { "layoutstats", 0ULL, 0 },
- { "clone", 0ULL, 0 },
-
- /* termination */
- { "", 0ULL, 0 }
+ { "null" , 0ULL, 0, NULL}
+ , {"read" , 0ULL, 0, NULL}
+ , {"write" , 0ULL, 0, NULL}
+ , {"commit" , 0ULL, 0, NULL}
+ , {"open" , 0ULL, 0, NULL}
+ , {"open_conf" , 0ULL, 0, NULL}
+ , {"open_noat" , 0ULL, 0, NULL}
+ , {"open_dgrd" , 0ULL, 0, NULL}
+ , {"close" , 0ULL, 0, NULL}
+ , {"setattr" , 0ULL, 0, NULL}
+ , {"fsinfo" , 0ULL, 0, NULL}
+ , {"renew" , 0ULL, 0, NULL}
+ , {"setclntid" , 0ULL, 0, NULL}
+ , {"confirm" , 0ULL, 0, NULL}
+ , {"lock" , 0ULL, 0, NULL}
+ , {"lockt" , 0ULL, 0, NULL}
+ , {"locku" , 0ULL, 0, NULL}
+ , {"access" , 0ULL, 0, NULL}
+ , {"getattr" , 0ULL, 0, NULL}
+ , {"lookup" , 0ULL, 0, NULL}
+ , {"lookup_root" , 0ULL, 0, NULL}
+ , {"remove" , 0ULL, 0, NULL}
+ , {"rename" , 0ULL, 0, NULL}
+ , {"link" , 0ULL, 0, NULL}
+ , {"symlink" , 0ULL, 0, NULL}
+ , {"create" , 0ULL, 0, NULL}
+ , {"pathconf" , 0ULL, 0, NULL}
+ , {"statfs" , 0ULL, 0, NULL}
+ , {"readlink" , 0ULL, 0, NULL}
+ , {"readdir" , 0ULL, 0, NULL}
+ , {"server_caps" , 0ULL, 0, NULL}
+ , {"delegreturn" , 0ULL, 0, NULL}
+ , {"getacl" , 0ULL, 0, NULL}
+ , {"setacl" , 0ULL, 0, NULL}
+ , {"fs_locations" , 0ULL, 0, NULL}
+ , {"rel_lkowner" , 0ULL, 0, NULL}
+ , {"secinfo" , 0ULL, 0, NULL}
+ , {"fsid_present" , 0ULL, 0, NULL}
+ ,
+
+ /* nfsv4.1 client ops */
+ { "exchange_id" , 0ULL, 0, NULL}
+ , {"create_session" , 0ULL, 0, NULL}
+ , {"destroy_session" , 0ULL, 0, NULL}
+ , {"sequence" , 0ULL, 0, NULL}
+ , {"get_lease_time" , 0ULL, 0, NULL}
+ , {"reclaim_comp" , 0ULL, 0, NULL}
+ , {"layoutget" , 0ULL, 0, NULL}
+ , {"getdevinfo" , 0ULL, 0, NULL}
+ , {"layoutcommit" , 0ULL, 0, NULL}
+ , {"layoutreturn" , 0ULL, 0, NULL}
+ , {"secinfo_no" , 0ULL, 0, NULL}
+ , {"test_stateid" , 0ULL, 0, NULL}
+ , {"free_stateid" , 0ULL, 0, NULL}
+ , {"getdevicelist" , 0ULL, 0, NULL}
+ , {"bind_conn_to_ses", 0ULL, 0, NULL}
+ , {"destroy_clientid", 0ULL, 0, NULL}
+ ,
+
+ /* nfsv4.2 client ops */
+ { "seek" , 0ULL, 0, NULL}
+ , {"allocate" , 0ULL, 0, NULL}
+ , {"deallocate" , 0ULL, 0, NULL}
+ , {"layoutstats" , 0ULL, 0, NULL}
+ , {"clone" , 0ULL, 0, NULL}
+ ,
+
+ /* termination */
+ { "" , 0ULL, 0, NULL}
};
struct nfsd_procs nfsd4_ops_values[] = {
- { "unused_op0", 0ULL, 0},
- { "unused_op1", 0ULL, 0},
- { "future_op2", 0ULL, 0},
- { "access", 0ULL, 0},
- { "close", 0ULL, 0},
- { "commit", 0ULL, 0},
- { "create", 0ULL, 0},
- { "delegpurge", 0ULL, 0},
- { "delegreturn", 0ULL, 0},
- { "getattr", 0ULL, 0},
- { "getfh", 0ULL, 0},
- { "link", 0ULL, 0},
- { "lock", 0ULL, 0},
- { "lockt", 0ULL, 0},
- { "locku", 0ULL, 0},
- { "lookup", 0ULL, 0},
- { "lookup_root", 0ULL, 0},
- { "nverify", 0ULL, 0},
- { "open", 0ULL, 0},
- { "openattr", 0ULL, 0},
- { "open_confirm", 0ULL, 0},
- { "open_downgrade", 0ULL, 0},
- { "putfh", 0ULL, 0},
- { "putpubfh", 0ULL, 0},
- { "putrootfh", 0ULL, 0},
- { "read", 0ULL, 0},
- { "readdir", 0ULL, 0},
- { "readlink", 0ULL, 0},
- { "remove", 0ULL, 0},
- { "rename", 0ULL, 0},
- { "renew", 0ULL, 0},
- { "restorefh", 0ULL, 0},
- { "savefh", 0ULL, 0},
- { "secinfo", 0ULL, 0},
- { "setattr", 0ULL, 0},
- { "setclientid", 0ULL, 0},
- { "setclientid_confirm", 0ULL, 0},
- { "verify", 0ULL, 0},
- { "write", 0ULL, 0},
- { "release_lockowner", 0ULL, 0},
-
- /* nfs41 */
- { "backchannel_ctl", 0ULL, 0},
- { "bind_conn_to_session", 0ULL, 0},
- { "exchange_id", 0ULL, 0},
- { "create_session", 0ULL, 0},
- { "destroy_session", 0ULL, 0},
- { "free_stateid", 0ULL, 0},
- { "get_dir_delegation", 0ULL, 0},
- { "getdeviceinfo", 0ULL, 0},
- { "getdevicelist", 0ULL, 0},
- { "layoutcommit", 0ULL, 0},
- { "layoutget", 0ULL, 0},
- { "layoutreturn", 0ULL, 0},
- { "secinfo_no_name", 0ULL, 0},
- { "sequence", 0ULL, 0},
- { "set_ssv", 0ULL, 0},
- { "test_stateid", 0ULL, 0},
- { "want_delegation", 0ULL, 0},
- { "destroy_clientid", 0ULL, 0},
- { "reclaim_complete", 0ULL, 0},
-
- /* nfs42 */
- { "allocate", 0ULL, 0},
- { "copy", 0ULL, 0},
- { "copy_notify", 0ULL, 0},
- { "deallocate", 0ULL, 0},
- { "ioadvise", 0ULL, 0},
- { "layouterror", 0ULL, 0},
- { "layoutstats", 0ULL, 0},
- { "offload_cancel", 0ULL, 0},
- { "offload_status", 0ULL, 0},
- { "read_plus", 0ULL, 0},
- { "seek", 0ULL, 0},
- { "write_same", 0ULL, 0},
-
- /* termination */
- { "", 0ULL, 0 }
+ { "unused_op0" , 0ULL, 0, NULL}
+ , {"unused_op1" , 0ULL, 0, NULL}
+ , {"future_op2" , 0ULL, 0, NULL}
+ , {"access" , 0ULL, 0, NULL}
+ , {"close" , 0ULL, 0, NULL}
+ , {"commit" , 0ULL, 0, NULL}
+ , {"create" , 0ULL, 0, NULL}
+ , {"delegpurge" , 0ULL, 0, NULL}
+ , {"delegreturn" , 0ULL, 0, NULL}
+ , {"getattr" , 0ULL, 0, NULL}
+ , {"getfh" , 0ULL, 0, NULL}
+ , {"link" , 0ULL, 0, NULL}
+ , {"lock" , 0ULL, 0, NULL}
+ , {"lockt" , 0ULL, 0, NULL}
+ , {"locku" , 0ULL, 0, NULL}
+ , {"lookup" , 0ULL, 0, NULL}
+ , {"lookup_root" , 0ULL, 0, NULL}
+ , {"nverify" , 0ULL, 0, NULL}
+ , {"open" , 0ULL, 0, NULL}
+ , {"openattr" , 0ULL, 0, NULL}
+ , {"open_confirm" , 0ULL, 0, NULL}
+ , {"open_downgrade" , 0ULL, 0, NULL}
+ , {"putfh" , 0ULL, 0, NULL}
+ , {"putpubfh" , 0ULL, 0, NULL}
+ , {"putrootfh" , 0ULL, 0, NULL}
+ , {"read" , 0ULL, 0, NULL}
+ , {"readdir" , 0ULL, 0, NULL}
+ , {"readlink" , 0ULL, 0, NULL}
+ , {"remove" , 0ULL, 0, NULL}
+ , {"rename" , 0ULL, 0, NULL}
+ , {"renew" , 0ULL, 0, NULL}
+ , {"restorefh" , 0ULL, 0, NULL}
+ , {"savefh" , 0ULL, 0, NULL}
+ , {"secinfo" , 0ULL, 0, NULL}
+ , {"setattr" , 0ULL, 0, NULL}
+ , {"setclientid" , 0ULL, 0, NULL}
+ , {"setclientid_confirm" , 0ULL, 0, NULL}
+ , {"verify" , 0ULL, 0, NULL}
+ , {"write" , 0ULL, 0, NULL}
+ , {"release_lockowner" , 0ULL, 0, NULL}
+ ,
+
+ /* nfs41 */
+ { "backchannel_ctl" , 0ULL, 0, NULL}
+ , {"bind_conn_to_session", 0ULL, 0, NULL}
+ , {"exchange_id" , 0ULL, 0, NULL}
+ , {"create_session" , 0ULL, 0, NULL}
+ , {"destroy_session" , 0ULL, 0, NULL}
+ , {"free_stateid" , 0ULL, 0, NULL}
+ , {"get_dir_delegation" , 0ULL, 0, NULL}
+ , {"getdeviceinfo" , 0ULL, 0, NULL}
+ , {"getdevicelist" , 0ULL, 0, NULL}
+ , {"layoutcommit" , 0ULL, 0, NULL}
+ , {"layoutget" , 0ULL, 0, NULL}
+ , {"layoutreturn" , 0ULL, 0, NULL}
+ , {"secinfo_no_name" , 0ULL, 0, NULL}
+ , {"sequence" , 0ULL, 0, NULL}
+ , {"set_ssv" , 0ULL, 0, NULL}
+ , {"test_stateid" , 0ULL, 0, NULL}
+ , {"want_delegation" , 0ULL, 0, NULL}
+ , {"destroy_clientid" , 0ULL, 0, NULL}
+ , {"reclaim_complete" , 0ULL, 0, NULL}
+ ,
+
+ /* nfs42 */
+ { "allocate" , 0ULL, 0, NULL}
+ , {"copy" , 0ULL, 0, NULL}
+ , {"copy_notify" , 0ULL, 0, NULL}
+ , {"deallocate" , 0ULL, 0, NULL}
+ , {"ioadvise" , 0ULL, 0, NULL}
+ , {"layouterror" , 0ULL, 0, NULL}
+ , {"layoutstats" , 0ULL, 0, NULL}
+ , {"offload_cancel" , 0ULL, 0, NULL}
+ , {"offload_status" , 0ULL, 0, NULL}
+ , {"read_plus" , 0ULL, 0, NULL}
+ , {"seek" , 0ULL, 0, NULL}
+ , {"write_same" , 0ULL, 0, NULL}
+ ,
+
+ /* termination */
+ { "" , 0ULL, 0, NULL}
};
@@ -487,234 +496,403 @@ int do_proc_net_rpc_nfsd(int update_every, usec_t dt) {
}
}
- RRDSET *st;
-
// --------------------------------------------------------------------
if(do_rc == 2) {
- st = rrdset_find_bytype_localhost("nfsd", "readcache");
- if(!st) {
- st = rrdset_create_localhost("nfsd", "readcache", NULL, "cache", NULL, "NFS Server Read Cache", "reads/s"
- , 5000, update_every, RRDSET_TYPE_STACKED);
-
- rrddim_add(st, "hits", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "misses", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "nocache", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_hits = NULL,
+ *rd_misses = NULL,
+ *rd_nocache = NULL;
+
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "nfsd"
+ , "readcache"
+ , NULL
+ , "cache"
+ , NULL
+ , "NFS Server Read Cache"
+ , "reads/s"
+ , "proc"
+ , "net/rpc/nfsd"
+ , 5000
+ , update_every
+ , RRDSET_TYPE_STACKED
+ );
+
+ rd_hits = rrddim_add(st, "hits", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_misses = rrddim_add(st, "misses", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_nocache = rrddim_add(st, "nocache", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "hits", rc_hits);
- rrddim_set(st, "misses", rc_misses);
- rrddim_set(st, "nocache", rc_nocache);
+ rrddim_set_by_pointer(st, rd_hits, rc_hits);
+ rrddim_set_by_pointer(st, rd_misses, rc_misses);
+ rrddim_set_by_pointer(st, rd_nocache, rc_nocache);
rrdset_done(st);
}
// --------------------------------------------------------------------
if(do_fh == 2) {
- st = rrdset_find_bytype_localhost("nfsd", "filehandles");
- if(!st) {
- st = rrdset_create_localhost("nfsd", "filehandles", NULL, "filehandles", NULL, "NFS Server File Handles"
- , "handles/s", 5001, update_every, RRDSET_TYPE_LINE);
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_stale = NULL,
+ *rd_total_lookups = NULL,
+ *rd_anonymous_lookups = NULL,
+ *rd_dir_not_in_dcache = NULL,
+ *rd_non_dir_not_in_dcache = NULL;
+
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "nfsd"
+ , "filehandles"
+ , NULL
+ , "filehandles"
+ , NULL
+ , "NFS Server File Handles"
+ , "handles/s"
+ , "proc"
+ , "net/rpc/nfsd"
+ , 5001
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
- rrddim_add(st, "stale", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
- rrddim_add(st, "total_lookups", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "anonymous_lookups", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "dir_not_in_dcache", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "non_dir_not_in_dcache", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_stale = rrddim_add(st, "stale", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+ rd_total_lookups = rrddim_add(st, "total_lookups", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_anonymous_lookups = rrddim_add(st, "anonymous_lookups", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_dir_not_in_dcache = rrddim_add(st, "dir_not_in_dcache", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_non_dir_not_in_dcache = rrddim_add(st, "non_dir_not_in_dcache", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "stale", fh_stale);
- rrddim_set(st, "total_lookups", fh_total_lookups);
- rrddim_set(st, "anonymous_lookups", fh_anonymous_lookups);
- rrddim_set(st, "dir_not_in_dcache", fh_dir_not_in_dcache);
- rrddim_set(st, "non_dir_not_in_dcache", fh_non_dir_not_in_dcache);
+ rrddim_set_by_pointer(st, rd_stale, fh_stale);
+ rrddim_set_by_pointer(st, rd_total_lookups, fh_total_lookups);
+ rrddim_set_by_pointer(st, rd_anonymous_lookups, fh_anonymous_lookups);
+ rrddim_set_by_pointer(st, rd_dir_not_in_dcache, fh_dir_not_in_dcache);
+ rrddim_set_by_pointer(st, rd_non_dir_not_in_dcache, fh_non_dir_not_in_dcache);
rrdset_done(st);
}
// --------------------------------------------------------------------
if(do_io == 2) {
- st = rrdset_find_bytype_localhost("nfsd", "io");
- if(!st) {
- st = rrdset_create_localhost("nfsd", "io", NULL, "io", NULL, "NFS Server I/O", "kilobytes/s", 5002
- , update_every, RRDSET_TYPE_AREA);
-
- rrddim_add(st, "read", NULL, 1, 1000, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "write", NULL, -1, 1000, RRD_ALGORITHM_INCREMENTAL);
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_read = NULL,
+ *rd_write = NULL;
+
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "nfsd"
+ , "io"
+ , NULL
+ , "io"
+ , NULL
+ , "NFS Server I/O"
+ , "kilobytes/s"
+ , "proc"
+ , "net/rpc/nfsd"
+ , 5002
+ , update_every
+ , RRDSET_TYPE_AREA
+ );
+
+ rd_read = rrddim_add(st, "read", NULL, 1, 1000, RRD_ALGORITHM_INCREMENTAL);
+ rd_write = rrddim_add(st, "write", NULL, -1, 1000, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "read", io_read);
- rrddim_set(st, "write", io_write);
+ rrddim_set_by_pointer(st, rd_read, io_read);
+ rrddim_set_by_pointer(st, rd_write, io_write);
rrdset_done(st);
}
// --------------------------------------------------------------------
if(do_th == 2) {
- st = rrdset_find_bytype_localhost("nfsd", "threads");
- if(!st) {
- st = rrdset_create_localhost("nfsd", "threads", NULL, "threads", NULL, "NFS Server Threads", "threads", 5003
- , update_every, RRDSET_TYPE_LINE);
+ {
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_threads = NULL;
+
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "nfsd"
+ , "threads"
+ , NULL
+ , "threads"
+ , NULL
+ , "NFS Server Threads"
+ , "threads"
+ , "proc"
+ , "net/rpc/nfsd"
+ , 5003
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rd_threads = rrddim_add(st, "threads", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+ }
+ else rrdset_next(st);
- rrddim_add(st, "threads", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+ rrddim_set_by_pointer(st, rd_threads, th_threads);
+ rrdset_done(st);
}
- else rrdset_next(st);
-
- rrddim_set(st, "threads", th_threads);
- rrdset_done(st);
- st = rrdset_find_bytype_localhost("nfsd", "threads_fullcnt");
- if(!st) {
- st = rrdset_create_localhost("nfsd", "threads_fullcnt", NULL, "threads", NULL
- , "NFS Server Threads Full Count", "ops/s", 5004, update_every
- , RRDSET_TYPE_LINE);
+ {
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_full_count = NULL;
+
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "nfsd"
+ , "threads_fullcnt"
+ , NULL
+ , "threads"
+ , NULL
+ , "NFS Server Threads Full Count"
+ , "ops/s"
+ , "proc"
+ , "net/rpc/nfsd"
+ , 5004
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rd_full_count = rrddim_add(st, "full_count", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ }
+ else rrdset_next(st);
- rrddim_add(st, "full_count", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rrddim_set_by_pointer(st, rd_full_count, th_fullcnt);
+ rrdset_done(st);
}
- else rrdset_next(st);
- rrddim_set(st, "full_count", th_fullcnt);
- rrdset_done(st);
-
- st = rrdset_find_bytype_localhost("nfsd", "threads_histogram");
- if(!st) {
- st = rrdset_create_localhost("nfsd", "threads_histogram", NULL, "threads", NULL
- , "NFS Server Threads Usage Histogram", "percentage", 5005, update_every
- , RRDSET_TYPE_LINE);
-
- rrddim_add(st, "0%-10%", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
- rrddim_add(st, "10%-20%", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
- rrddim_add(st, "20%-30%", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
- rrddim_add(st, "30%-40%", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
- rrddim_add(st, "40%-50%", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
- rrddim_add(st, "50%-60%", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
- rrddim_add(st, "60%-70%", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
- rrddim_add(st, "70%-80%", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
- rrddim_add(st, "80%-90%", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
- rrddim_add(st, "90%-100%", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
+ {
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_th_hist10 = NULL,
+ *rd_th_hist20 = NULL,
+ *rd_th_hist30 = NULL,
+ *rd_th_hist40 = NULL,
+ *rd_th_hist50 = NULL,
+ *rd_th_hist60 = NULL,
+ *rd_th_hist70 = NULL,
+ *rd_th_hist80 = NULL,
+ *rd_th_hist90 = NULL,
+ *rd_th_hist100 = NULL;
+
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "nfsd"
+ , "threads_histogram"
+ , NULL
+ , "threads"
+ , NULL
+ , "NFS Server Threads Usage Histogram"
+ , "percentage"
+ , "proc"
+ , "net/rpc/nfsd"
+ , 5005
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rd_th_hist10 = rrddim_add(st, "0%-10%", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
+ rd_th_hist20 = rrddim_add(st, "10%-20%", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
+ rd_th_hist30 = rrddim_add(st, "20%-30%", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
+ rd_th_hist40 = rrddim_add(st, "30%-40%", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
+ rd_th_hist50 = rrddim_add(st, "40%-50%", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
+ rd_th_hist60 = rrddim_add(st, "50%-60%", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
+ rd_th_hist70 = rrddim_add(st, "60%-70%", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
+ rd_th_hist80 = rrddim_add(st, "70%-80%", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
+ rd_th_hist90 = rrddim_add(st, "80%-90%", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
+ rd_th_hist100 = rrddim_add(st, "90%-100%", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
+ }
+ else rrdset_next(st);
+
+ rrddim_set_by_pointer(st, rd_th_hist10, th_hist10);
+ rrddim_set_by_pointer(st, rd_th_hist20, th_hist20);
+ rrddim_set_by_pointer(st, rd_th_hist30, th_hist30);
+ rrddim_set_by_pointer(st, rd_th_hist40, th_hist40);
+ rrddim_set_by_pointer(st, rd_th_hist50, th_hist50);
+ rrddim_set_by_pointer(st, rd_th_hist60, th_hist60);
+ rrddim_set_by_pointer(st, rd_th_hist70, th_hist70);
+ rrddim_set_by_pointer(st, rd_th_hist80, th_hist80);
+ rrddim_set_by_pointer(st, rd_th_hist90, th_hist90);
+ rrddim_set_by_pointer(st, rd_th_hist100, th_hist100);
+ rrdset_done(st);
}
- else rrdset_next(st);
-
- rrddim_set(st, "0%-10%", th_hist10);
- rrddim_set(st, "10%-20%", th_hist20);
- rrddim_set(st, "20%-30%", th_hist30);
- rrddim_set(st, "30%-40%", th_hist40);
- rrddim_set(st, "40%-50%", th_hist50);
- rrddim_set(st, "50%-60%", th_hist60);
- rrddim_set(st, "60%-70%", th_hist70);
- rrddim_set(st, "70%-80%", th_hist80);
- rrddim_set(st, "80%-90%", th_hist90);
- rrddim_set(st, "90%-100%", th_hist100);
- rrdset_done(st);
}
// --------------------------------------------------------------------
if(do_ra == 2) {
- st = rrdset_find_bytype_localhost("nfsd", "readahead");
- if(!st) {
- st = rrdset_create_localhost("nfsd", "readahead", NULL, "readahead", NULL, "NFS Server Read Ahead Depth"
- , "percentage", 5005, update_every, RRDSET_TYPE_STACKED);
-
- rrddim_add(st, "10%", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
- rrddim_add(st, "20%", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
- rrddim_add(st, "30%", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
- rrddim_add(st, "40%", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
- rrddim_add(st, "50%", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
- rrddim_add(st, "60%", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
- rrddim_add(st, "70%", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
- rrddim_add(st, "80%", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
- rrddim_add(st, "90%", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
- rrddim_add(st, "100%", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
- rrddim_add(st, "misses", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_ra_hist10 = NULL,
+ *rd_ra_hist20 = NULL,
+ *rd_ra_hist30 = NULL,
+ *rd_ra_hist40 = NULL,
+ *rd_ra_hist50 = NULL,
+ *rd_ra_hist60 = NULL,
+ *rd_ra_hist70 = NULL,
+ *rd_ra_hist80 = NULL,
+ *rd_ra_hist90 = NULL,
+ *rd_ra_hist100 = NULL,
+ *rd_ra_none = NULL;
+
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "nfsd"
+ , "readahead"
+ , NULL
+ , "readahead"
+ , NULL
+ , "NFS Server Read Ahead Depth"
+ , "percentage"
+ , "proc"
+ , "net/rpc/nfsd"
+ , 5005
+ , update_every
+ , RRDSET_TYPE_STACKED
+ );
+
+ rd_ra_hist10 = rrddim_add(st, "10%", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
+ rd_ra_hist20 = rrddim_add(st, "20%", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
+ rd_ra_hist30 = rrddim_add(st, "30%", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
+ rd_ra_hist40 = rrddim_add(st, "40%", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
+ rd_ra_hist50 = rrddim_add(st, "50%", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
+ rd_ra_hist60 = rrddim_add(st, "60%", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
+ rd_ra_hist70 = rrddim_add(st, "70%", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
+ rd_ra_hist80 = rrddim_add(st, "80%", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
+ rd_ra_hist90 = rrddim_add(st, "90%", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
+ rd_ra_hist100 = rrddim_add(st, "100%", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
+ rd_ra_none = rrddim_add(st, "misses", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
}
else rrdset_next(st);
// ignore ra_size
- if(ra_size) {};
-
- rrddim_set(st, "10%", ra_hist10);
- rrddim_set(st, "20%", ra_hist20);
- rrddim_set(st, "30%", ra_hist30);
- rrddim_set(st, "40%", ra_hist40);
- rrddim_set(st, "50%", ra_hist50);
- rrddim_set(st, "60%", ra_hist60);
- rrddim_set(st, "70%", ra_hist70);
- rrddim_set(st, "80%", ra_hist80);
- rrddim_set(st, "90%", ra_hist90);
- rrddim_set(st, "100%", ra_hist100);
- rrddim_set(st, "misses", ra_none);
+ (void)ra_size;
+
+ rrddim_set_by_pointer(st, rd_ra_hist10, ra_hist10);
+ rrddim_set_by_pointer(st, rd_ra_hist20, ra_hist20);
+ rrddim_set_by_pointer(st, rd_ra_hist30, ra_hist30);
+ rrddim_set_by_pointer(st, rd_ra_hist40, ra_hist40);
+ rrddim_set_by_pointer(st, rd_ra_hist50, ra_hist50);
+ rrddim_set_by_pointer(st, rd_ra_hist60, ra_hist60);
+ rrddim_set_by_pointer(st, rd_ra_hist70, ra_hist70);
+ rrddim_set_by_pointer(st, rd_ra_hist80, ra_hist80);
+ rrddim_set_by_pointer(st, rd_ra_hist90, ra_hist90);
+ rrddim_set_by_pointer(st, rd_ra_hist100,ra_hist100);
+ rrddim_set_by_pointer(st, rd_ra_none, ra_none);
rrdset_done(st);
}
// --------------------------------------------------------------------
if(do_net == 2) {
- st = rrdset_find_bytype_localhost("nfsd", "net");
- if(!st) {
- st = rrdset_create_localhost("nfsd", "net", NULL, "network", NULL, "NFS Server Network Statistics"
- , "packets/s", 5007, update_every, RRDSET_TYPE_STACKED);
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_udp = NULL,
+ *rd_tcp = NULL;
+
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "nfsd"
+ , "net"
+ , NULL
+ , "network"
+ , NULL
+ , "NFS Server Network Statistics"
+ , "packets/s"
+ , "proc"
+ , "net/rpc/nfsd"
+ , 5007
+ , update_every
+ , RRDSET_TYPE_STACKED
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
- rrddim_add(st, "udp", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "tcp", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_udp = rrddim_add(st, "udp", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_tcp = rrddim_add(st, "tcp", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
// ignore net_count, net_tcp_connections
- if(net_count) {};
- if(net_tcp_connections) {};
+ (void)net_count;
+ (void)net_tcp_connections;
- rrddim_set(st, "udp", net_udp_count);
- rrddim_set(st, "tcp", net_tcp_count);
+ rrddim_set_by_pointer(st, rd_udp, net_udp_count);
+ rrddim_set_by_pointer(st, rd_tcp, net_tcp_count);
rrdset_done(st);
}
// --------------------------------------------------------------------
if(do_rpc == 2) {
- st = rrdset_find_bytype_localhost("nfsd", "rpc");
- if(!st) {
- st = rrdset_create_localhost("nfsd", "rpc", NULL, "rpc", NULL
- , "NFS Server Remote Procedure Calls Statistics", "calls/s", 5008, update_every
- , RRDSET_TYPE_LINE);
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_calls = NULL,
+ *rd_bad_format = NULL,
+ *rd_bad_auth = NULL;
+
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "nfsd"
+ , "rpc"
+ , NULL
+ , "rpc"
+ , NULL
+ , "NFS Server Remote Procedure Calls Statistics"
+ , "calls/s"
+ , "proc"
+ , "net/rpc/nfsd"
+ , 5008
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
- rrddim_add(st, "calls", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "bad_format", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "bad_auth", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_calls = rrddim_add(st, "calls", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_bad_format = rrddim_add(st, "bad_format", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_bad_auth = rrddim_add(st, "bad_auth", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
// ignore rpc_bad_client
- if(rpc_bad_client) {};
+ (void)rpc_bad_client;
- rrddim_set(st, "calls", rpc_calls);
- rrddim_set(st, "bad_format", rpc_bad_format);
- rrddim_set(st, "bad_auth", rpc_bad_auth);
+ rrddim_set_by_pointer(st, rd_calls, rpc_calls);
+ rrddim_set_by_pointer(st, rd_bad_format, rpc_bad_format);
+ rrddim_set_by_pointer(st, rd_bad_auth, rpc_bad_auth);
rrdset_done(st);
}
// --------------------------------------------------------------------
if(do_proc2 == 2) {
- unsigned int i;
- st = rrdset_find_bytype_localhost("nfsd", "proc2");
- if(!st) {
- st = rrdset_create_localhost("nfsd", "proc2", NULL, "nfsv2rpc", NULL, "NFS v2 Server Remote Procedure Calls"
- , "calls/s", 5009, update_every, RRDSET_TYPE_STACKED);
-
- for(i = 0; nfsd_proc2_values[i].present ; i++)
- rrddim_add(st, nfsd_proc2_values[i].name, NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ static RRDSET *st = NULL;
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "nfsd"
+ , "proc2"
+ , NULL
+ , "nfsv2rpc"
+ , NULL
+ , "NFS v2 Server Remote Procedure Calls"
+ , "calls/s"
+ , "proc"
+ , "net/rpc/nfsd"
+ , 5009
+ , update_every
+ , RRDSET_TYPE_STACKED
+ );
}
else rrdset_next(st);
- for(i = 0; nfsd_proc2_values[i].present ; i++)
- rrddim_set(st, nfsd_proc2_values[i].name, nfsd_proc2_values[i].value);
+ size_t i;
+ for(i = 0; nfsd_proc2_values[i].present ; i++) {
+ if(unlikely(!nfsd_proc2_values[i].rd))
+ nfsd_proc2_values[i].rd = rrddim_add(st, nfsd_proc2_values[i].name, NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+
+ rrddim_set_by_pointer(st, nfsd_proc2_values[i].rd, nfsd_proc2_values[i].value);
+ }
rrdset_done(st);
}
@@ -722,19 +900,32 @@ int do_proc_net_rpc_nfsd(int update_every, usec_t dt) {
// --------------------------------------------------------------------
if(do_proc3 == 2) {
- unsigned int i;
- st = rrdset_find_bytype_localhost("nfsd", "proc3");
- if(!st) {
- st = rrdset_create_localhost("nfsd", "proc3", NULL, "nfsv3rpc", NULL, "NFS v3 Server Remote Procedure Calls"
- , "calls/s", 5010, update_every, RRDSET_TYPE_STACKED);
-
- for(i = 0; nfsd_proc3_values[i].present ; i++)
- rrddim_add(st, nfsd_proc3_values[i].name, NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ static RRDSET *st = NULL;
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "nfsd"
+ , "proc3"
+ , NULL
+ , "nfsv3rpc"
+ , NULL
+ , "NFS v3 Server Remote Procedure Calls"
+ , "calls/s"
+ , "proc"
+ , "net/rpc/nfsd"
+ , 5010
+ , update_every
+ , RRDSET_TYPE_STACKED
+ );
}
else rrdset_next(st);
- for(i = 0; nfsd_proc3_values[i].present ; i++)
- rrddim_set(st, nfsd_proc3_values[i].name, nfsd_proc3_values[i].value);
+ size_t i;
+ for(i = 0; nfsd_proc3_values[i].present ; i++) {
+ if(unlikely(!nfsd_proc3_values[i].rd))
+ nfsd_proc3_values[i].rd = rrddim_add(st, nfsd_proc3_values[i].name, NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+
+ rrddim_set_by_pointer(st, nfsd_proc3_values[i].rd, nfsd_proc3_values[i].value);
+ }
rrdset_done(st);
}
@@ -742,19 +933,32 @@ int do_proc_net_rpc_nfsd(int update_every, usec_t dt) {
// --------------------------------------------------------------------
if(do_proc4 == 2) {
- unsigned int i;
- st = rrdset_find_bytype_localhost("nfsd", "proc4");
- if(!st) {
- st = rrdset_create_localhost("nfsd", "proc4", NULL, "nfsv4rpc", NULL, "NFS v4 Server Remote Procedure Calls"
- , "calls/s", 5011, update_every, RRDSET_TYPE_STACKED);
-
- for(i = 0; nfsd_proc4_values[i].present ; i++)
- rrddim_add(st, nfsd_proc4_values[i].name, NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ static RRDSET *st = NULL;
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "nfsd"
+ , "proc4"
+ , NULL
+ , "nfsv4rpc"
+ , NULL
+ , "NFS v4 Server Remote Procedure Calls"
+ , "calls/s"
+ , "proc"
+ , "net/rpc/nfsd"
+ , 5011
+ , update_every
+ , RRDSET_TYPE_STACKED
+ );
}
else rrdset_next(st);
- for(i = 0; nfsd_proc4_values[i].present ; i++)
- rrddim_set(st, nfsd_proc4_values[i].name, nfsd_proc4_values[i].value);
+ size_t i;
+ for(i = 0; nfsd_proc4_values[i].present ; i++) {
+ if(unlikely(!nfsd_proc4_values[i].rd))
+ nfsd_proc4_values[i].rd = rrddim_add(st, nfsd_proc4_values[i].name, NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+
+ rrddim_set_by_pointer(st, nfsd_proc4_values[i].rd, nfsd_proc4_values[i].value);
+ }
rrdset_done(st);
}
@@ -762,19 +966,32 @@ int do_proc_net_rpc_nfsd(int update_every, usec_t dt) {
// --------------------------------------------------------------------
if(do_proc4ops == 2) {
- unsigned int i;
- st = rrdset_find_bytype_localhost("nfsd", "proc4ops");
- if(!st) {
- st = rrdset_create_localhost("nfsd", "proc4ops", NULL, "nfsv2ops", NULL, "NFS v4 Server Operations"
- , "operations/s", 5012, update_every, RRDSET_TYPE_STACKED);
-
- for(i = 0; nfsd4_ops_values[i].present ; i++)
- rrddim_add(st, nfsd4_ops_values[i].name, NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ static RRDSET *st = NULL;
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "nfsd"
+ , "proc4ops"
+ , NULL
+ , "nfsv2ops"
+ , NULL
+ , "NFS v4 Server Operations"
+ , "operations/s"
+ , "proc"
+ , "net/rpc/nfsd"
+ , 5012
+ , update_every
+ , RRDSET_TYPE_STACKED
+ );
}
else rrdset_next(st);
- for(i = 0; nfsd4_ops_values[i].present ; i++)
- rrddim_set(st, nfsd4_ops_values[i].name, nfsd4_ops_values[i].value);
+ size_t i;
+ for(i = 0; nfsd4_ops_values[i].present ; i++) {
+ if(unlikely(!nfsd4_ops_values[i].rd))
+ nfsd4_ops_values[i].rd = rrddim_add(st, nfsd4_ops_values[i].name, NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+
+ rrddim_set_by_pointer(st, nfsd4_ops_values[i].rd, nfsd4_ops_values[i].value);
+ }
rrdset_done(st);
}
diff --git a/src/proc_net_snmp.c b/src/proc_net_snmp.c
index 817c964b..fabfdf8c 100644
--- a/src/proc_net_snmp.c
+++ b/src/proc_net_snmp.c
@@ -2,197 +2,88 @@
#define RRD_TYPE_NET_SNMP "ipv4"
-struct netstat_columns {
- char *name;
- uint32_t hash;
- unsigned long long value;
- int multiplier; // not needed everywhere
- char *label; // not needed everywhere
-};
-
-static struct netstat_columns ip_data[] = {
-// { "Forwarding", 0, 0, 1, NULL },
-// { "DefaultTTL", 0, 0, 1, NULL },
- { "InReceives", 0, 0, 1, NULL },
- { "InHdrErrors", 0, 0, 1, NULL },
- { "InAddrErrors", 0, 0, 1, NULL },
- { "ForwDatagrams", 0, 0, 1, NULL },
- { "InUnknownProtos", 0, 0, 1, NULL },
- { "InDiscards", 0, 0, 1, NULL },
- { "InDelivers", 0, 0, 1, NULL },
- { "OutRequests", 0, 0, 1, NULL },
- { "OutDiscards", 0, 0, 1, NULL },
- { "OutNoRoutes", 0, 0, 1, NULL },
-// { "ReasmTimeout", 0, 0, 1, NULL },
- { "ReasmReqds", 0, 0, 1, NULL },
- { "ReasmOKs", 0, 0, 1, NULL },
- { "ReasmFails", 0, 0, 1, NULL },
- { "FragOKs", 0, 0, 1, NULL },
- { "FragFails", 0, 0, 1, NULL },
- { "FragCreates", 0, 0, 1, NULL },
- { NULL, 0, 0, 0, NULL }
-};
-
-static struct netstat_columns icmp_data[] = {
- { "InMsgs", 0, 0, 1, NULL },
- { "OutMsgs", 0, 0, -1, NULL },
- { "InErrors", 0, 0, 1, NULL },
- { "OutErrors", 0, 0, -1, NULL },
- { "InCsumErrors", 0, 0, 1, NULL },
-
- // all these are available in icmpmsg
-// { "InDestUnreachs", 0, 0, 1, NULL },
-// { "OutDestUnreachs", 0, 0, -1, NULL },
-// { "InTimeExcds", 0, 0, 1, NULL },
-// { "OutTimeExcds", 0, 0, -1, NULL },
-// { "InParmProbs", 0, 0, 1, NULL },
-// { "OutParmProbs", 0, 0, -1, NULL },
-// { "InSrcQuenchs", 0, 0, 1, NULL },
-// { "OutSrcQuenchs", 0, 0, -1, NULL },
-// { "InRedirects", 0, 0, 1, NULL },
-// { "OutRedirects", 0, 0, -1, NULL },
-// { "InEchos", 0, 0, 1, NULL },
-// { "OutEchos", 0, 0, -1, NULL },
-// { "InEchoReps", 0, 0, 1, NULL },
-// { "OutEchoReps", 0, 0, -1, NULL },
-// { "InTimestamps", 0, 0, 1, NULL },
-// { "OutTimestamps", 0, 0, -1, NULL },
-// { "InTimestampReps", 0, 0, 1, NULL },
-// { "OutTimestampReps", 0, 0, -1, NULL },
-// { "InAddrMasks", 0, 0, 1, NULL },
-// { "OutAddrMasks", 0, 0, -1, NULL },
-// { "InAddrMaskReps", 0, 0, 1, NULL },
-// { "OutAddrMaskReps", 0, 0, -1, NULL },
-
- { NULL, 0, 0, 0, NULL }
-};
-
-static struct netstat_columns icmpmsg_data[] = {
- { "InType0", 0, 0, 1, "InEchoReps" },
- { "OutType0", 0, 0, -1, "OutEchoReps" },
-// { "InType1", 0, 0, 1, NULL }, // unassigned
-// { "OutType1", 0, 0, -1, NULL }, // unassigned
-// { "InType2", 0, 0, 1, NULL }, // unassigned
-// { "OutType2", 0, 0, -1, NULL }, // unassigned
- { "InType3", 0, 0, 1, "InDestUnreachs" },
- { "OutType3", 0, 0, -1, "OutDestUnreachs" },
-// { "InType4", 0, 0, 1, "InSrcQuenchs" }, // deprecated
-// { "OutType4", 0, 0, -1, "OutSrcQuenchs" }, // deprecated
- { "InType5", 0, 0, 1, "InRedirects" },
- { "OutType5", 0, 0, -1, "OutRedirects" },
-// { "InType6", 0, 0, 1, "InAlterHostAddr" }, // deprecated
-// { "OutType6", 0, 0, -1, "OutAlterHostAddr" }, // deprecated
-// { "InType7", 0, 0, 1, NULL }, // unassigned
-// { "OutType7", 0, 0, -1, NULL }, // unassigned
- { "InType8", 0, 0, 1, "InEchos" },
- { "OutType8", 0, 0, -1, "OutEchos" },
- { "InType9", 0, 0, 1, "InRouterAdvert" },
- { "OutType9", 0, 0, -1, "OutRouterAdvert" },
- { "InType10", 0, 0, 1, "InRouterSelect" },
- { "OutType10", 0, 0, -1, "OutRouterSelect" },
- { "InType11", 0, 0, 1, "InTimeExcds" },
- { "OutType11", 0, 0, -1, "OutTimeExcds" },
- { "InType12", 0, 0, 1, "InParmProbs" },
- { "OutType12", 0, 0, -1, "OutParmProbs" },
- { "InType13", 0, 0, 1, "InTimestamps" },
- { "OutType13", 0, 0, -1, "OutTimestamps" },
- { "InType14", 0, 0, 1, "InTimestampReps" },
- { "OutType14", 0, 0, -1, "OutTimestampReps" },
-// { "InType15", 0, 0, 1, "InInfos" }, // deprecated
-// { "OutType15", 0, 0, -1, "OutInfos" }, // deprecated
-// { "InType16", 0, 0, 1, "InInfoReps" }, // deprecated
-// { "OutType16", 0, 0, -1, "OutInfoReps" }, // deprecated
-// { "InType17", 0, 0, 1, "InAddrMasks" }, // deprecated
-// { "OutType17", 0, 0, -1, "OutAddrMasks" }, // deprecated
-// { "InType18", 0, 0, 1, "InAddrMaskReps" }, // deprecated
-// { "OutType18", 0, 0, -1, "OutAddrMaskReps" }, // deprecated
-// { "InType30", 0, 0, 1, "InTraceroute" }, // deprecated
-// { "OutType30", 0, 0, -1, "OutTraceroute" }, // deprecated
- { NULL, 0, 0, 0, NULL }
-};
-
-static struct netstat_columns tcp_data[] = {
-// { "RtoAlgorithm", 0, 0, 1, NULL },
-// { "RtoMin", 0, 0, 1, NULL },
-// { "RtoMax", 0, 0, 1, NULL },
-// { "MaxConn", 0, 0, 1, NULL },
- { "ActiveOpens", 0, 0, 1, NULL },
- { "PassiveOpens", 0, 0, 1, NULL },
- { "AttemptFails", 0, 0, 1, NULL },
- { "EstabResets", 0, 0, 1, NULL },
- { "CurrEstab", 0, 0, 1, NULL },
- { "InSegs", 0, 0, 1, NULL },
- { "OutSegs", 0, 0, 1, NULL },
- { "RetransSegs", 0, 0, 1, NULL },
- { "InErrs", 0, 0, 1, NULL },
- { "OutRsts", 0, 0, 1, NULL },
- { "InCsumErrors", 0, 0, 1, NULL },
- { NULL, 0, 0, 0, NULL }
-};
-
-static struct netstat_columns udp_data[] = {
- { "InDatagrams", 0, 0, 1, NULL },
- { "NoPorts", 0, 0, 1, NULL },
- { "InErrors", 0, 0, 1, NULL },
- { "OutDatagrams", 0, 0, 1, NULL },
- { "RcvbufErrors", 0, 0, 1, NULL },
- { "SndbufErrors", 0, 0, 1, NULL },
- { "InCsumErrors", 0, 0, 1, NULL },
- { "IgnoredMulti", 0, 0, 1, NULL },
- { NULL, 0, 0, 0, NULL }
-};
-
-static struct netstat_columns udplite_data[] = {
- { "InDatagrams", 0, 0, 1, NULL },
- { "NoPorts", 0, 0, 1, NULL },
- { "InErrors", 0, 0, 1, NULL },
- { "OutDatagrams", 0, 0, 1, NULL },
- { "RcvbufErrors", 0, 0, 1, NULL },
- { "SndbufErrors", 0, 0, 1, NULL },
- { "InCsumErrors", 0, 0, 1, NULL },
- { "IgnoredMulti", 0, 0, 1, NULL },
- { NULL, 0, 0, 0, NULL }
-};
-
-static void hash_array(struct netstat_columns *nc) {
- int i;
-
- for(i = 0; nc[i].name ;i++)
- nc[i].hash = simple_hash(nc[i].name);
-}
-
-static unsigned long long *netstat_columns_find(struct netstat_columns *nc, const char *name) {
- uint32_t i, hash = simple_hash(name);
-
- for(i = 0; nc[i].name ;i++)
- if(unlikely(nc[i].hash == hash && !strcmp(nc[i].name, name)))
- return &nc[i].value;
-
- fatal("Cannot find key '%s' in /proc/net/snmp internal array.", name);
-}
-
-static void parse_line_pair(procfile *ff, struct netstat_columns *nc, size_t header_line, size_t values_line) {
- size_t hwords = procfile_linewords(ff, header_line);
- size_t vwords = procfile_linewords(ff, values_line);
- size_t w, i;
-
- if(unlikely(vwords > hwords)) {
- error("File /proc/net/snmp on header line %zu has %zu words, but on value line %zu has %zu words.", header_line, hwords, values_line, vwords);
- vwords = hwords;
- }
-
- for(w = 1; w < vwords ;w++) {
- char *key = procfile_lineword(ff, header_line, w);
- uint32_t hash = simple_hash(key);
-
- for(i = 0 ; nc[i].name ;i++) {
- if(unlikely(hash == nc[i].hash && !strcmp(key, nc[i].name))) {
- nc[i].value = str2ull(procfile_lineword(ff, values_line, w));
- break;
- }
- }
- }
-}
+static struct proc_net_snmp {
+ // kernel_uint_t ip_Forwarding;
+ kernel_uint_t ip_DefaultTTL;
+ kernel_uint_t ip_InReceives;
+ kernel_uint_t ip_InHdrErrors;
+ kernel_uint_t ip_InAddrErrors;
+ kernel_uint_t ip_ForwDatagrams;
+ kernel_uint_t ip_InUnknownProtos;
+ kernel_uint_t ip_InDiscards;
+ kernel_uint_t ip_InDelivers;
+ kernel_uint_t ip_OutRequests;
+ kernel_uint_t ip_OutDiscards;
+ kernel_uint_t ip_OutNoRoutes;
+ kernel_uint_t ip_ReasmTimeout;
+ kernel_uint_t ip_ReasmReqds;
+ kernel_uint_t ip_ReasmOKs;
+ kernel_uint_t ip_ReasmFails;
+ kernel_uint_t ip_FragOKs;
+ kernel_uint_t ip_FragFails;
+ kernel_uint_t ip_FragCreates;
+
+ kernel_uint_t icmp_InMsgs;
+ kernel_uint_t icmp_OutMsgs;
+ kernel_uint_t icmp_InErrors;
+ kernel_uint_t icmp_OutErrors;
+ kernel_uint_t icmp_InCsumErrors;
+
+ kernel_uint_t icmpmsg_InEchoReps;
+ kernel_uint_t icmpmsg_OutEchoReps;
+ kernel_uint_t icmpmsg_InDestUnreachs;
+ kernel_uint_t icmpmsg_OutDestUnreachs;
+ kernel_uint_t icmpmsg_InRedirects;
+ kernel_uint_t icmpmsg_OutRedirects;
+ kernel_uint_t icmpmsg_InEchos;
+ kernel_uint_t icmpmsg_OutEchos;
+ kernel_uint_t icmpmsg_InRouterAdvert;
+ kernel_uint_t icmpmsg_OutRouterAdvert;
+ kernel_uint_t icmpmsg_InRouterSelect;
+ kernel_uint_t icmpmsg_OutRouterSelect;
+ kernel_uint_t icmpmsg_InTimeExcds;
+ kernel_uint_t icmpmsg_OutTimeExcds;
+ kernel_uint_t icmpmsg_InParmProbs;
+ kernel_uint_t icmpmsg_OutParmProbs;
+ kernel_uint_t icmpmsg_InTimestamps;
+ kernel_uint_t icmpmsg_OutTimestamps;
+ kernel_uint_t icmpmsg_InTimestampReps;
+ kernel_uint_t icmpmsg_OutTimestampReps;
+
+ //kernel_uint_t tcp_RtoAlgorithm;
+ //kernel_uint_t tcp_RtoMin;
+ //kernel_uint_t tcp_RtoMax;
+ ssize_t tcp_MaxConn;
+ kernel_uint_t tcp_ActiveOpens;
+ kernel_uint_t tcp_PassiveOpens;
+ kernel_uint_t tcp_AttemptFails;
+ kernel_uint_t tcp_EstabResets;
+ kernel_uint_t tcp_CurrEstab;
+ kernel_uint_t tcp_InSegs;
+ kernel_uint_t tcp_OutSegs;
+ kernel_uint_t tcp_RetransSegs;
+ kernel_uint_t tcp_InErrs;
+ kernel_uint_t tcp_OutRsts;
+ kernel_uint_t tcp_InCsumErrors;
+
+ kernel_uint_t udp_InDatagrams;
+ kernel_uint_t udp_NoPorts;
+ kernel_uint_t udp_InErrors;
+ kernel_uint_t udp_OutDatagrams;
+ kernel_uint_t udp_RcvbufErrors;
+ kernel_uint_t udp_SndbufErrors;
+ kernel_uint_t udp_InCsumErrors;
+ kernel_uint_t udp_IgnoredMulti;
+
+ kernel_uint_t udplite_InDatagrams;
+ kernel_uint_t udplite_NoPorts;
+ kernel_uint_t udplite_InErrors;
+ kernel_uint_t udplite_OutDatagrams;
+ kernel_uint_t udplite_RcvbufErrors;
+ kernel_uint_t udplite_SndbufErrors;
+ kernel_uint_t udplite_InCsumErrors;
+ kernel_uint_t udplite_IgnoredMulti;
+} snmp_root = { 0 };
int do_proc_net_snmp(int update_every, usec_t dt) {
(void)dt;
@@ -203,67 +94,17 @@ int do_proc_net_snmp(int update_every, usec_t dt) {
do_udp_packets = -1, do_udp_errors = -1, do_icmp_packets = -1, do_icmpmsg = -1, do_udplite_packets = -1;
static uint32_t hash_ip = 0, hash_icmp = 0, hash_tcp = 0, hash_udp = 0, hash_icmpmsg = 0, hash_udplite = 0;
- //static unsigned long long *ip_Forwarding = NULL;
- //static unsigned long long *ip_DefaultTTL = NULL;
- static unsigned long long *ip_InReceives = NULL;
- static unsigned long long *ip_InHdrErrors = NULL;
- static unsigned long long *ip_InAddrErrors = NULL;
- static unsigned long long *ip_ForwDatagrams = NULL;
- static unsigned long long *ip_InUnknownProtos = NULL;
- static unsigned long long *ip_InDiscards = NULL;
- static unsigned long long *ip_InDelivers = NULL;
- static unsigned long long *ip_OutRequests = NULL;
- static unsigned long long *ip_OutDiscards = NULL;
- static unsigned long long *ip_OutNoRoutes = NULL;
- //static unsigned long long *ip_ReasmTimeout = NULL;
- static unsigned long long *ip_ReasmReqds = NULL;
- static unsigned long long *ip_ReasmOKs = NULL;
- static unsigned long long *ip_ReasmFails = NULL;
- static unsigned long long *ip_FragOKs = NULL;
- static unsigned long long *ip_FragFails = NULL;
- static unsigned long long *ip_FragCreates = NULL;
-
- static unsigned long long *icmp_InMsgs = NULL;
- static unsigned long long *icmp_OutMsgs = NULL;
- static unsigned long long *icmp_InErrors = NULL;
- static unsigned long long *icmp_OutErrors = NULL;
- static unsigned long long *icmp_InCsumErrors = NULL;
-
- //static unsigned long long *tcp_RtoAlgorithm = NULL;
- //static unsigned long long *tcp_RtoMin = NULL;
- //static unsigned long long *tcp_RtoMax = NULL;
- //static unsigned long long *tcp_MaxConn = NULL;
- static unsigned long long *tcp_ActiveOpens = NULL;
- static unsigned long long *tcp_PassiveOpens = NULL;
- static unsigned long long *tcp_AttemptFails = NULL;
- static unsigned long long *tcp_EstabResets = NULL;
- static unsigned long long *tcp_CurrEstab = NULL;
- static unsigned long long *tcp_InSegs = NULL;
- static unsigned long long *tcp_OutSegs = NULL;
- static unsigned long long *tcp_RetransSegs = NULL;
- static unsigned long long *tcp_InErrs = NULL;
- static unsigned long long *tcp_OutRsts = NULL;
- static unsigned long long *tcp_InCsumErrors = NULL;
-
- static unsigned long long *udp_InDatagrams = NULL;
- static unsigned long long *udp_NoPorts = NULL;
- static unsigned long long *udp_InErrors = NULL;
- static unsigned long long *udp_OutDatagrams = NULL;
- static unsigned long long *udp_RcvbufErrors = NULL;
- static unsigned long long *udp_SndbufErrors = NULL;
- static unsigned long long *udp_InCsumErrors = NULL;
- static unsigned long long *udp_IgnoredMulti = NULL;
-
- static unsigned long long *udplite_InDatagrams = NULL;
- static unsigned long long *udplite_NoPorts = NULL;
- static unsigned long long *udplite_InErrors = NULL;
- static unsigned long long *udplite_OutDatagrams = NULL;
- static unsigned long long *udplite_RcvbufErrors = NULL;
- static unsigned long long *udplite_SndbufErrors = NULL;
- static unsigned long long *udplite_InCsumErrors = NULL;
- static unsigned long long *udplite_IgnoredMulti = NULL;
-
- if(unlikely(do_ip_packets == -1)) {
+ static ARL_BASE *arl_ip = NULL,
+ *arl_icmp = NULL,
+ *arl_icmpmsg = NULL,
+ *arl_tcp = NULL,
+ *arl_udp = NULL,
+ *arl_udplite = NULL;
+
+ static RRDVAR *tcp_max_connections_var = NULL;
+ static ssize_t last_max_connections = 0;
+
+ if(unlikely(!arl_ip)) {
do_ip_packets = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 packets", 1);
do_ip_fragsout = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 fragments sent", 1);
do_ip_fragsin = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 fragments assembly", 1);
@@ -285,72 +126,94 @@ int do_proc_net_snmp(int update_every, usec_t dt) {
hash_icmpmsg = simple_hash("IcmpMsg");
hash_udplite = simple_hash("UdpLite");
- hash_array(ip_data);
- hash_array(tcp_data);
- hash_array(udp_data);
- hash_array(icmp_data);
- hash_array(icmpmsg_data);
- hash_array(udplite_data);
-
- //ip_Forwarding = netstat_columns_find(ip_data, "Forwarding");
- //ip_DefaultTTL = netstat_columns_find(ip_data, "DefaultTTL");
- ip_InReceives = netstat_columns_find(ip_data, "InReceives");
- ip_InHdrErrors = netstat_columns_find(ip_data, "InHdrErrors");
- ip_InAddrErrors = netstat_columns_find(ip_data, "InAddrErrors");
- ip_ForwDatagrams = netstat_columns_find(ip_data, "ForwDatagrams");
- ip_InUnknownProtos = netstat_columns_find(ip_data, "InUnknownProtos");
- ip_InDiscards = netstat_columns_find(ip_data, "InDiscards");
- ip_InDelivers = netstat_columns_find(ip_data, "InDelivers");
- ip_OutRequests = netstat_columns_find(ip_data, "OutRequests");
- ip_OutDiscards = netstat_columns_find(ip_data, "OutDiscards");
- ip_OutNoRoutes = netstat_columns_find(ip_data, "OutNoRoutes");
- //ip_ReasmTimeout = netstat_columns_find(ip_data, "ReasmTimeout");
- ip_ReasmReqds = netstat_columns_find(ip_data, "ReasmReqds");
- ip_ReasmOKs = netstat_columns_find(ip_data, "ReasmOKs");
- ip_ReasmFails = netstat_columns_find(ip_data, "ReasmFails");
- ip_FragOKs = netstat_columns_find(ip_data, "FragOKs");
- ip_FragFails = netstat_columns_find(ip_data, "FragFails");
- ip_FragCreates = netstat_columns_find(ip_data, "FragCreates");
-
- icmp_InMsgs = netstat_columns_find(icmp_data, "InMsgs");
- icmp_OutMsgs = netstat_columns_find(icmp_data, "OutMsgs");
- icmp_InErrors = netstat_columns_find(icmp_data, "InErrors");
- icmp_OutErrors = netstat_columns_find(icmp_data, "OutErrors");
- icmp_InCsumErrors = netstat_columns_find(icmp_data, "InCsumErrors");
-
- //tcp_RtoAlgorithm = netstat_columns_find(tcp_data, "RtoAlgorithm");
- //tcp_RtoMin = netstat_columns_find(tcp_data, "RtoMin");
- //tcp_RtoMax = netstat_columns_find(tcp_data, "RtoMax");
- //tcp_MaxConn = netstat_columns_find(tcp_data, "MaxConn");
- tcp_ActiveOpens = netstat_columns_find(tcp_data, "ActiveOpens");
- tcp_PassiveOpens = netstat_columns_find(tcp_data, "PassiveOpens");
- tcp_AttemptFails = netstat_columns_find(tcp_data, "AttemptFails");
- tcp_EstabResets = netstat_columns_find(tcp_data, "EstabResets");
- tcp_CurrEstab = netstat_columns_find(tcp_data, "CurrEstab");
- tcp_InSegs = netstat_columns_find(tcp_data, "InSegs");
- tcp_OutSegs = netstat_columns_find(tcp_data, "OutSegs");
- tcp_RetransSegs = netstat_columns_find(tcp_data, "RetransSegs");
- tcp_InErrs = netstat_columns_find(tcp_data, "InErrs");
- tcp_OutRsts = netstat_columns_find(tcp_data, "OutRsts");
- tcp_InCsumErrors = netstat_columns_find(tcp_data, "InCsumErrors");
-
- udp_InDatagrams = netstat_columns_find(udp_data, "InDatagrams");
- udp_NoPorts = netstat_columns_find(udp_data, "NoPorts");
- udp_InErrors = netstat_columns_find(udp_data, "InErrors");
- udp_OutDatagrams = netstat_columns_find(udp_data, "OutDatagrams");
- udp_RcvbufErrors = netstat_columns_find(udp_data, "RcvbufErrors");
- udp_SndbufErrors = netstat_columns_find(udp_data, "SndbufErrors");
- udp_InCsumErrors = netstat_columns_find(udp_data, "InCsumErrors");
- udp_IgnoredMulti = netstat_columns_find(udp_data, "IgnoredMulti");
-
- udplite_InDatagrams = netstat_columns_find(udplite_data, "InDatagrams");
- udplite_NoPorts = netstat_columns_find(udplite_data, "NoPorts");
- udplite_InErrors = netstat_columns_find(udplite_data, "InErrors");
- udplite_OutDatagrams = netstat_columns_find(udplite_data, "OutDatagrams");
- udplite_RcvbufErrors = netstat_columns_find(udplite_data, "RcvbufErrors");
- udplite_SndbufErrors = netstat_columns_find(udplite_data, "SndbufErrors");
- udplite_InCsumErrors = netstat_columns_find(udplite_data, "InCsumErrors");
- udplite_IgnoredMulti = netstat_columns_find(udplite_data, "IgnoredMulti");
+ arl_ip = arl_create("snmp/Ip", arl_callback_str2kernel_uint_t, 60);
+ // arl_expect(arl_ip, "Forwarding", &snmp_root.ip_Forwarding);
+ arl_expect(arl_ip, "DefaultTTL", &snmp_root.ip_DefaultTTL);
+ arl_expect(arl_ip, "InReceives", &snmp_root.ip_InReceives);
+ arl_expect(arl_ip, "InHdrErrors", &snmp_root.ip_InHdrErrors);
+ arl_expect(arl_ip, "InAddrErrors", &snmp_root.ip_InAddrErrors);
+ arl_expect(arl_ip, "ForwDatagrams", &snmp_root.ip_ForwDatagrams);
+ arl_expect(arl_ip, "InUnknownProtos", &snmp_root.ip_InUnknownProtos);
+ arl_expect(arl_ip, "InDiscards", &snmp_root.ip_InDiscards);
+ arl_expect(arl_ip, "InDelivers", &snmp_root.ip_InDelivers);
+ arl_expect(arl_ip, "OutRequests", &snmp_root.ip_OutRequests);
+ arl_expect(arl_ip, "OutDiscards", &snmp_root.ip_OutDiscards);
+ arl_expect(arl_ip, "OutNoRoutes", &snmp_root.ip_OutNoRoutes);
+ arl_expect(arl_ip, "ReasmTimeout", &snmp_root.ip_ReasmTimeout);
+ arl_expect(arl_ip, "ReasmReqds", &snmp_root.ip_ReasmReqds);
+ arl_expect(arl_ip, "ReasmOKs", &snmp_root.ip_ReasmOKs);
+ arl_expect(arl_ip, "ReasmFails", &snmp_root.ip_ReasmFails);
+ arl_expect(arl_ip, "FragOKs", &snmp_root.ip_FragOKs);
+ arl_expect(arl_ip, "FragFails", &snmp_root.ip_FragFails);
+ arl_expect(arl_ip, "FragCreates", &snmp_root.ip_FragCreates);
+
+ arl_icmp = arl_create("snmp/Icmp", arl_callback_str2kernel_uint_t, 60);
+ arl_expect(arl_icmp, "InMsgs", &snmp_root.icmp_InMsgs);
+ arl_expect(arl_icmp, "OutMsgs", &snmp_root.icmp_OutMsgs);
+ arl_expect(arl_icmp, "InErrors", &snmp_root.icmp_InErrors);
+ arl_expect(arl_icmp, "OutErrors", &snmp_root.icmp_OutErrors);
+ arl_expect(arl_icmp, "InCsumErrors", &snmp_root.icmp_InCsumErrors);
+
+ arl_icmpmsg = arl_create("snmp/Icmpmsg", arl_callback_str2kernel_uint_t, 60);
+ arl_expect(arl_icmpmsg, "InType0", &snmp_root.icmpmsg_InEchoReps);
+ arl_expect(arl_icmpmsg, "OutType0", &snmp_root.icmpmsg_OutEchoReps);
+ arl_expect(arl_icmpmsg, "InType3", &snmp_root.icmpmsg_InDestUnreachs);
+ arl_expect(arl_icmpmsg, "OutType3", &snmp_root.icmpmsg_OutDestUnreachs);
+ arl_expect(arl_icmpmsg, "InType5", &snmp_root.icmpmsg_InRedirects);
+ arl_expect(arl_icmpmsg, "OutType5", &snmp_root.icmpmsg_OutRedirects);
+ arl_expect(arl_icmpmsg, "InType8", &snmp_root.icmpmsg_InEchos);
+ arl_expect(arl_icmpmsg, "OutType8", &snmp_root.icmpmsg_OutEchos);
+ arl_expect(arl_icmpmsg, "InType9", &snmp_root.icmpmsg_InRouterAdvert);
+ arl_expect(arl_icmpmsg, "OutType9", &snmp_root.icmpmsg_OutRouterAdvert);
+ arl_expect(arl_icmpmsg, "InType10", &snmp_root.icmpmsg_InRouterSelect);
+ arl_expect(arl_icmpmsg, "OutType10", &snmp_root.icmpmsg_OutRouterSelect);
+ arl_expect(arl_icmpmsg, "InType11", &snmp_root.icmpmsg_InTimeExcds);
+ arl_expect(arl_icmpmsg, "OutType11", &snmp_root.icmpmsg_OutTimeExcds);
+ arl_expect(arl_icmpmsg, "InType12", &snmp_root.icmpmsg_InParmProbs);
+ arl_expect(arl_icmpmsg, "OutType12", &snmp_root.icmpmsg_OutParmProbs);
+ arl_expect(arl_icmpmsg, "InType13", &snmp_root.icmpmsg_InTimestamps);
+ arl_expect(arl_icmpmsg, "OutType13", &snmp_root.icmpmsg_OutTimestamps);
+ arl_expect(arl_icmpmsg, "InType14", &snmp_root.icmpmsg_InTimestampReps);
+ arl_expect(arl_icmpmsg, "OutType14", &snmp_root.icmpmsg_OutTimestampReps);
+
+ arl_tcp = arl_create("snmp/Tcp", arl_callback_str2kernel_uint_t, 60);
+ // arl_expect(arl_tcp, "RtoAlgorithm", &snmp_root.tcp_RtoAlgorithm);
+ // arl_expect(arl_tcp, "RtoMin", &snmp_root.tcp_RtoMin);
+ // arl_expect(arl_tcp, "RtoMax", &snmp_root.tcp_RtoMax);
+ arl_expect(arl_tcp, "MaxConn", &snmp_root.tcp_MaxConn);
+ arl_expect(arl_tcp, "ActiveOpens", &snmp_root.tcp_ActiveOpens);
+ arl_expect(arl_tcp, "PassiveOpens", &snmp_root.tcp_PassiveOpens);
+ arl_expect(arl_tcp, "AttemptFails", &snmp_root.tcp_AttemptFails);
+ arl_expect(arl_tcp, "EstabResets", &snmp_root.tcp_EstabResets);
+ arl_expect(arl_tcp, "CurrEstab", &snmp_root.tcp_CurrEstab);
+ arl_expect(arl_tcp, "InSegs", &snmp_root.tcp_InSegs);
+ arl_expect(arl_tcp, "OutSegs", &snmp_root.tcp_OutSegs);
+ arl_expect(arl_tcp, "RetransSegs", &snmp_root.tcp_RetransSegs);
+ arl_expect(arl_tcp, "InErrs", &snmp_root.tcp_InErrs);
+ arl_expect(arl_tcp, "OutRsts", &snmp_root.tcp_OutRsts);
+ arl_expect(arl_tcp, "InCsumErrors", &snmp_root.tcp_InCsumErrors);
+
+ arl_udp = arl_create("snmp/Udp", arl_callback_str2kernel_uint_t, 60);
+ arl_expect(arl_udp, "InDatagrams", &snmp_root.udp_InDatagrams);
+ arl_expect(arl_udp, "NoPorts", &snmp_root.udp_NoPorts);
+ arl_expect(arl_udp, "InErrors", &snmp_root.udp_InErrors);
+ arl_expect(arl_udp, "OutDatagrams", &snmp_root.udp_OutDatagrams);
+ arl_expect(arl_udp, "RcvbufErrors", &snmp_root.udp_RcvbufErrors);
+ arl_expect(arl_udp, "SndbufErrors", &snmp_root.udp_SndbufErrors);
+ arl_expect(arl_udp, "InCsumErrors", &snmp_root.udp_InCsumErrors);
+ arl_expect(arl_udp, "IgnoredMulti", &snmp_root.udp_IgnoredMulti);
+
+ arl_udplite = arl_create("snmp/Udplite", arl_callback_str2kernel_uint_t, 60);
+ arl_expect(arl_udplite, "InDatagrams", &snmp_root.udplite_InDatagrams);
+ arl_expect(arl_udplite, "NoPorts", &snmp_root.udplite_NoPorts);
+ arl_expect(arl_udplite, "InErrors", &snmp_root.udplite_InErrors);
+ arl_expect(arl_udplite, "OutDatagrams", &snmp_root.udplite_OutDatagrams);
+ arl_expect(arl_udplite, "RcvbufErrors", &snmp_root.udplite_RcvbufErrors);
+ arl_expect(arl_udplite, "SndbufErrors", &snmp_root.udplite_SndbufErrors);
+ arl_expect(arl_udplite, "InCsumErrors", &snmp_root.udplite_InCsumErrors);
+ arl_expect(arl_udplite, "IgnoredMulti", &snmp_root.udplite_IgnoredMulti);
+
+ tcp_max_connections_var = rrdvar_custom_host_variable_create(localhost, "tcp_max_connections");
}
if(unlikely(!ff)) {
@@ -364,9 +227,7 @@ int do_proc_net_snmp(int update_every, usec_t dt) {
if(unlikely(!ff)) return 0; // we return 0, so that we will retry to open it next time
size_t lines = procfile_lines(ff), l;
- size_t words;
-
- RRDSET *st;
+ size_t words, w;
for(l = 0; l < lines ;l++) {
char *key = procfile_lineword(ff, l, 0);
@@ -386,101 +247,170 @@ int do_proc_net_snmp(int update_every, usec_t dt) {
continue;
}
- // see also http://net-snmp.sourceforge.net/docs/mibs/ip.html
- parse_line_pair(ff, ip_data, h, l);
+ arl_begin(arl_ip);
+ for(w = 1; w < words ; w++) {
+ if (unlikely(arl_check(arl_ip, procfile_lineword(ff, h, w), procfile_lineword(ff, l, w)) != 0))
+ break;
+ }
// --------------------------------------------------------------------
if(do_ip_packets) {
- st = rrdset_find_localhost(RRD_TYPE_NET_SNMP ".packets");
- if(!st) {
- st = rrdset_create_localhost(RRD_TYPE_NET_SNMP, "packets", NULL, "packets", NULL, "IPv4 Packets"
- , "packets/s", 3000, update_every, RRDSET_TYPE_LINE);
-
- rrddim_add(st, "InReceives", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "OutRequests", "sent", -1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "ForwDatagrams", "forwarded", 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "InDelivers", "delivered", 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_InReceives = NULL,
+ *rd_OutRequests = NULL,
+ *rd_ForwDatagrams = NULL,
+ *rd_InDelivers = NULL;
+
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_SNMP
+ , "packets"
+ , NULL
+ , "packets"
+ , NULL
+ , "IPv4 Packets"
+ , "packets/s"
+ , "proc"
+ , "net/snmp"
+ , 2450
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rd_InReceives = rrddim_add(st, "InReceives", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutRequests = rrddim_add(st, "OutRequests", "sent", -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_ForwDatagrams = rrddim_add(st, "ForwDatagrams", "forwarded", 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InDelivers = rrddim_add(st, "InDelivers", "delivered", 1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "OutRequests", *ip_OutRequests);
- rrddim_set(st, "InReceives", *ip_InReceives);
- rrddim_set(st, "ForwDatagrams", *ip_ForwDatagrams);
- rrddim_set(st, "InDelivers", *ip_InDelivers);
+ rrddim_set_by_pointer(st, rd_OutRequests, (collected_number)snmp_root.ip_OutRequests);
+ rrddim_set_by_pointer(st, rd_InReceives, (collected_number)snmp_root.ip_InReceives);
+ rrddim_set_by_pointer(st, rd_ForwDatagrams, (collected_number)snmp_root.ip_ForwDatagrams);
+ rrddim_set_by_pointer(st, rd_InDelivers, (collected_number)snmp_root.ip_InDelivers);
rrdset_done(st);
}
// --------------------------------------------------------------------
if(do_ip_fragsout) {
- st = rrdset_find_localhost(RRD_TYPE_NET_SNMP ".fragsout");
- if(!st) {
- st = rrdset_create_localhost(RRD_TYPE_NET_SNMP, "fragsout", NULL, "fragments", NULL
- , "IPv4 Fragments Sent", "packets/s", 3010, update_every
- , RRDSET_TYPE_LINE);
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_FragOKs = NULL,
+ *rd_FragFails = NULL,
+ *rd_FragCreates = NULL;
+
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_SNMP
+ , "fragsout"
+ , NULL
+ , "fragments"
+ , NULL
+ , "IPv4 Fragments Sent"
+ , "packets/s"
+ , "proc"
+ , "net/snmp"
+ , 3020
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
- rrddim_add(st, "FragOKs", "ok", 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "FragFails", "failed", -1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "FragCreates", "created", 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_FragOKs = rrddim_add(st, "FragOKs", "ok", 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_FragFails = rrddim_add(st, "FragFails", "failed", -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_FragCreates = rrddim_add(st, "FragCreates", "created", 1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "FragOKs", *ip_FragOKs);
- rrddim_set(st, "FragFails", *ip_FragFails);
- rrddim_set(st, "FragCreates", *ip_FragCreates);
+ rrddim_set_by_pointer(st, rd_FragOKs, (collected_number)snmp_root.ip_FragOKs);
+ rrddim_set_by_pointer(st, rd_FragFails, (collected_number)snmp_root.ip_FragFails);
+ rrddim_set_by_pointer(st, rd_FragCreates, (collected_number)snmp_root.ip_FragCreates);
rrdset_done(st);
}
// --------------------------------------------------------------------
if(do_ip_fragsin) {
- st = rrdset_find_localhost(RRD_TYPE_NET_SNMP ".fragsin");
- if(!st) {
- st = rrdset_create_localhost(RRD_TYPE_NET_SNMP, "fragsin", NULL, "fragments", NULL
- , "IPv4 Fragments Reassembly", "packets/s", 3011, update_every
- , RRDSET_TYPE_LINE);
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_ReasmOKs = NULL,
+ *rd_ReasmFails = NULL,
+ *rd_ReasmReqds = NULL;
+
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_SNMP
+ , "fragsin"
+ , NULL
+ , "fragments"
+ , NULL
+ , "IPv4 Fragments Reassembly"
+ , "packets/s"
+ , "proc"
+ , "net/snmp"
+ , 3030
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
- rrddim_add(st, "ReasmOKs", "ok", 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "ReasmFails", "failed", -1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "ReasmReqds", "all", 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_ReasmOKs = rrddim_add(st, "ReasmOKs", "ok", 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_ReasmFails = rrddim_add(st, "ReasmFails", "failed", -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_ReasmReqds = rrddim_add(st, "ReasmReqds", "all", 1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "ReasmOKs", *ip_ReasmOKs);
- rrddim_set(st, "ReasmFails", *ip_ReasmFails);
- rrddim_set(st, "ReasmReqds", *ip_ReasmReqds);
+ rrddim_set_by_pointer(st, rd_ReasmOKs, (collected_number)snmp_root.ip_ReasmOKs);
+ rrddim_set_by_pointer(st, rd_ReasmFails, (collected_number)snmp_root.ip_ReasmFails);
+ rrddim_set_by_pointer(st, rd_ReasmReqds, (collected_number)snmp_root.ip_ReasmReqds);
rrdset_done(st);
}
// --------------------------------------------------------------------
if(do_ip_errors) {
- st = rrdset_find_localhost(RRD_TYPE_NET_SNMP ".errors");
- if(!st) {
- st = rrdset_create_localhost(RRD_TYPE_NET_SNMP, "errors", NULL, "errors", NULL, "IPv4 Errors"
- , "packets/s", 3002, update_every, RRDSET_TYPE_LINE);
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_InDiscards = NULL,
+ *rd_OutDiscards = NULL,
+ *rd_InHdrErrors = NULL,
+ *rd_OutNoRoutes = NULL,
+ *rd_InAddrErrors = NULL,
+ *rd_InUnknownProtos = NULL;
+
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_SNMP
+ , "errors"
+ , NULL
+ , "errors"
+ , NULL
+ , "IPv4 Errors"
+ , "packets/s"
+ , "proc"
+ , "net/snmp"
+ , 2470
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
- rrddim_add(st, "InDiscards", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "OutDiscards", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InDiscards = rrddim_add(st, "InDiscards", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutDiscards = rrddim_add(st, "OutDiscards", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "InHdrErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "OutNoRoutes", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InHdrErrors = rrddim_add(st, "InHdrErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutNoRoutes = rrddim_add(st, "OutNoRoutes", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "InAddrErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "InUnknownProtos", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InAddrErrors = rrddim_add(st, "InAddrErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InUnknownProtos = rrddim_add(st, "InUnknownProtos", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "InDiscards", *ip_InDiscards);
- rrddim_set(st, "OutDiscards", *ip_OutDiscards);
- rrddim_set(st, "InHdrErrors", *ip_InHdrErrors);
- rrddim_set(st, "InAddrErrors", *ip_InAddrErrors);
- rrddim_set(st, "InUnknownProtos", *ip_InUnknownProtos);
- rrddim_set(st, "OutNoRoutes", *ip_OutNoRoutes);
+ rrddim_set_by_pointer(st, rd_InDiscards, (collected_number)snmp_root.ip_InDiscards);
+ rrddim_set_by_pointer(st, rd_OutDiscards, (collected_number)snmp_root.ip_OutDiscards);
+ rrddim_set_by_pointer(st, rd_InHdrErrors, (collected_number)snmp_root.ip_InHdrErrors);
+ rrddim_set_by_pointer(st, rd_InAddrErrors, (collected_number)snmp_root.ip_InAddrErrors);
+ rrddim_set_by_pointer(st, rd_InUnknownProtos, (collected_number)snmp_root.ip_InUnknownProtos);
+ rrddim_set_by_pointer(st, rd_OutNoRoutes, (collected_number)snmp_root.ip_OutNoRoutes);
rrdset_done(st);
}
}
@@ -498,43 +428,81 @@ int do_proc_net_snmp(int update_every, usec_t dt) {
continue;
}
- parse_line_pair(ff, icmp_data, h, l);
+ arl_begin(arl_icmp);
+ for(w = 1; w < words ; w++) {
+ if (unlikely(arl_check(arl_icmp, procfile_lineword(ff, h, w), procfile_lineword(ff, l, w)) != 0))
+ break;
+ }
// --------------------------------------------------------------------
if(do_icmp_packets) {
- st = rrdset_find_localhost(RRD_TYPE_NET_SNMP ".icmp");
- if(!st) {
- st = rrdset_create_localhost(RRD_TYPE_NET_SNMP, "icmp", NULL, "icmp", NULL, "IPv4 ICMP Packets"
- , "packets/s", 2602, update_every, RRDSET_TYPE_LINE);
-
- rrddim_add(st, "InMsgs", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "OutMsgs", "sent", -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ {
+ static RRDSET *st_packets = NULL;
+ static RRDDIM *rd_InMsgs = NULL,
+ *rd_OutMsgs = NULL;
+
+ if(unlikely(!st_packets)) {
+ st_packets = rrdset_create_localhost(
+ RRD_TYPE_NET_SNMP
+ , "icmp"
+ , NULL
+ , "icmp"
+ , NULL
+ , "IPv4 ICMP Packets"
+ , "packets/s"
+ , "proc"
+ , "net/snmp"
+ , 2602
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rd_InMsgs = rrddim_add(st_packets, "InMsgs", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutMsgs = rrddim_add(st_packets, "OutMsgs", "sent", -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ }
+ else rrdset_next(st_packets);
+
+ rrddim_set_by_pointer(st_packets, rd_InMsgs, (collected_number)snmp_root.icmp_InMsgs);
+ rrddim_set_by_pointer(st_packets, rd_OutMsgs, (collected_number)snmp_root.icmp_OutMsgs);
+
+ rrdset_done(st_packets);
}
- else rrdset_next(st);
-
- rrddim_set(st, "InMsgs", *icmp_InMsgs);
- rrddim_set(st, "OutMsgs", *icmp_OutMsgs);
-
- rrdset_done(st);
-
- st = rrdset_find_localhost(RRD_TYPE_NET_SNMP ".icmp_errors");
- if(!st) {
- st = rrdset_create_localhost(RRD_TYPE_NET_SNMP, "icmp_errors", NULL, "icmp", NULL
- , "IPv4 ICMP Errors", "packets/s", 2603, update_every
- , RRDSET_TYPE_LINE);
- rrddim_add(st, "InErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "OutErrors", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "InCsumErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ {
+ static RRDSET *st_errors = NULL;
+ static RRDDIM *rd_InErrors = NULL,
+ *rd_OutErrors = NULL,
+ *rd_InCsumErrors = NULL;
+
+ if(unlikely(!st_errors)) {
+ st_errors = rrdset_create_localhost(
+ RRD_TYPE_NET_SNMP
+ , "icmp_errors"
+ , NULL
+ , "icmp"
+ , NULL
+ , "IPv4 ICMP Errors"
+ , "packets/s"
+ , "proc"
+ , "net/snmp"
+ , 2603
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rd_InErrors = rrddim_add(st_errors, "InErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutErrors = rrddim_add(st_errors, "OutErrors", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InCsumErrors = rrddim_add(st_errors, "InCsumErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ }
+ else rrdset_next(st_errors);
+
+ rrddim_set_by_pointer(st_errors, rd_InErrors, (collected_number)snmp_root.icmp_InErrors);
+ rrddim_set_by_pointer(st_errors, rd_OutErrors, (collected_number)snmp_root.icmp_OutErrors);
+ rrddim_set_by_pointer(st_errors, rd_InCsumErrors, (collected_number)snmp_root.icmp_InCsumErrors);
+
+ rrdset_done(st_errors);
}
- else rrdset_next(st);
-
- rrddim_set(st, "InErrors", *icmp_InErrors);
- rrddim_set(st, "OutErrors", *icmp_OutErrors);
- rrddim_set(st, "InCsumErrors", *icmp_InCsumErrors);
-
- rrdset_done(st);
}
}
else if(unlikely(hash == hash_icmpmsg && strcmp(key, "IcmpMsg") == 0)) {
@@ -545,25 +513,102 @@ int do_proc_net_snmp(int update_every, usec_t dt) {
break;
}
- parse_line_pair(ff, icmpmsg_data, h, l);
+ words = procfile_linewords(ff, l);
+ if(words < 3) {
+ error("Cannot read /proc/net/snmp IcmpMsg line. Expected 3+ params, read %zu.", words);
+ continue;
+ }
+
+ arl_begin(arl_icmpmsg);
+ for(w = 1; w < words ; w++) {
+ if (unlikely(arl_check(arl_icmpmsg, procfile_lineword(ff, h, w), procfile_lineword(ff, l, w)) != 0))
+ break;
+ }
// --------------------------------------------------------------------
if(do_icmpmsg) {
- int i;
-
- st = rrdset_find_localhost(RRD_TYPE_NET_SNMP ".icmpmsg");
- if(!st) {
- st = rrdset_create_localhost(RRD_TYPE_NET_SNMP, "icmpmsg", NULL, "icmp", NULL, "IPv4 ICMP Messages"
- , "packets/s", 2604, update_every, RRDSET_TYPE_LINE);
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_InEchoReps = NULL,
+ *rd_OutEchoReps = NULL,
+ *rd_InDestUnreachs = NULL,
+ *rd_OutDestUnreachs = NULL,
+ *rd_InRedirects = NULL,
+ *rd_OutRedirects = NULL,
+ *rd_InEchos = NULL,
+ *rd_OutEchos = NULL,
+ *rd_InRouterAdvert = NULL,
+ *rd_OutRouterAdvert = NULL,
+ *rd_InRouterSelect = NULL,
+ *rd_OutRouterSelect = NULL,
+ *rd_InTimeExcds = NULL,
+ *rd_OutTimeExcds = NULL,
+ *rd_InParmProbs = NULL,
+ *rd_OutParmProbs = NULL,
+ *rd_InTimestamps = NULL,
+ *rd_OutTimestamps = NULL,
+ *rd_InTimestampReps = NULL,
+ *rd_OutTimestampReps = NULL;
+
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_SNMP
+ , "icmpmsg"
+ , NULL
+ , "icmp"
+ , NULL
+ , "IPv4 ICMP Messages"
+ , "packets/s"
+ , "proc"
+ , "net/snmp"
+ , 2604
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
- for(i = 0; icmpmsg_data[i].name ;i++)
- rrddim_add(st, icmpmsg_data[i].name, icmpmsg_data[i].label, icmpmsg_data[i].multiplier, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InEchoReps = rrddim_add(st, "InType0", "InEchoReps", 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutEchoReps = rrddim_add(st, "OutType0", "OutEchoReps", -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InDestUnreachs = rrddim_add(st, "InType3", "InDestUnreachs", 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutDestUnreachs = rrddim_add(st, "OutType3", "OutDestUnreachs", -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InRedirects = rrddim_add(st, "InType5", "InRedirects", 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutRedirects = rrddim_add(st, "OutType5", "OutRedirects", -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InEchos = rrddim_add(st, "InType8", "InEchos", 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutEchos = rrddim_add(st, "OutType8", "OutEchos", -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InRouterAdvert = rrddim_add(st, "InType9", "InRouterAdvert", 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutRouterAdvert = rrddim_add(st, "OutType9", "OutRouterAdvert", -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InRouterSelect = rrddim_add(st, "InType10", "InRouterSelect", 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutRouterSelect = rrddim_add(st, "OutType10", "OutRouterSelect", -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InTimeExcds = rrddim_add(st, "InType11", "InTimeExcds", 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutTimeExcds = rrddim_add(st, "OutType11", "OutTimeExcds", -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InParmProbs = rrddim_add(st, "InType12", "InParmProbs", 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutParmProbs = rrddim_add(st, "OutType12", "OutParmProbs", -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InTimestamps = rrddim_add(st, "InType13", "InTimestamps", 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutTimestamps = rrddim_add(st, "OutType13", "OutTimestamps", -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InTimestampReps = rrddim_add(st, "InType14", "InTimestampReps", 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutTimestampReps = rrddim_add(st, "OutType14", "OutTimestampReps", -1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- for(i = 0; icmpmsg_data[i].name ;i++)
- rrddim_set(st, icmpmsg_data[i].name, icmpmsg_data[i].value);
+ rrddim_set_by_pointer(st, rd_InEchoReps, (collected_number)snmp_root.icmpmsg_InEchoReps);
+ rrddim_set_by_pointer(st, rd_OutEchoReps, (collected_number)snmp_root.icmpmsg_OutEchoReps);
+ rrddim_set_by_pointer(st, rd_InDestUnreachs, (collected_number)snmp_root.icmpmsg_InDestUnreachs);
+ rrddim_set_by_pointer(st, rd_OutDestUnreachs, (collected_number)snmp_root.icmpmsg_OutDestUnreachs);
+ rrddim_set_by_pointer(st, rd_InRedirects, (collected_number)snmp_root.icmpmsg_InRedirects);
+ rrddim_set_by_pointer(st, rd_OutRedirects, (collected_number)snmp_root.icmpmsg_OutRedirects);
+ rrddim_set_by_pointer(st, rd_InEchos, (collected_number)snmp_root.icmpmsg_InEchos);
+ rrddim_set_by_pointer(st, rd_OutEchos, (collected_number)snmp_root.icmpmsg_OutEchos);
+ rrddim_set_by_pointer(st, rd_InRouterAdvert, (collected_number)snmp_root.icmpmsg_InRouterAdvert);
+ rrddim_set_by_pointer(st, rd_OutRouterAdvert, (collected_number)snmp_root.icmpmsg_OutRouterAdvert);
+ rrddim_set_by_pointer(st, rd_InRouterSelect, (collected_number)snmp_root.icmpmsg_InRouterSelect);
+ rrddim_set_by_pointer(st, rd_OutRouterSelect, (collected_number)snmp_root.icmpmsg_OutRouterSelect);
+ rrddim_set_by_pointer(st, rd_InTimeExcds, (collected_number)snmp_root.icmpmsg_InTimeExcds);
+ rrddim_set_by_pointer(st, rd_OutTimeExcds, (collected_number)snmp_root.icmpmsg_OutTimeExcds);
+ rrddim_set_by_pointer(st, rd_InParmProbs, (collected_number)snmp_root.icmpmsg_InParmProbs);
+ rrddim_set_by_pointer(st, rd_OutParmProbs, (collected_number)snmp_root.icmpmsg_OutParmProbs);
+ rrddim_set_by_pointer(st, rd_InTimestamps, (collected_number)snmp_root.icmpmsg_InTimestamps);
+ rrddim_set_by_pointer(st, rd_OutTimestamps, (collected_number)snmp_root.icmpmsg_OutTimestamps);
+ rrddim_set_by_pointer(st, rd_InTimestampReps, (collected_number)snmp_root.icmpmsg_InTimestampReps);
+ rrddim_set_by_pointer(st, rd_OutTimestampReps, (collected_number)snmp_root.icmpmsg_OutTimestampReps);
rrdset_done(st);
}
@@ -582,69 +627,132 @@ int do_proc_net_snmp(int update_every, usec_t dt) {
continue;
}
- parse_line_pair(ff, tcp_data, h, l);
+ arl_begin(arl_tcp);
+ for(w = 1; w < words ; w++) {
+ if (unlikely(arl_check(arl_tcp, procfile_lineword(ff, h, w), procfile_lineword(ff, l, w)) != 0))
+ break;
+ }
+
+ // --------------------------------------------------------------------
+
+ if(snmp_root.tcp_MaxConn != last_max_connections) {
+ last_max_connections = snmp_root.tcp_MaxConn;
+ rrdvar_custom_host_variable_set(localhost, tcp_max_connections_var, last_max_connections);
+ }
// --------------------------------------------------------------------
// see http://net-snmp.sourceforge.net/docs/mibs/tcp.html
if(do_tcp_sockets) {
- st = rrdset_find_localhost(RRD_TYPE_NET_SNMP ".tcpsock");
- if(!st) {
- st = rrdset_create_localhost(RRD_TYPE_NET_SNMP, "tcpsock", NULL, "tcp", NULL, "IPv4 TCP Connections"
- , "active connections", 2500, update_every, RRDSET_TYPE_LINE);
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_CurrEstab = NULL;
- rrddim_add(st, "CurrEstab", "connections", 1, 1, RRD_ALGORITHM_ABSOLUTE);
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_SNMP
+ , "tcpsock"
+ , NULL
+ , "tcp"
+ , NULL
+ , "IPv4 TCP Connections"
+ , "active connections"
+ , "proc"
+ , "net/snmp"
+ , 2501
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rd_CurrEstab = rrddim_add(st, "CurrEstab", "connections", 1, 1, RRD_ALGORITHM_ABSOLUTE);
}
else rrdset_next(st);
- rrddim_set(st, "CurrEstab", *tcp_CurrEstab);
+ rrddim_set_by_pointer(st, rd_CurrEstab, (collected_number)snmp_root.tcp_CurrEstab);
rrdset_done(st);
}
// --------------------------------------------------------------------
if(do_tcp_packets) {
- st = rrdset_find_localhost(RRD_TYPE_NET_SNMP ".tcppackets");
- if(!st) {
- st = rrdset_create_localhost(RRD_TYPE_NET_SNMP, "tcppackets", NULL, "tcp", NULL, "IPv4 TCP Packets"
- , "packets/s", 2600, update_every, RRDSET_TYPE_LINE);
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_InSegs = NULL,
+ *rd_OutSegs = NULL;
+
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_SNMP
+ , "tcppackets"
+ , NULL
+ , "tcp"
+ , NULL
+ , "IPv4 TCP Packets"
+ , "packets/s"
+ , "proc"
+ , "net/snmp"
+ , 2510
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
- rrddim_add(st, "InSegs", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "OutSegs", "sent", -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InSegs = rrddim_add(st, "InSegs", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutSegs = rrddim_add(st, "OutSegs", "sent", -1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "InSegs", *tcp_InSegs);
- rrddim_set(st, "OutSegs", *tcp_OutSegs);
+ rrddim_set_by_pointer(st, rd_InSegs, (collected_number)snmp_root.tcp_InSegs);
+ rrddim_set_by_pointer(st, rd_OutSegs, (collected_number)snmp_root.tcp_OutSegs);
rrdset_done(st);
}
// --------------------------------------------------------------------
if(do_tcp_errors) {
- st = rrdset_find_localhost(RRD_TYPE_NET_SNMP ".tcperrors");
- if(!st) {
- st = rrdset_create_localhost(RRD_TYPE_NET_SNMP, "tcperrors", NULL, "tcp", NULL, "IPv4 TCP Errors"
- , "packets/s", 2700, update_every, RRDSET_TYPE_LINE);
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_InErrs = NULL,
+ *rd_InCsumErrors = NULL,
+ *rd_RetransSegs = NULL;
+
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_SNMP
+ , "tcperrors"
+ , NULL
+ , "tcp"
+ , NULL
+ , "IPv4 TCP Errors"
+ , "packets/s"
+ , "proc"
+ , "net/snmp"
+ , 2520
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
- rrddim_add(st, "InErrs", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "InCsumErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "RetransSegs", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InErrs = rrddim_add(st, "InErrs", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InCsumErrors = rrddim_add(st, "InCsumErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_RetransSegs = rrddim_add(st, "RetransSegs", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "InErrs", *tcp_InErrs);
- rrddim_set(st, "InCsumErrors", *tcp_InCsumErrors);
- rrddim_set(st, "RetransSegs", *tcp_RetransSegs);
+ rrddim_set_by_pointer(st, rd_InErrs, (collected_number)snmp_root.tcp_InErrs);
+ rrddim_set_by_pointer(st, rd_InCsumErrors, (collected_number)snmp_root.tcp_InCsumErrors);
+ rrddim_set_by_pointer(st, rd_RetransSegs, (collected_number)snmp_root.tcp_RetransSegs);
rrdset_done(st);
}
// --------------------------------------------------------------------
if(do_tcp_handshake) {
- st = rrdset_find_localhost(RRD_TYPE_NET_SNMP ".tcphandshake");
- if(!st) {
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_EstabResets = NULL,
+ *rd_OutRsts = NULL,
+ *rd_ActiveOpens = NULL,
+ *rd_PassiveOpens = NULL,
+ *rd_AttemptFails = NULL,
+ *rd_TCPSynRetrans = NULL;
+
+ if(unlikely(!st)) {
st = rrdset_create_localhost(
RRD_TYPE_NET_SNMP
, "tcphandshake"
@@ -653,27 +761,29 @@ int do_proc_net_snmp(int update_every, usec_t dt) {
, NULL
, "IPv4 TCP Handshake Issues"
, "events/s"
- , 2900
+ , "proc"
+ , "net/snmp"
+ , 2530
, update_every
, RRDSET_TYPE_LINE
);
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
- rrddim_add(st, "EstabResets", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "OutRsts", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "ActiveOpens", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "PassiveOpens", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "AttemptFails", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "TCPSynRetrans", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_EstabResets = rrddim_add(st, "EstabResets", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutRsts = rrddim_add(st, "OutRsts", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_ActiveOpens = rrddim_add(st, "ActiveOpens", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_PassiveOpens = rrddim_add(st, "PassiveOpens", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_AttemptFails = rrddim_add(st, "AttemptFails", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_TCPSynRetrans = rrddim_add(st, "TCPSynRetrans", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "EstabResets", *tcp_EstabResets);
- rrddim_set(st, "OutRsts", *tcp_OutRsts);
- rrddim_set(st, "ActiveOpens", *tcp_ActiveOpens);
- rrddim_set(st, "PassiveOpens", *tcp_PassiveOpens);
- rrddim_set(st, "AttemptFails", *tcp_AttemptFails);
- rrddim_set(st, "TCPSynRetrans", tcpext_TCPSynRetrans);
+ rrddim_set_by_pointer(st, rd_EstabResets, (collected_number)snmp_root.tcp_EstabResets);
+ rrddim_set_by_pointer(st, rd_OutRsts, (collected_number)snmp_root.tcp_OutRsts);
+ rrddim_set_by_pointer(st, rd_ActiveOpens, (collected_number)snmp_root.tcp_ActiveOpens);
+ rrddim_set_by_pointer(st, rd_PassiveOpens, (collected_number)snmp_root.tcp_PassiveOpens);
+ rrddim_set_by_pointer(st, rd_AttemptFails, (collected_number)snmp_root.tcp_AttemptFails);
+ rrddim_set_by_pointer(st, rd_TCPSynRetrans, tcpext_TCPSynRetrans);
rrdset_done(st);
}
}
@@ -691,51 +801,89 @@ int do_proc_net_snmp(int update_every, usec_t dt) {
continue;
}
- parse_line_pair(ff, udp_data, h, l);
+ arl_begin(arl_udp);
+ for(w = 1; w < words ; w++) {
+ if (unlikely(arl_check(arl_udp, procfile_lineword(ff, h, w), procfile_lineword(ff, l, w)) != 0))
+ break;
+ }
// --------------------------------------------------------------------
// see http://net-snmp.sourceforge.net/docs/mibs/udp.html
if(do_udp_packets) {
- st = rrdset_find_localhost(RRD_TYPE_NET_SNMP ".udppackets");
- if(!st) {
- st = rrdset_create_localhost(RRD_TYPE_NET_SNMP, "udppackets", NULL, "udp", NULL, "IPv4 UDP Packets"
- , "packets/s", 2601, update_every, RRDSET_TYPE_LINE);
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_InDatagrams = NULL,
+ *rd_OutDatagrams = NULL;
- rrddim_add(st, "InDatagrams", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "OutDatagrams", "sent", -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_SNMP
+ , "udppackets"
+ , NULL
+ , "udp"
+ , NULL
+ , "IPv4 UDP Packets"
+ , "packets/s"
+ , "proc"
+ , "net/snmp"
+ , 2602
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rd_InDatagrams = rrddim_add(st, "InDatagrams", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutDatagrams = rrddim_add(st, "OutDatagrams", "sent", -1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "InDatagrams", *udp_InDatagrams);
- rrddim_set(st, "OutDatagrams", *udp_OutDatagrams);
+ rrddim_set_by_pointer(st, rd_InDatagrams, (collected_number)snmp_root.udp_InDatagrams);
+ rrddim_set_by_pointer(st, rd_OutDatagrams, (collected_number)snmp_root.udp_OutDatagrams);
rrdset_done(st);
}
// --------------------------------------------------------------------
if(do_udp_errors) {
- st = rrdset_find_localhost(RRD_TYPE_NET_SNMP ".udperrors");
- if(!st) {
- st = rrdset_create_localhost(RRD_TYPE_NET_SNMP, "udperrors", NULL, "udp", NULL, "IPv4 UDP Errors"
- , "events/s", 2701, update_every, RRDSET_TYPE_LINE);
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_RcvbufErrors = NULL,
+ *rd_SndbufErrors = NULL,
+ *rd_InErrors = NULL,
+ *rd_NoPorts = NULL,
+ *rd_InCsumErrors = NULL,
+ *rd_IgnoredMulti = NULL;
+
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_SNMP
+ , "udperrors"
+ , NULL
+ , "udp"
+ , NULL
+ , "IPv4 UDP Errors"
+ , "events/s"
+ , "proc"
+ , "net/snmp"
+ , 2701
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
- rrddim_add(st, "RcvbufErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "SndbufErrors", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "InErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "NoPorts", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "InCsumErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "IgnoredMulti", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_RcvbufErrors = rrddim_add(st, "RcvbufErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_SndbufErrors = rrddim_add(st, "SndbufErrors", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InErrors = rrddim_add(st, "InErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_NoPorts = rrddim_add(st, "NoPorts", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InCsumErrors = rrddim_add(st, "InCsumErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_IgnoredMulti = rrddim_add(st, "IgnoredMulti", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "InErrors", *udp_InErrors);
- rrddim_set(st, "NoPorts", *udp_NoPorts);
- rrddim_set(st, "RcvbufErrors", *udp_RcvbufErrors);
- rrddim_set(st, "SndbufErrors", *udp_SndbufErrors);
- rrddim_set(st, "InCsumErrors", *udp_InCsumErrors);
- rrddim_set(st, "IgnoredMulti", *udp_IgnoredMulti);
+ rrddim_set_by_pointer(st, rd_InErrors, (collected_number)snmp_root.udp_InErrors);
+ rrddim_set_by_pointer(st, rd_NoPorts, (collected_number)snmp_root.udp_NoPorts);
+ rrddim_set_by_pointer(st, rd_RcvbufErrors, (collected_number)snmp_root.udp_RcvbufErrors);
+ rrddim_set_by_pointer(st, rd_SndbufErrors, (collected_number)snmp_root.udp_SndbufErrors);
+ rrddim_set_by_pointer(st, rd_InCsumErrors, (collected_number)snmp_root.udp_InCsumErrors);
+ rrddim_set_by_pointer(st, rd_IgnoredMulti, (collected_number)snmp_root.udp_IgnoredMulti);
rrdset_done(st);
}
}
@@ -753,48 +901,87 @@ int do_proc_net_snmp(int update_every, usec_t dt) {
continue;
}
- parse_line_pair(ff, udplite_data, h, l);
+ arl_begin(arl_udplite);
+ for(w = 1; w < words ; w++) {
+ if (unlikely(arl_check(arl_udplite, procfile_lineword(ff, h, w), procfile_lineword(ff, l, w)) != 0))
+ break;
+ }
// --------------------------------------------------------------------
if(do_udplite_packets) {
- st = rrdset_find_localhost(RRD_TYPE_NET_SNMP ".udplite");
- if(!st) {
- st = rrdset_create_localhost(RRD_TYPE_NET_SNMP, "udplite", NULL, "udplite", NULL
- , "IPv4 UDPLite Packets", "packets/s", 2603, update_every
- , RRDSET_TYPE_LINE);
-
- rrddim_add(st, "InDatagrams", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "OutDatagrams", "sent", -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ {
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_InDatagrams = NULL,
+ *rd_OutDatagrams = NULL;
+
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_SNMP
+ , "udplite"
+ , NULL
+ , "udplite"
+ , NULL
+ , "IPv4 UDPLite Packets"
+ , "packets/s"
+ , "proc"
+ , "net/snmp"
+ , 2603
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rd_InDatagrams = rrddim_add(st, "InDatagrams", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutDatagrams = rrddim_add(st, "OutDatagrams", "sent", -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ }
+ else rrdset_next(st);
+
+ rrddim_set_by_pointer(st, rd_InDatagrams, (collected_number)snmp_root.udplite_InDatagrams);
+ rrddim_set_by_pointer(st, rd_OutDatagrams, (collected_number)snmp_root.udplite_OutDatagrams);
+ rrdset_done(st);
}
- else rrdset_next(st);
-
- rrddim_set(st, "InDatagrams", *udplite_InDatagrams);
- rrddim_set(st, "OutDatagrams", *udplite_OutDatagrams);
- rrdset_done(st);
- st = rrdset_find_localhost(RRD_TYPE_NET_SNMP ".udplite_errors");
- if(!st) {
- st = rrdset_create_localhost(RRD_TYPE_NET_SNMP, "udplite_errors", NULL, "udplite", NULL
- , "IPv4 UDPLite Errors", "packets/s", 2604, update_every
- , RRDSET_TYPE_LINE);
-
- rrddim_add(st, "RcvbufErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "SndbufErrors", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "NoPorts", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "IgnoredMulti", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "InErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "InCsumErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ {
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_RcvbufErrors = NULL,
+ *rd_SndbufErrors = NULL,
+ *rd_InErrors = NULL,
+ *rd_NoPorts = NULL,
+ *rd_InCsumErrors = NULL,
+ *rd_IgnoredMulti = NULL;
+
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_SNMP
+ , "udplite_errors"
+ , NULL
+ , "udplite"
+ , NULL
+ , "IPv4 UDPLite Errors"
+ , "packets/s"
+ , "proc"
+ , "net/snmp"
+ , 2604
+ , update_every
+ , RRDSET_TYPE_LINE);
+
+ rd_RcvbufErrors = rrddim_add(st, "RcvbufErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_SndbufErrors = rrddim_add(st, "SndbufErrors", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InErrors = rrddim_add(st, "InErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_NoPorts = rrddim_add(st, "NoPorts", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InCsumErrors = rrddim_add(st, "InCsumErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_IgnoredMulti = rrddim_add(st, "IgnoredMulti", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ }
+ else rrdset_next(st);
+
+ rrddim_set_by_pointer(st, rd_NoPorts, (collected_number)snmp_root.udplite_NoPorts);
+ rrddim_set_by_pointer(st, rd_InErrors, (collected_number)snmp_root.udplite_InErrors);
+ rrddim_set_by_pointer(st, rd_InCsumErrors, (collected_number)snmp_root.udplite_InCsumErrors);
+ rrddim_set_by_pointer(st, rd_RcvbufErrors, (collected_number)snmp_root.udplite_RcvbufErrors);
+ rrddim_set_by_pointer(st, rd_SndbufErrors, (collected_number)snmp_root.udplite_SndbufErrors);
+ rrddim_set_by_pointer(st, rd_IgnoredMulti, (collected_number)snmp_root.udplite_IgnoredMulti);
+ rrdset_done(st);
}
- else rrdset_next(st);
-
- rrddim_set(st, "NoPorts", *udplite_NoPorts);
- rrddim_set(st, "InErrors", *udplite_InErrors);
- rrddim_set(st, "InCsumErrors", *udplite_InCsumErrors);
- rrddim_set(st, "RcvbufErrors", *udplite_RcvbufErrors);
- rrddim_set(st, "SndbufErrors", *udplite_SndbufErrors);
- rrddim_set(st, "IgnoredMulti", *udplite_IgnoredMulti);
- rrdset_done(st);
}
}
}
diff --git a/src/proc_net_snmp6.c b/src/proc_net_snmp6.c
index 6649b7af..bd71b391 100644
--- a/src/proc_net_snmp6.c
+++ b/src/proc_net_snmp6.c
@@ -272,24 +272,37 @@ int do_proc_net_snmp6(int update_every, usec_t dt) {
procfile_lineword(ff, l, 1)))) break;
}
- RRDSET *st;
-
// --------------------------------------------------------------------
if(do_bandwidth == CONFIG_BOOLEAN_YES || (do_bandwidth == CONFIG_BOOLEAN_AUTO && (Ip6InOctets || Ip6OutOctets))) {
do_bandwidth = CONFIG_BOOLEAN_YES;
- st = rrdset_find_localhost("system.ipv6");
- if(unlikely(!st)) {
- st = rrdset_create_localhost("system", "ipv6", NULL, "network", NULL, "IPv6 Bandwidth", "kilobits/s", 500
- , update_every, RRDSET_TYPE_AREA);
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_received = NULL,
+ *rd_sent = NULL;
- rrddim_add(st, "received", NULL, 8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "sent", NULL, -8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "system"
+ , "ipv6"
+ , NULL
+ , "network"
+ , NULL
+ , "IPv6 Bandwidth"
+ , "kilobits/s"
+ , "proc"
+ , "net/snmp6"
+ , 502
+ , update_every
+ , RRDSET_TYPE_AREA
+ );
+
+ rd_received = rrddim_add(st, "InOctets", "received", 8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
+ rd_sent = rrddim_add(st, "OutOctets", "sent", -8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "sent", Ip6OutOctets);
- rrddim_set(st, "received", Ip6InOctets);
+ rrddim_set_by_pointer(st, rd_received, Ip6InOctets);
+ rrddim_set_by_pointer(st, rd_sent, Ip6OutOctets);
rrdset_done(st);
}
@@ -297,22 +310,39 @@ int do_proc_net_snmp6(int update_every, usec_t dt) {
if(do_ip_packets == CONFIG_BOOLEAN_YES || (do_ip_packets == CONFIG_BOOLEAN_AUTO && (Ip6InReceives || Ip6OutRequests || Ip6InDelivers || Ip6OutForwDatagrams))) {
do_ip_packets = CONFIG_BOOLEAN_YES;
- st = rrdset_find_localhost(RRD_TYPE_NET_SNMP6 ".packets");
- if(unlikely(!st)) {
- st = rrdset_create_localhost(RRD_TYPE_NET_SNMP6, "packets", NULL, "packets", NULL, "IPv6 Packets"
- , "packets/s", 3000, update_every, RRDSET_TYPE_LINE);
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_received = NULL,
+ *rd_sent = NULL,
+ *rd_forwarded = NULL,
+ *rd_delivers = NULL;
- rrddim_add(st, "received", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "sent", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "forwarded", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "delivers", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_SNMP6
+ , "packets"
+ , NULL
+ , "packets"
+ , NULL
+ , "IPv6 Packets"
+ , "packets/s"
+ , "proc"
+ , "net/snmp6"
+ , 3000
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rd_received = rrddim_add(st, "InReceives", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_sent = rrddim_add(st, "OutRequests", "sent", -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_forwarded = rrddim_add(st, "OutForwDatagrams", "forwarded", -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_delivers = rrddim_add(st, "InDelivers", "delivers", 1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "sent", Ip6OutRequests);
- rrddim_set(st, "received", Ip6InReceives);
- rrddim_set(st, "forwarded", Ip6OutForwDatagrams);
- rrddim_set(st, "delivers", Ip6InDelivers);
+ rrddim_set_by_pointer(st, rd_received, Ip6InReceives);
+ rrddim_set_by_pointer(st, rd_sent, Ip6OutRequests);
+ rrddim_set_by_pointer(st, rd_forwarded, Ip6OutForwDatagrams);
+ rrddim_set_by_pointer(st, rd_delivers, Ip6InDelivers);
rrdset_done(st);
}
@@ -320,21 +350,37 @@ int do_proc_net_snmp6(int update_every, usec_t dt) {
if(do_ip_fragsout == CONFIG_BOOLEAN_YES || (do_ip_fragsout == CONFIG_BOOLEAN_AUTO && (Ip6FragOKs || Ip6FragFails || Ip6FragCreates))) {
do_ip_fragsout = CONFIG_BOOLEAN_YES;
- st = rrdset_find_localhost(RRD_TYPE_NET_SNMP6 ".fragsout");
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_ok = NULL,
+ *rd_failed = NULL,
+ *rd_all = NULL;
+
if(unlikely(!st)) {
- st = rrdset_create_localhost(RRD_TYPE_NET_SNMP6, "fragsout", NULL, "fragments", NULL, "IPv6 Fragments Sent"
- , "packets/s", 3010, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_SNMP6
+ , "fragsout"
+ , NULL
+ , "fragments6"
+ , NULL
+ , "IPv6 Fragments Sent"
+ , "packets/s"
+ , "proc"
+ , "net/snmp6"
+ , 3011
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
- rrddim_add(st, "ok", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "failed", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "all", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_ok = rrddim_add(st, "FragOKs", "ok", 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_failed = rrddim_add(st, "FragFails", "failed", -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_all = rrddim_add(st, "FragCreates", "all", 1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "ok", Ip6FragOKs);
- rrddim_set(st, "failed", Ip6FragFails);
- rrddim_set(st, "all", Ip6FragCreates);
+ rrddim_set_by_pointer(st, rd_ok, Ip6FragOKs);
+ rrddim_set_by_pointer(st, rd_failed, Ip6FragFails);
+ rrddim_set_by_pointer(st, rd_all, Ip6FragCreates);
rrdset_done(st);
}
@@ -348,24 +394,40 @@ int do_proc_net_snmp6(int update_every, usec_t dt) {
|| Ip6ReasmReqds
))) {
do_ip_fragsin = CONFIG_BOOLEAN_YES;
- st = rrdset_find_localhost(RRD_TYPE_NET_SNMP6 ".fragsin");
+
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_ok = NULL,
+ *rd_failed = NULL,
+ *rd_timeout = NULL,
+ *rd_all = NULL;
+
if(unlikely(!st)) {
- st = rrdset_create_localhost(RRD_TYPE_NET_SNMP6, "fragsin", NULL, "fragments", NULL
- , "IPv6 Fragments Reassembly", "packets/s", 3011, update_every
- , RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_SNMP6
+ , "fragsin"
+ , NULL
+ , "fragments6"
+ , NULL
+ , "IPv6 Fragments Reassembly"
+ , "packets/s"
+ , "proc"
+ , "net/snmp6"
+ , 3012
+ , update_every
+ , RRDSET_TYPE_LINE);
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
- rrddim_add(st, "ok", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "failed", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "timeout", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "all", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_ok = rrddim_add(st, "ReasmOKs", "ok", 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_failed = rrddim_add(st, "ReasmFails", "failed", -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_timeout = rrddim_add(st, "ReasmTimeout", "timeout", -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_all = rrddim_add(st, "ReasmReqds", "all", 1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "ok", Ip6ReasmOKs);
- rrddim_set(st, "failed", Ip6ReasmFails);
- rrddim_set(st, "timeout", Ip6ReasmTimeout);
- rrddim_set(st, "all", Ip6ReasmReqds);
+ rrddim_set_by_pointer(st, rd_ok, Ip6ReasmOKs);
+ rrddim_set_by_pointer(st, rd_failed, Ip6ReasmFails);
+ rrddim_set_by_pointer(st, rd_timeout, Ip6ReasmTimeout);
+ rrddim_set_by_pointer(st, rd_all, Ip6ReasmReqds);
rrdset_done(st);
}
@@ -383,37 +445,55 @@ int do_proc_net_snmp6(int update_every, usec_t dt) {
|| Ip6InNoRoutes
))) {
do_ip_errors = CONFIG_BOOLEAN_YES;
- st = rrdset_find_localhost(RRD_TYPE_NET_SNMP6 ".errors");
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_InDiscards = NULL,
+ *rd_OutDiscards = NULL,
+ *rd_InHdrErrors = NULL,
+ *rd_InAddrErrors = NULL,
+ *rd_InUnknownProtos = NULL,
+ *rd_InTooBigErrors = NULL,
+ *rd_InTruncatedPkts = NULL,
+ *rd_InNoRoutes = NULL,
+ *rd_OutNoRoutes = NULL;
+
if(unlikely(!st)) {
- st = rrdset_create_localhost(RRD_TYPE_NET_SNMP6, "errors", NULL, "errors", NULL, "IPv6 Errors", "packets/s"
- , 3002, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_SNMP6
+ , "errors"
+ , NULL
+ , "errors"
+ , NULL
+ , "IPv6 Errors"
+ , "packets/s"
+ , "proc"
+ , "net/snmp6"
+ , 3002
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
- rrddim_add(st, "InDiscards", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "OutDiscards", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
-
- rrddim_add(st, "InHdrErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "InAddrErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "InUnknownProtos", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "InTooBigErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "InTruncatedPkts", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "InNoRoutes", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
-
- rrddim_add(st, "OutNoRoutes", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InDiscards = rrddim_add(st, "InDiscards", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutDiscards = rrddim_add(st, "OutDiscards", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InHdrErrors = rrddim_add(st, "InHdrErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InAddrErrors = rrddim_add(st, "InAddrErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InUnknownProtos = rrddim_add(st, "InUnknownProtos", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InTooBigErrors = rrddim_add(st, "InTooBigErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InTruncatedPkts = rrddim_add(st, "InTruncatedPkts", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InNoRoutes = rrddim_add(st, "InNoRoutes", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutNoRoutes = rrddim_add(st, "OutNoRoutes", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "InDiscards", Ip6InDiscards);
- rrddim_set(st, "OutDiscards", Ip6OutDiscards);
-
- rrddim_set(st, "InHdrErrors", Ip6InHdrErrors);
- rrddim_set(st, "InAddrErrors", Ip6InAddrErrors);
- rrddim_set(st, "InUnknownProtos", Ip6InUnknownProtos);
- rrddim_set(st, "InTooBigErrors", Ip6InTooBigErrors);
- rrddim_set(st, "InTruncatedPkts", Ip6InTruncatedPkts);
- rrddim_set(st, "InNoRoutes", Ip6InNoRoutes);
-
- rrddim_set(st, "OutNoRoutes", Ip6OutNoRoutes);
+ rrddim_set_by_pointer(st, rd_InDiscards, Ip6InDiscards);
+ rrddim_set_by_pointer(st, rd_OutDiscards, Ip6OutDiscards);
+ rrddim_set_by_pointer(st, rd_InHdrErrors, Ip6InHdrErrors);
+ rrddim_set_by_pointer(st, rd_InAddrErrors, Ip6InAddrErrors);
+ rrddim_set_by_pointer(st, rd_InUnknownProtos, Ip6InUnknownProtos);
+ rrddim_set_by_pointer(st, rd_InTooBigErrors, Ip6InTooBigErrors);
+ rrddim_set_by_pointer(st, rd_InTruncatedPkts, Ip6InTruncatedPkts);
+ rrddim_set_by_pointer(st, rd_InNoRoutes, Ip6InNoRoutes);
+ rrddim_set_by_pointer(st, rd_OutNoRoutes, Ip6OutNoRoutes);
rrdset_done(st);
}
@@ -421,18 +501,33 @@ int do_proc_net_snmp6(int update_every, usec_t dt) {
if(do_udp_packets == CONFIG_BOOLEAN_YES || (do_udp_packets == CONFIG_BOOLEAN_AUTO && (Udp6InDatagrams || Udp6OutDatagrams))) {
do_udp_packets = CONFIG_BOOLEAN_YES;
- st = rrdset_find_localhost(RRD_TYPE_NET_SNMP6 ".udppackets");
- if(unlikely(!st)) {
- st = rrdset_create_localhost(RRD_TYPE_NET_SNMP6, "udppackets", NULL, "udp", NULL, "IPv6 UDP Packets"
- , "packets/s", 3601, update_every, RRDSET_TYPE_LINE);
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_received = NULL,
+ *rd_sent = NULL;
- rrddim_add(st, "received", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "sent", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_SNMP6
+ , "udppackets"
+ , NULL
+ , "udp6"
+ , NULL
+ , "IPv6 UDP Packets"
+ , "packets/s"
+ , "proc"
+ , "net/snmp6"
+ , 3601
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rd_received = rrddim_add(st, "InDatagrams", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_sent = rrddim_add(st, "OutDatagrams", "sent", -1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "received", Udp6InDatagrams);
- rrddim_set(st, "sent", Udp6OutDatagrams);
+ rrddim_set_by_pointer(st, rd_received, Udp6InDatagrams);
+ rrddim_set_by_pointer(st, rd_sent, Udp6OutDatagrams);
rrdset_done(st);
}
@@ -448,27 +543,46 @@ int do_proc_net_snmp6(int update_every, usec_t dt) {
|| Udp6IgnoredMulti
))) {
do_udp_errors = CONFIG_BOOLEAN_YES;
- st = rrdset_find_localhost(RRD_TYPE_NET_SNMP6 ".udperrors");
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_RcvbufErrors = NULL,
+ *rd_SndbufErrors = NULL,
+ *rd_InErrors = NULL,
+ *rd_NoPorts = NULL,
+ *rd_InCsumErrors = NULL,
+ *rd_IgnoredMulti = NULL;
+
if(unlikely(!st)) {
- st = rrdset_create_localhost(RRD_TYPE_NET_SNMP6, "udperrors", NULL, "udp", NULL, "IPv6 UDP Errors"
- , "events/s", 3701, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_SNMP6
+ , "udperrors"
+ , NULL
+ , "udp6"
+ , NULL
+ , "IPv6 UDP Errors"
+ , "events/s"
+ , "proc"
+ , "net/snmp6"
+ , 3701
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
- rrddim_add(st, "RcvbufErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "SndbufErrors", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "InErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "NoPorts", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "InCsumErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "IgnoredMulti", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_RcvbufErrors = rrddim_add(st, "RcvbufErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_SndbufErrors = rrddim_add(st, "SndbufErrors", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InErrors = rrddim_add(st, "InErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_NoPorts = rrddim_add(st, "NoPorts", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InCsumErrors = rrddim_add(st, "InCsumErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_IgnoredMulti = rrddim_add(st, "IgnoredMulti", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "InErrors", Udp6InErrors);
- rrddim_set(st, "NoPorts", Udp6NoPorts);
- rrddim_set(st, "RcvbufErrors", Udp6RcvbufErrors);
- rrddim_set(st, "SndbufErrors", Udp6SndbufErrors);
- rrddim_set(st, "InCsumErrors", Udp6InCsumErrors);
- rrddim_set(st, "IgnoredMulti", Udp6IgnoredMulti);
+ rrddim_set_by_pointer(st, rd_RcvbufErrors, Udp6RcvbufErrors);
+ rrddim_set_by_pointer(st, rd_SndbufErrors, Udp6SndbufErrors);
+ rrddim_set_by_pointer(st, rd_InErrors, Udp6InErrors);
+ rrddim_set_by_pointer(st, rd_NoPorts, Udp6NoPorts);
+ rrddim_set_by_pointer(st, rd_InCsumErrors, Udp6InCsumErrors);
+ rrddim_set_by_pointer(st, rd_IgnoredMulti, Udp6IgnoredMulti);
rrdset_done(st);
}
@@ -476,18 +590,33 @@ int do_proc_net_snmp6(int update_every, usec_t dt) {
if(do_udplite_packets == CONFIG_BOOLEAN_YES || (do_udplite_packets == CONFIG_BOOLEAN_AUTO && (UdpLite6InDatagrams || UdpLite6OutDatagrams))) {
do_udplite_packets = CONFIG_BOOLEAN_YES;
- st = rrdset_find_localhost(RRD_TYPE_NET_SNMP6 ".udplitepackets");
- if(unlikely(!st)) {
- st = rrdset_create_localhost(RRD_TYPE_NET_SNMP6, "udplitepackets", NULL, "udplite", NULL
- , "IPv6 UDPlite Packets", "packets/s", 3601, update_every, RRDSET_TYPE_LINE);
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_received = NULL,
+ *rd_sent = NULL;
- rrddim_add(st, "received", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "sent", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_SNMP6
+ , "udplitepackets"
+ , NULL
+ , "udplite6"
+ , NULL
+ , "IPv6 UDPlite Packets"
+ , "packets/s"
+ , "proc"
+ , "net/snmp6"
+ , 3602
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rd_received = rrddim_add(st, "InDatagrams", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_sent = rrddim_add(st, "OutDatagrams", "sent", -1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "received", UdpLite6InDatagrams);
- rrddim_set(st, "sent", UdpLite6OutDatagrams);
+ rrddim_set_by_pointer(st, rd_received, UdpLite6InDatagrams);
+ rrddim_set_by_pointer(st, rd_sent, UdpLite6OutDatagrams);
rrdset_done(st);
}
@@ -503,25 +632,43 @@ int do_proc_net_snmp6(int update_every, usec_t dt) {
|| UdpLite6InCsumErrors
))) {
do_udplite_errors = CONFIG_BOOLEAN_YES;
- st = rrdset_find_localhost(RRD_TYPE_NET_SNMP6 ".udpliteerrors");
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_RcvbufErrors = NULL,
+ *rd_SndbufErrors = NULL,
+ *rd_InErrors = NULL,
+ *rd_NoPorts = NULL,
+ *rd_InCsumErrors = NULL;
+
if(unlikely(!st)) {
- st = rrdset_create_localhost(RRD_TYPE_NET_SNMP6, "udpliteerrors", NULL, "udplite", NULL
- , "IPv6 UDP Lite Errors", "events/s", 3701, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_SNMP6
+ , "udpliteerrors"
+ , NULL
+ , "udplite6"
+ , NULL
+ , "IPv6 UDP Lite Errors"
+ , "events/s"
+ , "proc"
+ , "net/snmp6"
+ , 3701
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
- rrddim_add(st, "RcvbufErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "SndbufErrors", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "InErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "NoPorts", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "InCsumErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_RcvbufErrors = rrddim_add(st, "RcvbufErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_SndbufErrors = rrddim_add(st, "SndbufErrors", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InErrors = rrddim_add(st, "InErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_NoPorts = rrddim_add(st, "NoPorts", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InCsumErrors = rrddim_add(st, "InCsumErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "InErrors", UdpLite6InErrors);
- rrddim_set(st, "NoPorts", UdpLite6NoPorts);
- rrddim_set(st, "RcvbufErrors", UdpLite6RcvbufErrors);
- rrddim_set(st, "SndbufErrors", UdpLite6SndbufErrors);
- rrddim_set(st, "InCsumErrors", UdpLite6InCsumErrors);
+ rrddim_set_by_pointer(st, rd_InErrors, UdpLite6InErrors);
+ rrddim_set_by_pointer(st, rd_NoPorts, UdpLite6NoPorts);
+ rrddim_set_by_pointer(st, rd_RcvbufErrors, UdpLite6RcvbufErrors);
+ rrddim_set_by_pointer(st, rd_SndbufErrors, UdpLite6SndbufErrors);
+ rrddim_set_by_pointer(st, rd_InCsumErrors, UdpLite6InCsumErrors);
rrdset_done(st);
}
@@ -529,20 +676,34 @@ int do_proc_net_snmp6(int update_every, usec_t dt) {
if(do_mcast == CONFIG_BOOLEAN_YES || (do_mcast == CONFIG_BOOLEAN_AUTO && (Ip6OutMcastOctets || Ip6InMcastOctets))) {
do_mcast = CONFIG_BOOLEAN_YES;
- st = rrdset_find_localhost(RRD_TYPE_NET_SNMP6 ".mcast");
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_Ip6InMcastOctets = NULL,
+ *rd_Ip6OutMcastOctets = NULL;
+
if(unlikely(!st)) {
- st = rrdset_create_localhost(RRD_TYPE_NET_SNMP6, "mcast", NULL, "multicast", NULL
- , "IPv6 Multicast Bandwidth", "kilobits/s", 9000, update_every
- , RRDSET_TYPE_AREA);
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_SNMP6
+ , "mcast"
+ , NULL
+ , "multicast6"
+ , NULL
+ , "IPv6 Multicast Bandwidth"
+ , "kilobits/s"
+ , "proc"
+ , "net/snmp6"
+ , 9000
+ , update_every
+ , RRDSET_TYPE_AREA
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
- rrddim_add(st, "received", NULL, 8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "sent", NULL, -8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
+ rd_Ip6InMcastOctets = rrddim_add(st, "InMcastOctets", "received", 8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
+ rd_Ip6OutMcastOctets = rrddim_add(st, "OutMcastOctets", "sent", -8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "sent", Ip6OutMcastOctets);
- rrddim_set(st, "received", Ip6InMcastOctets);
+ rrddim_set_by_pointer(st, rd_Ip6InMcastOctets, Ip6InMcastOctets);
+ rrddim_set_by_pointer(st, rd_Ip6OutMcastOctets, Ip6OutMcastOctets);
rrdset_done(st);
}
@@ -550,20 +711,34 @@ int do_proc_net_snmp6(int update_every, usec_t dt) {
if(do_bcast == CONFIG_BOOLEAN_YES || (do_bcast == CONFIG_BOOLEAN_AUTO && (Ip6OutBcastOctets || Ip6InBcastOctets))) {
do_bcast = CONFIG_BOOLEAN_YES;
- st = rrdset_find_localhost(RRD_TYPE_NET_SNMP6 ".bcast");
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_Ip6InBcastOctets = NULL,
+ *rd_Ip6OutBcastOctets = NULL;
+
if(unlikely(!st)) {
- st = rrdset_create_localhost(RRD_TYPE_NET_SNMP6, "bcast", NULL, "broadcast", NULL
- , "IPv6 Broadcast Bandwidth", "kilobits/s", 8000, update_every
- , RRDSET_TYPE_AREA);
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_SNMP6
+ , "bcast"
+ , NULL
+ , "broadcast6"
+ , NULL
+ , "IPv6 Broadcast Bandwidth"
+ , "kilobits/s"
+ , "proc"
+ , "net/snmp6"
+ , 8000
+ , update_every
+ , RRDSET_TYPE_AREA
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
- rrddim_add(st, "received", NULL, 8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "sent", NULL, -8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
+ rd_Ip6InBcastOctets = rrddim_add(st, "InBcastOctets", "received", 8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
+ rd_Ip6OutBcastOctets = rrddim_add(st, "OutBcastOctets", "sent", -8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "sent", Ip6OutBcastOctets);
- rrddim_set(st, "received", Ip6InBcastOctets);
+ rrddim_set_by_pointer(st, rd_Ip6InBcastOctets, Ip6InBcastOctets);
+ rrddim_set_by_pointer(st, rd_Ip6OutBcastOctets, Ip6OutBcastOctets);
rrdset_done(st);
}
@@ -571,19 +746,34 @@ int do_proc_net_snmp6(int update_every, usec_t dt) {
if(do_mcast_p == CONFIG_BOOLEAN_YES || (do_mcast_p == CONFIG_BOOLEAN_AUTO && (Ip6OutMcastPkts || Ip6InMcastPkts))) {
do_mcast_p = CONFIG_BOOLEAN_YES;
- st = rrdset_find_localhost(RRD_TYPE_NET_SNMP6 ".mcastpkts");
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_Ip6InMcastPkts = NULL,
+ *rd_Ip6OutMcastPkts = NULL;
+
if(unlikely(!st)) {
- st = rrdset_create_localhost(RRD_TYPE_NET_SNMP6, "mcastpkts", NULL, "multicast", NULL
- , "IPv6 Multicast Packets", "packets/s", 9500, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_SNMP6
+ , "mcastpkts"
+ , NULL
+ , "multicast6"
+ , NULL
+ , "IPv6 Multicast Packets"
+ , "packets/s"
+ , "proc"
+ , "net/snmp6"
+ , 9500
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
- rrddim_add(st, "received", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "sent", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_Ip6InMcastPkts = rrddim_add(st, "InMcastPkts", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_Ip6OutMcastPkts = rrddim_add(st, "OutMcastPkts", "sent", -1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "sent", Ip6OutMcastPkts);
- rrddim_set(st, "received", Ip6InMcastPkts);
+ rrddim_set_by_pointer(st, rd_Ip6InMcastPkts, Ip6InMcastPkts);
+ rrddim_set_by_pointer(st, rd_Ip6OutMcastPkts, Ip6OutMcastPkts);
rrdset_done(st);
}
@@ -591,18 +781,33 @@ int do_proc_net_snmp6(int update_every, usec_t dt) {
if(do_icmp == CONFIG_BOOLEAN_YES || (do_icmp == CONFIG_BOOLEAN_AUTO && (Icmp6InMsgs || Icmp6OutMsgs))) {
do_icmp = CONFIG_BOOLEAN_YES;
- st = rrdset_find_localhost(RRD_TYPE_NET_SNMP6 ".icmp");
- if(unlikely(!st)) {
- st = rrdset_create_localhost(RRD_TYPE_NET_SNMP6, "icmp", NULL, "icmp", NULL, "IPv6 ICMP Messages"
- , "messages/s", 10000, update_every, RRDSET_TYPE_LINE);
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_Icmp6InMsgs = NULL,
+ *rd_Icmp6OutMsgs = NULL;
- rrddim_add(st, "received", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "sent", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_SNMP6
+ , "icmp"
+ , NULL
+ , "icmp6"
+ , NULL
+ , "IPv6 ICMP Messages"
+ , "messages/s"
+ , "proc"
+ , "net/snmp6"
+ , 10000
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rd_Icmp6InMsgs = rrddim_add(st, "InMsgs", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_Icmp6OutMsgs = rrddim_add(st, "OutMsgs", "sent", -1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "sent", Icmp6InMsgs);
- rrddim_set(st, "received", Icmp6OutMsgs);
+ rrddim_set_by_pointer(st, rd_Icmp6InMsgs, Icmp6InMsgs);
+ rrddim_set_by_pointer(st, rd_Icmp6OutMsgs, Icmp6OutMsgs);
rrdset_done(st);
}
@@ -610,18 +815,33 @@ int do_proc_net_snmp6(int update_every, usec_t dt) {
if(do_icmp_redir == CONFIG_BOOLEAN_YES || (do_icmp_redir == CONFIG_BOOLEAN_AUTO && (Icmp6InRedirects || Icmp6OutRedirects))) {
do_icmp_redir = CONFIG_BOOLEAN_YES;
- st = rrdset_find_localhost(RRD_TYPE_NET_SNMP6 ".icmpredir");
- if(unlikely(!st)) {
- st = rrdset_create_localhost(RRD_TYPE_NET_SNMP6, "icmpredir", NULL, "icmp", NULL, "IPv6 ICMP Redirects"
- , "redirects/s", 10050, update_every, RRDSET_TYPE_LINE);
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_Icmp6InRedirects = NULL,
+ *rd_Icmp6OutRedirects = NULL;
- rrddim_add(st, "received", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "sent", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_SNMP6
+ , "icmpredir"
+ , NULL
+ , "icmp6"
+ , NULL
+ , "IPv6 ICMP Redirects"
+ , "redirects/s"
+ , "proc"
+ , "net/snmp6"
+ , 10050
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rd_Icmp6InRedirects = rrddim_add(st, "InRedirects", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_Icmp6OutRedirects = rrddim_add(st, "OutRedirects", "sent", -1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "sent", Icmp6InRedirects);
- rrddim_set(st, "received", Icmp6OutRedirects);
+ rrddim_set_by_pointer(st, rd_Icmp6InRedirects, Icmp6InRedirects);
+ rrddim_set_by_pointer(st, rd_Icmp6OutRedirects, Icmp6OutRedirects);
rrdset_done(st);
}
@@ -642,37 +862,60 @@ int do_proc_net_snmp6(int update_every, usec_t dt) {
|| Icmp6OutParmProblems
))) {
do_icmp_errors = CONFIG_BOOLEAN_YES;
- st = rrdset_find_localhost(RRD_TYPE_NET_SNMP6 ".icmperrors");
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_InErrors = NULL,
+ *rd_OutErrors = NULL,
+ *rd_InCsumErrors = NULL,
+ *rd_InDestUnreachs = NULL,
+ *rd_InPktTooBigs = NULL,
+ *rd_InTimeExcds = NULL,
+ *rd_InParmProblems = NULL,
+ *rd_OutDestUnreachs = NULL,
+ *rd_OutPktTooBigs = NULL,
+ *rd_OutTimeExcds = NULL,
+ *rd_OutParmProblems = NULL;
+
if(unlikely(!st)) {
- st = rrdset_create_localhost(RRD_TYPE_NET_SNMP6, "icmperrors", NULL, "icmp", NULL, "IPv6 ICMP Errors"
- , "errors/s", 10100, update_every, RRDSET_TYPE_LINE);
-
- rrddim_add(st, "InErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "OutErrors", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
-
- rrddim_add(st, "InCsumErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "InDestUnreachs", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "InPktTooBigs", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "InTimeExcds", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "InParmProblems", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "OutDestUnreachs", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "OutPktTooBigs", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "OutTimeExcds", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "OutParmProblems", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_SNMP6
+ , "icmperrors"
+ , NULL
+ , "icmp6"
+ , NULL
+ , "IPv6 ICMP Errors"
+ , "errors/s"
+ , "proc"
+ , "net/snmp6"
+ , 10100
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rd_InErrors = rrddim_add(st, "InErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutErrors = rrddim_add(st, "OutErrors", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InCsumErrors = rrddim_add(st, "InCsumErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InDestUnreachs = rrddim_add(st, "InDestUnreachs", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InPktTooBigs = rrddim_add(st, "InPktTooBigs", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InTimeExcds = rrddim_add(st, "InTimeExcds", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InParmProblems = rrddim_add(st, "InParmProblems", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutDestUnreachs = rrddim_add(st, "OutDestUnreachs", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutPktTooBigs = rrddim_add(st, "OutPktTooBigs", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutTimeExcds = rrddim_add(st, "OutTimeExcds", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutParmProblems = rrddim_add(st, "OutParmProblems", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "InErrors", Icmp6InErrors);
- rrddim_set(st, "OutErrors", Icmp6OutErrors);
- rrddim_set(st, "InCsumErrors", Icmp6InCsumErrors);
- rrddim_set(st, "InDestUnreachs", Icmp6InDestUnreachs);
- rrddim_set(st, "InPktTooBigs", Icmp6InPktTooBigs);
- rrddim_set(st, "InTimeExcds", Icmp6InTimeExcds);
- rrddim_set(st, "InParmProblems", Icmp6InParmProblems);
- rrddim_set(st, "OutDestUnreachs", Icmp6OutDestUnreachs);
- rrddim_set(st, "OutPktTooBigs", Icmp6OutPktTooBigs);
- rrddim_set(st, "OutTimeExcds", Icmp6OutTimeExcds);
- rrddim_set(st, "OutParmProblems", Icmp6OutParmProblems);
+ rrddim_set_by_pointer(st, rd_InErrors, Icmp6InErrors);
+ rrddim_set_by_pointer(st, rd_OutErrors, Icmp6OutErrors);
+ rrddim_set_by_pointer(st, rd_InCsumErrors, Icmp6InCsumErrors);
+ rrddim_set_by_pointer(st, rd_InDestUnreachs, Icmp6InDestUnreachs);
+ rrddim_set_by_pointer(st, rd_InPktTooBigs, Icmp6InPktTooBigs);
+ rrddim_set_by_pointer(st, rd_InTimeExcds, Icmp6InTimeExcds);
+ rrddim_set_by_pointer(st, rd_InParmProblems, Icmp6InParmProblems);
+ rrddim_set_by_pointer(st, rd_OutDestUnreachs, Icmp6OutDestUnreachs);
+ rrddim_set_by_pointer(st, rd_OutPktTooBigs, Icmp6OutPktTooBigs);
+ rrddim_set_by_pointer(st, rd_OutTimeExcds, Icmp6OutTimeExcds);
+ rrddim_set_by_pointer(st, rd_OutParmProblems, Icmp6OutParmProblems);
rrdset_done(st);
}
@@ -686,22 +929,39 @@ int do_proc_net_snmp6(int update_every, usec_t dt) {
|| Icmp6OutEchoReplies
))) {
do_icmp_echos = CONFIG_BOOLEAN_YES;
- st = rrdset_find_localhost(RRD_TYPE_NET_SNMP6 ".icmpechos");
- if(unlikely(!st)) {
- st = rrdset_create_localhost(RRD_TYPE_NET_SNMP6, "icmpechos", NULL, "icmp", NULL, "IPv6 ICMP Echo"
- , "messages/s", 10200, update_every, RRDSET_TYPE_LINE);
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_InEchos = NULL,
+ *rd_OutEchos = NULL,
+ *rd_InEchoReplies = NULL,
+ *rd_OutEchoReplies = NULL;
- rrddim_add(st, "InEchos", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "OutEchos", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "InEchoReplies", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "OutEchoReplies", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_SNMP6
+ , "icmpechos"
+ , NULL
+ , "icmp6"
+ , NULL
+ , "IPv6 ICMP Echo"
+ , "messages/s"
+ , "proc"
+ , "net/snmp6"
+ , 10200
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rd_InEchos = rrddim_add(st, "InEchos", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutEchos = rrddim_add(st, "OutEchos", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InEchoReplies = rrddim_add(st, "InEchoReplies", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutEchoReplies = rrddim_add(st, "OutEchoReplies", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "InEchos", Icmp6InEchos);
- rrddim_set(st, "OutEchos", Icmp6OutEchos);
- rrddim_set(st, "InEchoReplies", Icmp6InEchoReplies);
- rrddim_set(st, "OutEchoReplies", Icmp6OutEchoReplies);
+ rrddim_set_by_pointer(st, rd_InEchos, Icmp6InEchos);
+ rrddim_set_by_pointer(st, rd_OutEchos, Icmp6OutEchos);
+ rrddim_set_by_pointer(st, rd_InEchoReplies, Icmp6InEchoReplies);
+ rrddim_set_by_pointer(st, rd_OutEchoReplies, Icmp6OutEchoReplies);
rrdset_done(st);
}
@@ -717,27 +977,44 @@ int do_proc_net_snmp6(int update_every, usec_t dt) {
|| Icmp6OutGroupMembReductions
))) {
do_icmp_groupmemb = CONFIG_BOOLEAN_YES;
- st = rrdset_find_localhost(RRD_TYPE_NET_SNMP6 ".groupmemb");
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_InQueries = NULL,
+ *rd_OutQueries = NULL,
+ *rd_InResponses = NULL,
+ *rd_OutResponses = NULL,
+ *rd_InReductions = NULL,
+ *rd_OutReductions = NULL;
+
if(unlikely(!st)) {
- st = rrdset_create_localhost(RRD_TYPE_NET_SNMP6, "groupmemb", NULL, "icmp", NULL
- , "IPv6 ICMP Group Membership", "messages/s", 10300, update_every
- , RRDSET_TYPE_LINE);
-
- rrddim_add(st, "InQueries", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "OutQueries", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "InResponses", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "OutResponses", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "InReductions", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "OutReductions", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_SNMP6
+ , "groupmemb"
+ , NULL
+ , "icmp6"
+ , NULL
+ , "IPv6 ICMP Group Membership"
+ , "messages/s"
+ , "proc"
+ , "net/snmp6"
+ , 10300
+ , update_every
+ , RRDSET_TYPE_LINE);
+
+ rd_InQueries = rrddim_add(st, "InQueries", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutQueries = rrddim_add(st, "OutQueries", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InResponses = rrddim_add(st, "InResponses", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutResponses = rrddim_add(st, "OutResponses", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InReductions = rrddim_add(st, "InReductions", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutReductions = rrddim_add(st, "OutReductions", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "InQueries", Icmp6InGroupMembQueries);
- rrddim_set(st, "OutQueries", Icmp6OutGroupMembQueries);
- rrddim_set(st, "InResponses", Icmp6InGroupMembResponses);
- rrddim_set(st, "OutResponses", Icmp6OutGroupMembResponses);
- rrddim_set(st, "InReductions", Icmp6InGroupMembReductions);
- rrddim_set(st, "OutReductions", Icmp6OutGroupMembReductions);
+ rrddim_set_by_pointer(st, rd_InQueries, Icmp6InGroupMembQueries);
+ rrddim_set_by_pointer(st, rd_OutQueries, Icmp6OutGroupMembQueries);
+ rrddim_set_by_pointer(st, rd_InResponses, Icmp6InGroupMembResponses);
+ rrddim_set_by_pointer(st, rd_OutResponses, Icmp6OutGroupMembResponses);
+ rrddim_set_by_pointer(st, rd_InReductions, Icmp6InGroupMembReductions);
+ rrddim_set_by_pointer(st, rd_OutReductions, Icmp6OutGroupMembReductions);
rrdset_done(st);
}
@@ -751,22 +1028,39 @@ int do_proc_net_snmp6(int update_every, usec_t dt) {
|| Icmp6OutRouterAdvertisements
))) {
do_icmp_router = CONFIG_BOOLEAN_YES;
- st = rrdset_find_localhost(RRD_TYPE_NET_SNMP6 ".icmprouter");
- if(unlikely(!st)) {
- st = rrdset_create_localhost(RRD_TYPE_NET_SNMP6, "icmprouter", NULL, "icmp", NULL, "IPv6 Router Messages"
- , "messages/s", 10400, update_every, RRDSET_TYPE_LINE);
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_InSolicits = NULL,
+ *rd_OutSolicits = NULL,
+ *rd_InAdvertisements = NULL,
+ *rd_OutAdvertisements = NULL;
- rrddim_add(st, "InSolicits", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "OutSolicits", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "InAdvertisements", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "OutAdvertisements", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_SNMP6
+ , "icmprouter"
+ , NULL
+ , "icmp6"
+ , NULL
+ , "IPv6 Router Messages"
+ , "messages/s"
+ , "proc"
+ , "net/snmp6"
+ , 10400
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rd_InSolicits = rrddim_add(st, "InSolicits", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutSolicits = rrddim_add(st, "OutSolicits", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InAdvertisements = rrddim_add(st, "InAdvertisements", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutAdvertisements = rrddim_add(st, "OutAdvertisements", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "InSolicits", Icmp6InRouterSolicits);
- rrddim_set(st, "OutSolicits", Icmp6OutRouterSolicits);
- rrddim_set(st, "InAdvertisements", Icmp6InRouterAdvertisements);
- rrddim_set(st, "OutAdvertisements", Icmp6OutRouterAdvertisements);
+ rrddim_set_by_pointer(st, rd_InSolicits, Icmp6InRouterSolicits);
+ rrddim_set_by_pointer(st, rd_OutSolicits, Icmp6OutRouterSolicits);
+ rrddim_set_by_pointer(st, rd_InAdvertisements, Icmp6InRouterAdvertisements);
+ rrddim_set_by_pointer(st, rd_OutAdvertisements, Icmp6OutRouterAdvertisements);
rrdset_done(st);
}
@@ -780,23 +1074,39 @@ int do_proc_net_snmp6(int update_every, usec_t dt) {
|| Icmp6OutNeighborAdvertisements
))) {
do_icmp_neighbor = CONFIG_BOOLEAN_YES;
- st = rrdset_find_localhost(RRD_TYPE_NET_SNMP6 ".icmpneighbor");
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_InSolicits = NULL,
+ *rd_OutSolicits = NULL,
+ *rd_InAdvertisements = NULL,
+ *rd_OutAdvertisements = NULL;
+
if(unlikely(!st)) {
- st = rrdset_create_localhost(RRD_TYPE_NET_SNMP6, "icmpneighbor", NULL, "icmp", NULL
- , "IPv6 Neighbor Messages", "messages/s", 10500, update_every
- , RRDSET_TYPE_LINE);
-
- rrddim_add(st, "InSolicits", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "OutSolicits", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "InAdvertisements", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "OutAdvertisements", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_SNMP6
+ , "icmpneighbor"
+ , NULL
+ , "icmp6"
+ , NULL
+ , "IPv6 Neighbor Messages"
+ , "messages/s"
+ , "proc"
+ , "net/snmp6"
+ , 10500
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rd_InSolicits = rrddim_add(st, "InSolicits", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutSolicits = rrddim_add(st, "OutSolicits", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InAdvertisements = rrddim_add(st, "InAdvertisements", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutAdvertisements = rrddim_add(st, "OutAdvertisements", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "InSolicits", Icmp6InNeighborSolicits);
- rrddim_set(st, "OutSolicits", Icmp6OutNeighborSolicits);
- rrddim_set(st, "InAdvertisements", Icmp6InNeighborAdvertisements);
- rrddim_set(st, "OutAdvertisements", Icmp6OutNeighborAdvertisements);
+ rrddim_set_by_pointer(st, rd_InSolicits, Icmp6InNeighborSolicits);
+ rrddim_set_by_pointer(st, rd_OutSolicits, Icmp6OutNeighborSolicits);
+ rrddim_set_by_pointer(st, rd_InAdvertisements, Icmp6InNeighborAdvertisements);
+ rrddim_set_by_pointer(st, rd_OutAdvertisements, Icmp6OutNeighborAdvertisements);
rrdset_done(st);
}
@@ -804,18 +1114,33 @@ int do_proc_net_snmp6(int update_every, usec_t dt) {
if(do_icmp_mldv2 == CONFIG_BOOLEAN_YES || (do_icmp_mldv2 == CONFIG_BOOLEAN_AUTO && (Icmp6InMLDv2Reports || Icmp6OutMLDv2Reports))) {
do_icmp_mldv2 = CONFIG_BOOLEAN_YES;
- st = rrdset_find_localhost(RRD_TYPE_NET_SNMP6 ".icmpmldv2");
- if(unlikely(!st)) {
- st = rrdset_create_localhost(RRD_TYPE_NET_SNMP6, "icmpmldv2", NULL, "icmp", NULL, "IPv6 ICMP MLDv2 Reports"
- , "reports/s", 10600, update_every, RRDSET_TYPE_LINE);
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_InMLDv2Reports = NULL,
+ *rd_OutMLDv2Reports = NULL;
- rrddim_add(st, "received", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "sent", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_SNMP6
+ , "icmpmldv2"
+ , NULL
+ , "icmp6"
+ , NULL
+ , "IPv6 ICMP MLDv2 Reports"
+ , "reports/s"
+ , "proc"
+ , "net/snmp6"
+ , 10600
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rd_InMLDv2Reports = rrddim_add(st, "InMLDv2Reports", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutMLDv2Reports = rrddim_add(st, "OutMLDv2Reports", "sent", -1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "sent", Icmp6InMLDv2Reports);
- rrddim_set(st, "received", Icmp6OutMLDv2Reports);
+ rrddim_set_by_pointer(st, rd_InMLDv2Reports, Icmp6InMLDv2Reports);
+ rrddim_set_by_pointer(st, rd_OutMLDv2Reports, Icmp6OutMLDv2Reports);
rrdset_done(st);
}
@@ -835,34 +1160,57 @@ int do_proc_net_snmp6(int update_every, usec_t dt) {
|| Icmp6OutType143
))) {
do_icmp_types = CONFIG_BOOLEAN_YES;
- st = rrdset_find_localhost(RRD_TYPE_NET_SNMP6 ".icmptypes");
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_InType1 = NULL,
+ *rd_InType128 = NULL,
+ *rd_InType129 = NULL,
+ *rd_InType136 = NULL,
+ *rd_OutType1 = NULL,
+ *rd_OutType128 = NULL,
+ *rd_OutType129 = NULL,
+ *rd_OutType133 = NULL,
+ *rd_OutType135 = NULL,
+ *rd_OutType143 = NULL;
+
if(unlikely(!st)) {
- st = rrdset_create_localhost(RRD_TYPE_NET_SNMP6, "icmptypes", NULL, "icmp", NULL, "IPv6 ICMP Types"
- , "messages/s", 10700, update_every, RRDSET_TYPE_LINE);
-
- rrddim_add(st, "InType1", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "InType128", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "InType129", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "InType136", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "OutType1", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "OutType128", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "OutType129", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "OutType133", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "OutType135", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "OutType143", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_SNMP6
+ , "icmptypes"
+ , NULL
+ , "icmp6"
+ , NULL
+ , "IPv6 ICMP Types"
+ , "messages/s"
+ , "proc"
+ , "net/snmp6"
+ , 10700
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rd_InType1 = rrddim_add(st, "InType1", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InType128 = rrddim_add(st, "InType128", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InType129 = rrddim_add(st, "InType129", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InType136 = rrddim_add(st, "InType136", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutType1 = rrddim_add(st, "OutType1", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutType128 = rrddim_add(st, "OutType128", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutType129 = rrddim_add(st, "OutType129", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutType133 = rrddim_add(st, "OutType133", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutType135 = rrddim_add(st, "OutType135", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_OutType143 = rrddim_add(st, "OutType143", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "InType1", Icmp6InType1);
- rrddim_set(st, "InType128", Icmp6InType128);
- rrddim_set(st, "InType129", Icmp6InType129);
- rrddim_set(st, "InType136", Icmp6InType136);
- rrddim_set(st, "OutType1", Icmp6OutType1);
- rrddim_set(st, "OutType128", Icmp6OutType128);
- rrddim_set(st, "OutType129", Icmp6OutType129);
- rrddim_set(st, "OutType133", Icmp6OutType133);
- rrddim_set(st, "OutType135", Icmp6OutType135);
- rrddim_set(st, "OutType143", Icmp6OutType143);
+ rrddim_set_by_pointer(st, rd_InType1, Icmp6InType1);
+ rrddim_set_by_pointer(st, rd_InType128, Icmp6InType128);
+ rrddim_set_by_pointer(st, rd_InType129, Icmp6InType129);
+ rrddim_set_by_pointer(st, rd_InType136, Icmp6InType136);
+ rrddim_set_by_pointer(st, rd_OutType1, Icmp6OutType1);
+ rrddim_set_by_pointer(st, rd_OutType128, Icmp6OutType128);
+ rrddim_set_by_pointer(st, rd_OutType129, Icmp6OutType129);
+ rrddim_set_by_pointer(st, rd_OutType133, Icmp6OutType133);
+ rrddim_set_by_pointer(st, rd_OutType135, Icmp6OutType135);
+ rrddim_set_by_pointer(st, rd_OutType143, Icmp6OutType143);
rrdset_done(st);
}
@@ -876,22 +1224,39 @@ int do_proc_net_snmp6(int update_every, usec_t dt) {
|| Ip6InCEPkts
))) {
do_ect = CONFIG_BOOLEAN_YES;
- st = rrdset_find_localhost(RRD_TYPE_NET_SNMP6 ".ect");
- if(unlikely(!st)) {
- st = rrdset_create_localhost(RRD_TYPE_NET_SNMP6, "ect", NULL, "packets", NULL, "IPv6 ECT Packets"
- , "packets/s", 10800, update_every, RRDSET_TYPE_LINE);
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_InNoECTPkts = NULL,
+ *rd_InECT1Pkts = NULL,
+ *rd_InECT0Pkts = NULL,
+ *rd_InCEPkts = NULL;
- rrddim_add(st, "InNoECTPkts", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "InECT1Pkts", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "InECT0Pkts", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "InCEPkts", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_SNMP6
+ , "ect"
+ , NULL
+ , "packets"
+ , NULL
+ , "IPv6 ECT Packets"
+ , "packets/s"
+ , "proc"
+ , "net/snmp6"
+ , 10800
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rd_InNoECTPkts = rrddim_add(st, "InNoECTPkts", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InECT1Pkts = rrddim_add(st, "InECT1Pkts", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InECT0Pkts = rrddim_add(st, "InECT0Pkts", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_InCEPkts = rrddim_add(st, "InCEPkts", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "InNoECTPkts", Ip6InNoECTPkts);
- rrddim_set(st, "InECT1Pkts", Ip6InECT1Pkts);
- rrddim_set(st, "InECT0Pkts", Ip6InECT0Pkts);
- rrddim_set(st, "InCEPkts", Ip6InCEPkts);
+ rrddim_set_by_pointer(st, rd_InNoECTPkts, Ip6InNoECTPkts);
+ rrddim_set_by_pointer(st, rd_InECT1Pkts, Ip6InECT1Pkts);
+ rrddim_set_by_pointer(st, rd_InECT0Pkts, Ip6InECT0Pkts);
+ rrddim_set_by_pointer(st, rd_InCEPkts, Ip6InCEPkts);
rrdset_done(st);
}
diff --git a/src/proc_net_sockstat.c b/src/proc_net_sockstat.c
new file mode 100644
index 00000000..2ca4061b
--- /dev/null
+++ b/src/proc_net_sockstat.c
@@ -0,0 +1,514 @@
+#include "common.h"
+
+static struct proc_net_sockstat {
+ kernel_uint_t sockets_used;
+
+ kernel_uint_t tcp_inuse;
+ kernel_uint_t tcp_orphan;
+ kernel_uint_t tcp_tw;
+ kernel_uint_t tcp_alloc;
+ kernel_uint_t tcp_mem;
+
+ kernel_uint_t udp_inuse;
+ kernel_uint_t udp_mem;
+
+ kernel_uint_t udplite_inuse;
+
+ kernel_uint_t raw_inuse;
+
+ kernel_uint_t frag_inuse;
+ kernel_uint_t frag_memory;
+} sockstat_root = { 0 };
+
+
+static int read_tcp_mem(void) {
+ static char *filename = NULL;
+ static RRDVAR *tcp_mem_low_threshold = NULL,
+ *tcp_mem_pressure_threshold = NULL,
+ *tcp_mem_high_threshold = NULL;
+
+ if(unlikely(!tcp_mem_low_threshold)) {
+ tcp_mem_low_threshold = rrdvar_custom_host_variable_create(localhost, "tcp_mem_low");
+ tcp_mem_pressure_threshold = rrdvar_custom_host_variable_create(localhost, "tcp_mem_pressure");
+ tcp_mem_high_threshold = rrdvar_custom_host_variable_create(localhost, "tcp_mem_high");
+ }
+
+ if(unlikely(!filename)) {
+ char buffer[FILENAME_MAX + 1];
+ snprintfz(buffer, FILENAME_MAX, "%s/proc/sys/net/ipv4/tcp_mem", netdata_configured_host_prefix);
+ filename = strdupz(buffer);
+ }
+
+ char buffer[200 + 1], *start, *end;
+ if(read_file(filename, buffer, 200) != 0) return 1;
+ buffer[200] = '\0';
+
+ unsigned long long low = 0, pressure = 0, high = 0;
+
+ start = buffer;
+ low = strtoull(start, &end, 10);
+
+ start = end;
+ pressure = strtoull(start, &end, 10);
+
+ start = end;
+ high = strtoull(start, &end, 10);
+
+ // fprintf(stderr, "TCP MEM low = %llu, pressure = %llu, high = %llu\n", low, pressure, high);
+
+ rrdvar_custom_host_variable_set(localhost, tcp_mem_low_threshold, low * sysconf(_SC_PAGESIZE) / 1024);
+ rrdvar_custom_host_variable_set(localhost, tcp_mem_pressure_threshold, pressure * sysconf(_SC_PAGESIZE) / 1024);
+ rrdvar_custom_host_variable_set(localhost, tcp_mem_high_threshold, high * sysconf(_SC_PAGESIZE) / 1024);
+
+ return 0;
+}
+
+static kernel_uint_t read_tcp_max_orphans(void) {
+ static char *filename = NULL;
+ static RRDVAR *tcp_max_orphans_var = NULL;
+
+ if(unlikely(!filename)) {
+ char buffer[FILENAME_MAX + 1];
+ snprintfz(buffer, FILENAME_MAX, "%s/proc/sys/net/ipv4/tcp_max_orphans", netdata_configured_host_prefix);
+ filename = strdupz(buffer);
+ }
+
+ unsigned long long tcp_max_orphans = 0;
+ if(read_single_number_file(filename, &tcp_max_orphans) == 0) {
+
+ if(unlikely(!tcp_max_orphans_var))
+ tcp_max_orphans_var = rrdvar_custom_host_variable_create(localhost, "tcp_max_orphans");
+
+ rrdvar_custom_host_variable_set(localhost, tcp_max_orphans_var, tcp_max_orphans);
+ return tcp_max_orphans;
+ }
+
+ return 0;
+}
+
+int do_proc_net_sockstat(int update_every, usec_t dt) {
+ (void)dt;
+
+ static procfile *ff = NULL;
+
+ static uint32_t hash_sockets = 0,
+ hash_raw = 0,
+ hash_frag = 0,
+ hash_tcp = 0,
+ hash_udp = 0,
+ hash_udplite = 0;
+
+ static long long update_constants_every = 60, update_constants_count = 0;
+
+ static ARL_BASE *arl_sockets = NULL;
+ static ARL_BASE *arl_tcp = NULL;
+ static ARL_BASE *arl_udp = NULL;
+ static ARL_BASE *arl_udplite = NULL;
+ static ARL_BASE *arl_raw = NULL;
+ static ARL_BASE *arl_frag = NULL;
+
+ static int do_sockets = -1, do_tcp_sockets = -1, do_tcp_mem = -1, do_udp_sockets = -1, do_udp_mem = -1, do_udplite_sockets = -1, do_raw_sockets = -1, do_frag_sockets = -1, do_frag_mem = -1;
+
+ static char *keys[7] = { NULL };
+ static uint32_t hashes[7] = { 0 };
+ static ARL_BASE *bases[7] = { NULL };
+
+ if(unlikely(!arl_sockets)) {
+ do_sockets = config_get_boolean_ondemand("plugin:proc:/proc/net/sockstat", "ipv4 sockets", CONFIG_BOOLEAN_AUTO);
+ do_tcp_sockets = config_get_boolean_ondemand("plugin:proc:/proc/net/sockstat", "ipv4 TCP sockets", CONFIG_BOOLEAN_AUTO);
+ do_tcp_mem = config_get_boolean_ondemand("plugin:proc:/proc/net/sockstat", "ipv4 TCP memory", CONFIG_BOOLEAN_AUTO);
+ do_udp_sockets = config_get_boolean_ondemand("plugin:proc:/proc/net/sockstat", "ipv4 UDP sockets", CONFIG_BOOLEAN_AUTO);
+ do_udp_mem = config_get_boolean_ondemand("plugin:proc:/proc/net/sockstat", "ipv4 UDP memory", CONFIG_BOOLEAN_AUTO);
+ do_udplite_sockets = config_get_boolean_ondemand("plugin:proc:/proc/net/sockstat", "ipv4 UDPLITE sockets", CONFIG_BOOLEAN_AUTO);
+ do_raw_sockets = config_get_boolean_ondemand("plugin:proc:/proc/net/sockstat", "ipv4 RAW sockets", CONFIG_BOOLEAN_AUTO);
+ do_frag_sockets = config_get_boolean_ondemand("plugin:proc:/proc/net/sockstat", "ipv4 FRAG sockets", CONFIG_BOOLEAN_AUTO);
+ do_frag_mem = config_get_boolean_ondemand("plugin:proc:/proc/net/sockstat", "ipv4 FRAG memory", CONFIG_BOOLEAN_AUTO);
+
+ update_constants_every = config_get_number("plugin:proc:/proc/net/sockstat", "update constants every", update_constants_every);
+ update_constants_count = update_constants_every;
+
+ arl_sockets = arl_create("sockstat/sockets", arl_callback_str2kernel_uint_t, 60);
+ arl_expect(arl_sockets, "used", &sockstat_root.sockets_used);
+
+ arl_tcp = arl_create("sockstat/TCP", arl_callback_str2kernel_uint_t, 60);
+ arl_expect(arl_tcp, "inuse", &sockstat_root.tcp_inuse);
+ arl_expect(arl_tcp, "orphan", &sockstat_root.tcp_orphan);
+ arl_expect(arl_tcp, "tw", &sockstat_root.tcp_tw);
+ arl_expect(arl_tcp, "alloc", &sockstat_root.tcp_alloc);
+ arl_expect(arl_tcp, "mem", &sockstat_root.tcp_mem);
+
+ arl_udp = arl_create("sockstat/UDP", arl_callback_str2kernel_uint_t, 60);
+ arl_expect(arl_udp, "inuse", &sockstat_root.udp_inuse);
+ arl_expect(arl_udp, "mem", &sockstat_root.udp_mem);
+
+ arl_udplite = arl_create("sockstat/UDPLITE", arl_callback_str2kernel_uint_t, 60);
+ arl_expect(arl_udplite, "inuse", &sockstat_root.udplite_inuse);
+
+ arl_raw = arl_create("sockstat/RAW", arl_callback_str2kernel_uint_t, 60);
+ arl_expect(arl_raw, "inuse", &sockstat_root.raw_inuse);
+
+ arl_frag = arl_create("sockstat/FRAG", arl_callback_str2kernel_uint_t, 60);
+ arl_expect(arl_frag, "inuse", &sockstat_root.frag_inuse);
+ arl_expect(arl_frag, "memory", &sockstat_root.frag_memory);
+
+ hash_sockets = simple_hash("sockets");
+ hash_tcp = simple_hash("TCP");
+ hash_udp = simple_hash("UDP");
+ hash_udplite = simple_hash("UDPLITE");
+ hash_raw = simple_hash("RAW");
+ hash_frag = simple_hash("FRAG");
+
+ keys[0] = "sockets"; hashes[0] = hash_sockets; bases[0] = arl_sockets;
+ keys[1] = "TCP"; hashes[1] = hash_tcp; bases[1] = arl_tcp;
+ keys[2] = "UDP"; hashes[2] = hash_udp; bases[2] = arl_udp;
+ keys[3] = "UDPLITE"; hashes[3] = hash_udplite; bases[3] = arl_udplite;
+ keys[4] = "RAW"; hashes[4] = hash_raw; bases[4] = arl_raw;
+ keys[5] = "FRAG"; hashes[5] = hash_frag; bases[5] = arl_frag;
+ keys[6] = NULL; // terminator
+ }
+
+ update_constants_count += update_every;
+ if(unlikely(update_constants_count > update_constants_every)) {
+ read_tcp_max_orphans();
+ read_tcp_mem();
+ update_constants_count = 0;
+ }
+
+ if(unlikely(!ff)) {
+ char filename[FILENAME_MAX + 1];
+ snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/proc/net/sockstat");
+ ff = procfile_open(config_get("plugin:proc:/proc/net/sockstat", "filename to monitor", filename), " \t:", PROCFILE_FLAG_DEFAULT);
+ if(unlikely(!ff)) return 1;
+ }
+
+ ff = procfile_readall(ff);
+ if(unlikely(!ff)) return 0; // we return 0, so that we will retry to open it next time
+
+ size_t lines = procfile_lines(ff), l;
+
+ for(l = 0; l < lines ;l++) {
+ size_t words = procfile_linewords(ff, l);
+ char *key = procfile_lineword(ff, l, 0);
+ uint32_t hash = simple_hash(key);
+
+ int k;
+ for(k = 0; keys[k] ; k++) {
+ if(unlikely(hash == hashes[k] && strcmp(key, keys[k]) == 0)) {
+ // fprintf(stderr, "KEY: '%s', l=%zu, w=1, words=%zu\n", key, l, words);
+ ARL_BASE *arl = bases[k];
+ arl_begin(arl);
+ size_t w = 1;
+
+ while(w + 1 < words) {
+ char *name = procfile_lineword(ff, l, w); w++;
+ char *value = procfile_lineword(ff, l, w); w++;
+ // fprintf(stderr, " > NAME '%s', VALUE '%s', l=%zu, w=%zu, words=%zu\n", name, value, l, w, words);
+ if(unlikely(arl_check(arl, name, value) != 0))
+ break;
+ }
+
+ break;
+ }
+ }
+ }
+
+ // ------------------------------------------------------------------------
+
+ if(do_sockets == CONFIG_BOOLEAN_YES || (do_sockets == CONFIG_BOOLEAN_AUTO && sockstat_root.sockets_used)) {
+ do_sockets = CONFIG_BOOLEAN_YES;
+
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_used = NULL;
+
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "ipv4"
+ , "sockstat_sockets"
+ , NULL
+ , "sockets"
+ , NULL
+ , "IPv4 Sockets Used"
+ , "sockets"
+ , "proc"
+ , "net/sockstat"
+ , 2400
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rd_used = rrddim_add(st, "used", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+ }
+ else rrdset_next(st);
+
+ rrddim_set_by_pointer(st, rd_used, (collected_number)sockstat_root.sockets_used);
+ rrdset_done(st);
+ }
+
+ // ------------------------------------------------------------------------
+
+ if(do_tcp_sockets == CONFIG_BOOLEAN_YES || (do_tcp_sockets == CONFIG_BOOLEAN_AUTO && (sockstat_root.tcp_inuse || sockstat_root.tcp_orphan || sockstat_root.tcp_tw || sockstat_root.tcp_alloc))) {
+ do_tcp_sockets = CONFIG_BOOLEAN_YES;
+
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_inuse = NULL,
+ *rd_orphan = NULL,
+ *rd_timewait = NULL,
+ *rd_alloc = NULL;
+
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "ipv4"
+ , "sockstat_tcp_sockets"
+ , NULL
+ , "tcp"
+ , NULL
+ , "IPv4 TCP Sockets"
+ , "sockets"
+ , "proc"
+ , "net/sockstat"
+ , 2500
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rd_alloc = rrddim_add(st, "alloc", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+ rd_orphan = rrddim_add(st, "orphan", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+ rd_inuse = rrddim_add(st, "inuse", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+ rd_timewait = rrddim_add(st, "timewait", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+ }
+ else rrdset_next(st);
+
+ rrddim_set_by_pointer(st, rd_inuse, (collected_number)sockstat_root.tcp_inuse);
+ rrddim_set_by_pointer(st, rd_orphan, (collected_number)sockstat_root.tcp_orphan);
+ rrddim_set_by_pointer(st, rd_timewait, (collected_number)sockstat_root.tcp_tw);
+ rrddim_set_by_pointer(st, rd_alloc, (collected_number)sockstat_root.tcp_alloc);
+ rrdset_done(st);
+ }
+
+ // ------------------------------------------------------------------------
+
+ if(do_tcp_mem == CONFIG_BOOLEAN_YES || (do_tcp_mem == CONFIG_BOOLEAN_AUTO && sockstat_root.tcp_mem)) {
+ do_tcp_mem = CONFIG_BOOLEAN_YES;
+
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_mem = NULL;
+
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "ipv4"
+ , "sockstat_tcp_mem"
+ , NULL
+ , "tcp"
+ , NULL
+ , "IPv4 TCP Sockets Memory"
+ , "KB"
+ , "proc"
+ , "net/sockstat"
+ , 2540
+ , update_every
+ , RRDSET_TYPE_AREA
+ );
+
+ rd_mem = rrddim_add(st, "mem", NULL, sysconf(_SC_PAGESIZE), 1024, RRD_ALGORITHM_ABSOLUTE);
+ }
+ else rrdset_next(st);
+
+ rrddim_set_by_pointer(st, rd_mem, (collected_number)sockstat_root.tcp_mem);
+ rrdset_done(st);
+ }
+
+ // ------------------------------------------------------------------------
+
+ if(do_udp_sockets == CONFIG_BOOLEAN_YES || (do_udp_sockets == CONFIG_BOOLEAN_AUTO && sockstat_root.udp_inuse)) {
+ do_udp_sockets = CONFIG_BOOLEAN_YES;
+
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_inuse = NULL;
+
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "ipv4"
+ , "sockstat_udp_sockets"
+ , NULL
+ , "udp"
+ , NULL
+ , "IPv4 UDP Sockets"
+ , "sockets"
+ , "proc"
+ , "net/sockstat"
+ , 2600
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rd_inuse = rrddim_add(st, "inuse", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+ }
+ else rrdset_next(st);
+
+ rrddim_set_by_pointer(st, rd_inuse, (collected_number)sockstat_root.udp_inuse);
+ rrdset_done(st);
+ }
+
+ // ------------------------------------------------------------------------
+
+ if(do_udp_mem == CONFIG_BOOLEAN_YES || (do_udp_mem == CONFIG_BOOLEAN_AUTO && sockstat_root.udp_mem)) {
+ do_udp_mem = CONFIG_BOOLEAN_YES;
+
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_mem = NULL;
+
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "ipv4"
+ , "sockstat_udp_mem"
+ , NULL
+ , "udp"
+ , NULL
+ , "IPv4 UDP Sockets Memory"
+ , "KB"
+ , "proc"
+ , "net/sockstat"
+ , 2603
+ , update_every
+ , RRDSET_TYPE_AREA
+ );
+
+ rd_mem = rrddim_add(st, "mem", NULL, sysconf(_SC_PAGESIZE), 1024, RRD_ALGORITHM_ABSOLUTE);
+ }
+ else rrdset_next(st);
+
+ rrddim_set_by_pointer(st, rd_mem, (collected_number)sockstat_root.udp_mem);
+ rrdset_done(st);
+ }
+
+ // ------------------------------------------------------------------------
+
+ if(do_udplite_sockets == CONFIG_BOOLEAN_YES || (do_udplite_sockets == CONFIG_BOOLEAN_AUTO && sockstat_root.udplite_inuse)) {
+ do_udplite_sockets = CONFIG_BOOLEAN_YES;
+
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_inuse = NULL;
+
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "ipv4"
+ , "sockstat_udplite_sockets"
+ , NULL
+ , "udplite"
+ , NULL
+ , "IPv4 UDPLITE Sockets"
+ , "sockets"
+ , "proc"
+ , "net/sockstat"
+ , 2602
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rd_inuse = rrddim_add(st, "inuse", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+ }
+ else rrdset_next(st);
+
+ rrddim_set_by_pointer(st, rd_inuse, (collected_number)sockstat_root.udplite_inuse);
+ rrdset_done(st);
+ }
+
+ // ------------------------------------------------------------------------
+
+ if(do_raw_sockets == CONFIG_BOOLEAN_YES || (do_raw_sockets == CONFIG_BOOLEAN_AUTO && sockstat_root.raw_inuse)) {
+ do_raw_sockets = CONFIG_BOOLEAN_YES;
+
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_inuse = NULL;
+
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "ipv4"
+ , "sockstat_raw_sockets"
+ , NULL
+ , "raw"
+ , NULL
+ , "IPv4 RAW Sockets"
+ , "sockets"
+ , "proc"
+ , "net/sockstat"
+ , 3010
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rd_inuse = rrddim_add(st, "inuse", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+ }
+ else rrdset_next(st);
+
+ rrddim_set_by_pointer(st, rd_inuse, (collected_number)sockstat_root.raw_inuse);
+ rrdset_done(st);
+ }
+
+ // ------------------------------------------------------------------------
+
+ if(do_frag_sockets == CONFIG_BOOLEAN_YES || (do_frag_sockets == CONFIG_BOOLEAN_AUTO && sockstat_root.frag_inuse)) {
+ do_frag_sockets = CONFIG_BOOLEAN_YES;
+
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_inuse = NULL;
+
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "ipv4"
+ , "sockstat_frag_sockets"
+ , NULL
+ , "fragments"
+ , NULL
+ , "IPv4 FRAG Sockets"
+ , "fragments"
+ , "proc"
+ , "net/sockstat"
+ , 3010
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rd_inuse = rrddim_add(st, "inuse", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+ }
+ else rrdset_next(st);
+
+ rrddim_set_by_pointer(st, rd_inuse, (collected_number)sockstat_root.frag_inuse);
+ rrdset_done(st);
+ }
+
+ // ------------------------------------------------------------------------
+
+ if(do_frag_mem == CONFIG_BOOLEAN_YES || (do_frag_mem == CONFIG_BOOLEAN_AUTO && sockstat_root.frag_memory)) {
+ do_frag_mem = CONFIG_BOOLEAN_YES;
+
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_mem = NULL;
+
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "ipv4"
+ , "sockstat_frag_mem"
+ , NULL
+ , "fragments"
+ , NULL
+ , "IPv4 FRAG Sockets Memory"
+ , "KB"
+ , "proc"
+ , "net/sockstat"
+ , 3020
+ , update_every
+ , RRDSET_TYPE_AREA
+ );
+
+ rd_mem = rrddim_add(st, "mem", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
+ }
+ else rrdset_next(st);
+
+ rrddim_set_by_pointer(st, rd_mem, (collected_number)sockstat_root.frag_memory);
+ rrdset_done(st);
+ }
+
+ return 0;
+}
+
diff --git a/src/proc_net_sockstat6.c b/src/proc_net_sockstat6.c
new file mode 100644
index 00000000..97175ccf
--- /dev/null
+++ b/src/proc_net_sockstat6.c
@@ -0,0 +1,269 @@
+#include "common.h"
+
+static struct proc_net_sockstat6 {
+ kernel_uint_t tcp6_inuse;
+ kernel_uint_t udp6_inuse;
+ kernel_uint_t udplite6_inuse;
+ kernel_uint_t raw6_inuse;
+ kernel_uint_t frag6_inuse;
+} sockstat6_root = { 0 };
+
+int do_proc_net_sockstat6(int update_every, usec_t dt) {
+ (void)dt;
+
+ static procfile *ff = NULL;
+
+ static uint32_t hash_raw = 0,
+ hash_frag = 0,
+ hash_tcp = 0,
+ hash_udp = 0,
+ hash_udplite = 0;
+
+ static ARL_BASE *arl_tcp = NULL;
+ static ARL_BASE *arl_udp = NULL;
+ static ARL_BASE *arl_udplite = NULL;
+ static ARL_BASE *arl_raw = NULL;
+ static ARL_BASE *arl_frag = NULL;
+
+ static int do_tcp_sockets = -1, do_udp_sockets = -1, do_udplite_sockets = -1, do_raw_sockets = -1, do_frag_sockets = -1;
+
+ static char *keys[6] = { NULL };
+ static uint32_t hashes[6] = { 0 };
+ static ARL_BASE *bases[6] = { NULL };
+
+ if(unlikely(!arl_tcp)) {
+ do_tcp_sockets = config_get_boolean_ondemand("plugin:proc:/proc/net/sockstat6", "ipv6 TCP sockets", CONFIG_BOOLEAN_AUTO);
+ do_udp_sockets = config_get_boolean_ondemand("plugin:proc:/proc/net/sockstat6", "ipv6 UDP sockets", CONFIG_BOOLEAN_AUTO);
+ do_udplite_sockets = config_get_boolean_ondemand("plugin:proc:/proc/net/sockstat6", "ipv6 UDPLITE sockets", CONFIG_BOOLEAN_AUTO);
+ do_raw_sockets = config_get_boolean_ondemand("plugin:proc:/proc/net/sockstat6", "ipv6 RAW sockets", CONFIG_BOOLEAN_AUTO);
+ do_frag_sockets = config_get_boolean_ondemand("plugin:proc:/proc/net/sockstat6", "ipv6 FRAG sockets", CONFIG_BOOLEAN_AUTO);
+
+ arl_tcp = arl_create("sockstat6/TCP6", arl_callback_str2kernel_uint_t, 60);
+ arl_expect(arl_tcp, "inuse", &sockstat6_root.tcp6_inuse);
+
+ arl_udp = arl_create("sockstat6/UDP6", arl_callback_str2kernel_uint_t, 60);
+ arl_expect(arl_udp, "inuse", &sockstat6_root.udp6_inuse);
+
+ arl_udplite = arl_create("sockstat6/UDPLITE6", arl_callback_str2kernel_uint_t, 60);
+ arl_expect(arl_udplite, "inuse", &sockstat6_root.udplite6_inuse);
+
+ arl_raw = arl_create("sockstat6/RAW6", arl_callback_str2kernel_uint_t, 60);
+ arl_expect(arl_raw, "inuse", &sockstat6_root.raw6_inuse);
+
+ arl_frag = arl_create("sockstat6/FRAG6", arl_callback_str2kernel_uint_t, 60);
+ arl_expect(arl_frag, "inuse", &sockstat6_root.frag6_inuse);
+
+ hash_tcp = simple_hash("TCP6");
+ hash_udp = simple_hash("UDP6");
+ hash_udplite = simple_hash("UDPLITE6");
+ hash_raw = simple_hash("RAW6");
+ hash_frag = simple_hash("FRAG6");
+
+ keys[0] = "TCP6"; hashes[0] = hash_tcp; bases[0] = arl_tcp;
+ keys[1] = "UDP6"; hashes[1] = hash_udp; bases[1] = arl_udp;
+ keys[2] = "UDPLITE6"; hashes[2] = hash_udplite; bases[2] = arl_udplite;
+ keys[3] = "RAW6"; hashes[3] = hash_raw; bases[3] = arl_raw;
+ keys[4] = "FRAG6"; hashes[4] = hash_frag; bases[4] = arl_frag;
+ keys[5] = NULL; // terminator
+ }
+
+ if(unlikely(!ff)) {
+ char filename[FILENAME_MAX + 1];
+ snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/proc/net/sockstat6");
+ ff = procfile_open(config_get("plugin:proc:/proc/net/sockstat6", "filename to monitor", filename), " \t:", PROCFILE_FLAG_DEFAULT);
+ if(unlikely(!ff)) return 1;
+ }
+
+ ff = procfile_readall(ff);
+ if(unlikely(!ff)) return 0; // we return 0, so that we will retry to open it next time
+
+ size_t lines = procfile_lines(ff), l;
+
+ for(l = 0; l < lines ;l++) {
+ size_t words = procfile_linewords(ff, l);
+ char *key = procfile_lineword(ff, l, 0);
+ uint32_t hash = simple_hash(key);
+
+ int k;
+ for(k = 0; keys[k] ; k++) {
+ if(unlikely(hash == hashes[k] && strcmp(key, keys[k]) == 0)) {
+ // fprintf(stderr, "KEY: '%s', l=%zu, w=1, words=%zu\n", key, l, words);
+ ARL_BASE *arl = bases[k];
+ arl_begin(arl);
+ size_t w = 1;
+
+ while(w + 1 < words) {
+ char *name = procfile_lineword(ff, l, w); w++;
+ char *value = procfile_lineword(ff, l, w); w++;
+ // fprintf(stderr, " > NAME '%s', VALUE '%s', l=%zu, w=%zu, words=%zu\n", name, value, l, w, words);
+ if(unlikely(arl_check(arl, name, value) != 0))
+ break;
+ }
+
+ break;
+ }
+ }
+ }
+
+ // ------------------------------------------------------------------------
+
+ if(do_tcp_sockets == CONFIG_BOOLEAN_YES || (do_tcp_sockets == CONFIG_BOOLEAN_AUTO && (sockstat6_root.tcp6_inuse))) {
+ do_tcp_sockets = CONFIG_BOOLEAN_YES;
+
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_inuse = NULL;
+
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "ipv6"
+ , "sockstat6_tcp_sockets"
+ , NULL
+ , "tcp6"
+ , NULL
+ , "IPv6 TCP Sockets"
+ , "sockets"
+ , "proc"
+ , "net/sockstat6"
+ , 3599
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rd_inuse = rrddim_add(st, "inuse", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+ }
+ else rrdset_next(st);
+
+ rrddim_set_by_pointer(st, rd_inuse, (collected_number)sockstat6_root.tcp6_inuse);
+ rrdset_done(st);
+ }
+
+ // ------------------------------------------------------------------------
+
+ if(do_udp_sockets == CONFIG_BOOLEAN_YES || (do_udp_sockets == CONFIG_BOOLEAN_AUTO && sockstat6_root.udp6_inuse)) {
+ do_udp_sockets = CONFIG_BOOLEAN_YES;
+
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_inuse = NULL;
+
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "ipv6"
+ , "sockstat6_udp_sockets"
+ , NULL
+ , "udp6"
+ , NULL
+ , "IPv6 UDP Sockets"
+ , "sockets"
+ , "proc"
+ , "net/sockstat6"
+ , 3600
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rd_inuse = rrddim_add(st, "inuse", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+ }
+ else rrdset_next(st);
+
+ rrddim_set_by_pointer(st, rd_inuse, (collected_number)sockstat6_root.udp6_inuse);
+ rrdset_done(st);
+ }
+
+ // ------------------------------------------------------------------------
+
+ if(do_udplite_sockets == CONFIG_BOOLEAN_YES || (do_udplite_sockets == CONFIG_BOOLEAN_AUTO && sockstat6_root.udplite6_inuse)) {
+ do_udplite_sockets = CONFIG_BOOLEAN_YES;
+
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_inuse = NULL;
+
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "ipv6"
+ , "sockstat6_udplite_sockets"
+ , NULL
+ , "udplite6"
+ , NULL
+ , "IPv6 UDPLITE Sockets"
+ , "sockets"
+ , "proc"
+ , "net/sockstat6"
+ , 3601
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rd_inuse = rrddim_add(st, "inuse", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+ }
+ else rrdset_next(st);
+
+ rrddim_set_by_pointer(st, rd_inuse, (collected_number)sockstat6_root.udplite6_inuse);
+ rrdset_done(st);
+ }
+
+ // ------------------------------------------------------------------------
+
+ if(do_raw_sockets == CONFIG_BOOLEAN_YES || (do_raw_sockets == CONFIG_BOOLEAN_AUTO && sockstat6_root.raw6_inuse)) {
+ do_raw_sockets = CONFIG_BOOLEAN_YES;
+
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_inuse = NULL;
+
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "ipv6"
+ , "sockstat6_raw_sockets"
+ , NULL
+ , "raw6"
+ , NULL
+ , "IPv6 RAW Sockets"
+ , "sockets"
+ , "proc"
+ , "net/sockstat6"
+ , 3700
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rd_inuse = rrddim_add(st, "inuse", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+ }
+ else rrdset_next(st);
+
+ rrddim_set_by_pointer(st, rd_inuse, (collected_number)sockstat6_root.raw6_inuse);
+ rrdset_done(st);
+ }
+
+ // ------------------------------------------------------------------------
+
+ if(do_frag_sockets == CONFIG_BOOLEAN_YES || (do_frag_sockets == CONFIG_BOOLEAN_AUTO && sockstat6_root.frag6_inuse)) {
+ do_frag_sockets = CONFIG_BOOLEAN_YES;
+
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_inuse = NULL;
+
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "ipv6"
+ , "sockstat6_frag_sockets"
+ , NULL
+ , "fragments6"
+ , NULL
+ , "IPv6 FRAG Sockets"
+ , "fragments"
+ , "proc"
+ , "net/sockstat6"
+ , 3010
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rd_inuse = rrddim_add(st, "inuse", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+ }
+ else rrdset_next(st);
+
+ rrddim_set_by_pointer(st, rd_inuse, (collected_number)sockstat6_root.frag6_inuse);
+ rrdset_done(st);
+ }
+
+ return 0;
+}
diff --git a/src/proc_net_softnet_stat.c b/src/proc_net_softnet_stat.c
index b03a43c5..f3c117e1 100644
--- a/src/proc_net_softnet_stat.c
+++ b/src/proc_net_softnet_stat.c
@@ -79,8 +79,20 @@ int do_proc_net_softnet_stat(int update_every, usec_t dt) {
st = rrdset_find_bytype_localhost("system", "softnet_stat");
if(unlikely(!st)) {
- st = rrdset_create_localhost("system", "softnet_stat", NULL, "softnet_stat", "system.softnet_stat", "System softnet_stat"
- , "events/s", 955, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "system"
+ , "softnet_stat"
+ , NULL
+ , "softnet_stat"
+ , "system.softnet_stat"
+ , "System softnet_stat"
+ , "events/s"
+ , "proc"
+ , "net/softnet_stat"
+ , 955
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
for(w = 0; w < allocated_columns ;w++)
if(unlikely(softnet_column_name(w)))
rrddim_add(st, softnet_column_name(w), NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -103,8 +115,20 @@ int do_proc_net_softnet_stat(int update_every, usec_t dt) {
char title[100+1];
snprintfz(title, 100, "CPU%zu softnet_stat", l);
- st = rrdset_create_localhost("cpu", id, NULL, "softnet_stat", "cpu.softnet_stat", title, "events/s", 4101 + l
- , update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ "cpu"
+ , id
+ , NULL
+ , "softnet_stat"
+ , "cpu.softnet_stat"
+ , title
+ , "events/s"
+ , "proc"
+ , "net/softnet_stat"
+ , 4101 + l
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
for(w = 0; w < allocated_columns ;w++)
if(unlikely(softnet_column_name(w)))
rrddim_add(st, softnet_column_name(w), NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
diff --git a/src/proc_net_stat_conntrack.c b/src/proc_net_stat_conntrack.c
index e04b80a3..363fbc19 100644
--- a/src/proc_net_stat_conntrack.c
+++ b/src/proc_net_stat_conntrack.c
@@ -122,136 +122,225 @@ int do_proc_net_stat_conntrack(int update_every, usec_t dt) {
unsigned long long max;
if(likely(!read_single_number_file(nf_conntrack_max_filename, &max)))
- rrdvar_custom_host_variable_set(rrdvar_max, max);
+ rrdvar_custom_host_variable_set(localhost, rrdvar_max, max);
}
- RRDSET *st;
-
// --------------------------------------------------------------------
if(do_sockets) {
- st = rrdset_find_localhost(RRD_TYPE_NET_STAT_NETFILTER "." RRD_TYPE_NET_STAT_CONNTRACK "_sockets");
- if(unlikely(!st)) {
- st = rrdset_create_localhost(RRD_TYPE_NET_STAT_NETFILTER, RRD_TYPE_NET_STAT_CONNTRACK "_sockets", NULL
- , RRD_TYPE_NET_STAT_CONNTRACK, NULL, "Connection Tracker Connections"
- , "active connections", 3000, update_every, RRDSET_TYPE_LINE);
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_connections = NULL;
- rrddim_add(st, "connections", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+ if(unlikely(!st)) {
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_STAT_NETFILTER
+ , RRD_TYPE_NET_STAT_CONNTRACK "_sockets"
+ , NULL
+ , RRD_TYPE_NET_STAT_CONNTRACK
+ , NULL
+ , "Connection Tracker Connections"
+ , "active connections"
+ , "proc"
+ , "net/stat/nf_conntrack"
+ , 3000
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rd_connections = rrddim_add(st, "connections", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
}
else rrdset_next(st);
- rrddim_set(st, "connections", aentries);
+ rrddim_set_by_pointer(st, rd_connections, aentries);
rrdset_done(st);
}
// --------------------------------------------------------------------
if(do_new) {
- st = rrdset_find_localhost(RRD_TYPE_NET_STAT_NETFILTER "." RRD_TYPE_NET_STAT_CONNTRACK "_new");
- if(unlikely(!st)) {
- st = 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", 3001, update_every, RRDSET_TYPE_LINE);
+ static RRDSET *st = NULL;
+ static RRDDIM
+ *rd_new = NULL,
+ *rd_ignore = NULL,
+ *rd_invalid = NULL;
- rrddim_add(st, "new", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "ignore", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "invalid", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ if(unlikely(!st)) {
+ st = 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"
+ , "proc"
+ , "net/stat/nf_conntrack"
+ , 3001
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rd_new = rrddim_add(st, "new", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_ignore = rrddim_add(st, "ignore", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_invalid = rrddim_add(st, "invalid", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "new", anew);
- rrddim_set(st, "ignore", aignore);
- rrddim_set(st, "invalid", ainvalid);
+ rrddim_set_by_pointer(st, rd_new, anew);
+ rrddim_set_by_pointer(st, rd_ignore, aignore);
+ rrddim_set_by_pointer(st, rd_invalid, ainvalid);
rrdset_done(st);
}
// --------------------------------------------------------------------
if(do_changes) {
- st = rrdset_find_localhost(RRD_TYPE_NET_STAT_NETFILTER "." RRD_TYPE_NET_STAT_CONNTRACK "_changes");
+ static RRDSET *st = NULL;
+ static RRDDIM
+ *rd_inserted = NULL,
+ *rd_deleted = NULL,
+ *rd_delete_list = NULL;
+
if(unlikely(!st)) {
- st = 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"
- , 3002, update_every, RRDSET_TYPE_LINE);
+ st = 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"
+ , "proc"
+ , "net/stat/nf_conntrack"
+ , 3002
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
- rrddim_add(st, "inserted", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "deleted", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "delete_list", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_inserted = rrddim_add(st, "inserted", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_deleted = rrddim_add(st, "deleted", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_delete_list = rrddim_add(st, "delete_list", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "inserted", ainsert);
- rrddim_set(st, "deleted", adelete);
- rrddim_set(st, "delete_list", adelete_list);
+ rrddim_set_by_pointer(st, rd_inserted, ainsert);
+ rrddim_set_by_pointer(st, rd_deleted, adelete);
+ rrddim_set_by_pointer(st, rd_delete_list, adelete_list);
rrdset_done(st);
}
// --------------------------------------------------------------------
if(do_expect) {
- st = rrdset_find_localhost(RRD_TYPE_NET_STAT_NETFILTER "." RRD_TYPE_NET_STAT_CONNTRACK "_expect");
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_created = NULL,
+ *rd_deleted = NULL,
+ *rd_new = NULL;
+
if(unlikely(!st)) {
- st = 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", 3003, update_every, RRDSET_TYPE_LINE);
+ st = 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"
+ , "proc"
+ , "net/stat/nf_conntrack"
+ , 3003
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
- rrddim_add(st, "created", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "deleted", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "new", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_created = rrddim_add(st, "created", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_deleted = rrddim_add(st, "deleted", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_new = rrddim_add(st, "new", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "created", aexpect_create);
- rrddim_set(st, "deleted", aexpect_delete);
- rrddim_set(st, "new", aexpect_new);
+ rrddim_set_by_pointer(st, rd_created, aexpect_create);
+ rrddim_set_by_pointer(st, rd_deleted, aexpect_delete);
+ rrddim_set_by_pointer(st, rd_new, aexpect_new);
rrdset_done(st);
}
// --------------------------------------------------------------------
if(do_search) {
- st = rrdset_find_localhost(RRD_TYPE_NET_STAT_NETFILTER "." RRD_TYPE_NET_STAT_CONNTRACK "_search");
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_searched = NULL,
+ *rd_restarted = NULL,
+ *rd_found = NULL;
+
if(unlikely(!st)) {
- st = 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", 3010, update_every, RRDSET_TYPE_LINE);
+ st = 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"
+ , "proc"
+ , "net/stat/nf_conntrack"
+ , 3010
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
- rrddim_add(st, "searched", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "restarted", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "found", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_searched = rrddim_add(st, "searched", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_restarted = rrddim_add(st, "restarted", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_found = rrddim_add(st, "found", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "searched", asearched);
- rrddim_set(st, "restarted", asearch_restart);
- rrddim_set(st, "found", afound);
+ rrddim_set_by_pointer(st, rd_searched, asearched);
+ rrddim_set_by_pointer(st, rd_restarted, asearch_restart);
+ rrddim_set_by_pointer(st, rd_found, afound);
rrdset_done(st);
}
// --------------------------------------------------------------------
if(do_errors) {
- st = rrdset_find_localhost(RRD_TYPE_NET_STAT_NETFILTER "." RRD_TYPE_NET_STAT_CONNTRACK "_errors");
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_icmp_error = NULL,
+ *rd_insert_failed = NULL,
+ *rd_drop = NULL,
+ *rd_early_drop = NULL;
+
if(unlikely(!st)) {
- st = 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"
- , 3005, update_every, RRDSET_TYPE_LINE);
+ st = 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"
+ , "proc"
+ , "net/stat/nf_conntrack"
+ , 3005
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
- rrddim_add(st, "icmp_error", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "insert_failed", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "drop", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "early_drop", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_icmp_error = rrddim_add(st, "icmp_error", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_insert_failed = rrddim_add(st, "insert_failed", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_drop = rrddim_add(st, "drop", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_early_drop = rrddim_add(st, "early_drop", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(st);
- rrddim_set(st, "icmp_error", aicmp_error);
- rrddim_set(st, "insert_failed", ainsert_failed);
- rrddim_set(st, "drop", adrop);
- rrddim_set(st, "early_drop", aearly_drop);
+ rrddim_set_by_pointer(st, rd_icmp_error, aicmp_error);
+ rrddim_set_by_pointer(st, rd_insert_failed, ainsert_failed);
+ rrddim_set_by_pointer(st, rd_drop, adrop);
+ rrddim_set_by_pointer(st, rd_early_drop, aearly_drop);
rrdset_done(st);
}
diff --git a/src/proc_net_stat_synproxy.c b/src/proc_net_stat_synproxy.c
index 5a1fc30e..0d6f6ee0 100644
--- a/src/proc_net_stat_synproxy.c
+++ b/src/proc_net_stat_synproxy.c
@@ -53,18 +53,27 @@ int do_proc_net_stat_synproxy(int update_every, usec_t dt) {
unsigned long long events = entries + syn_received + cookie_invalid + cookie_valid + cookie_retrans + conn_reopened;
- RRDSET *st;
-
// --------------------------------------------------------------------
if((do_entries == CONFIG_BOOLEAN_AUTO && events) || do_entries == CONFIG_BOOLEAN_YES) {
do_entries = CONFIG_BOOLEAN_YES;
- st = rrdset_find_localhost(RRD_TYPE_NET_STAT_NETFILTER "." RRD_TYPE_NET_STAT_SYNPROXY "_entries");
+ static RRDSET *st = NULL;
if(unlikely(!st)) {
- st = rrdset_create_localhost(RRD_TYPE_NET_STAT_NETFILTER, RRD_TYPE_NET_STAT_SYNPROXY "_entries", NULL
- , RRD_TYPE_NET_STAT_SYNPROXY, NULL, "SYNPROXY Entries Used", "entries", 3304
- , update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_STAT_NETFILTER
+ , RRD_TYPE_NET_STAT_SYNPROXY "_entries"
+ , NULL
+ , RRD_TYPE_NET_STAT_SYNPROXY
+ , NULL
+ , "SYNPROXY Entries Used"
+ , "entries"
+ , "proc"
+ , "net/stat/synproxy"
+ , 3304
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrddim_add(st, "entries", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
}
@@ -79,11 +88,22 @@ int do_proc_net_stat_synproxy(int update_every, usec_t dt) {
if((do_syns == CONFIG_BOOLEAN_AUTO && events) || do_syns == CONFIG_BOOLEAN_YES) {
do_syns = CONFIG_BOOLEAN_YES;
- st = rrdset_find_localhost(RRD_TYPE_NET_STAT_NETFILTER "." RRD_TYPE_NET_STAT_SYNPROXY "_syn_received");
+ static RRDSET *st = NULL;
if(unlikely(!st)) {
- st = rrdset_create_localhost(RRD_TYPE_NET_STAT_NETFILTER, RRD_TYPE_NET_STAT_SYNPROXY "_syn_received", NULL
- , RRD_TYPE_NET_STAT_SYNPROXY, NULL, "SYNPROXY SYN Packets received", "SYN/s"
- , 3301, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_STAT_NETFILTER
+ , RRD_TYPE_NET_STAT_SYNPROXY "_syn_received"
+ , NULL
+ , RRD_TYPE_NET_STAT_SYNPROXY
+ , NULL
+ , "SYNPROXY SYN Packets received"
+ , "SYN/s"
+ , "proc"
+ , "net/stat/synproxy"
+ , 3301
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrddim_add(st, "received", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
}
@@ -98,11 +118,22 @@ int do_proc_net_stat_synproxy(int update_every, usec_t dt) {
if((do_reopened == CONFIG_BOOLEAN_AUTO && events) || do_reopened == CONFIG_BOOLEAN_YES) {
do_reopened = CONFIG_BOOLEAN_YES;
- st = rrdset_find_localhost(RRD_TYPE_NET_STAT_NETFILTER "." RRD_TYPE_NET_STAT_SYNPROXY "_conn_reopened");
+ static RRDSET *st = NULL;
if(unlikely(!st)) {
- st = rrdset_create_localhost(RRD_TYPE_NET_STAT_NETFILTER, RRD_TYPE_NET_STAT_SYNPROXY "_conn_reopened", NULL
- , RRD_TYPE_NET_STAT_SYNPROXY, NULL, "SYNPROXY Connections Reopened"
- , "connections/s", 3303, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_STAT_NETFILTER
+ , RRD_TYPE_NET_STAT_SYNPROXY "_conn_reopened"
+ , NULL
+ , RRD_TYPE_NET_STAT_SYNPROXY
+ , NULL
+ , "SYNPROXY Connections Reopened"
+ , "connections/s"
+ , "proc"
+ , "net/stat/synproxy"
+ , 3303
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrddim_add(st, "reopened", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
}
@@ -117,11 +148,22 @@ int do_proc_net_stat_synproxy(int update_every, usec_t dt) {
if((do_cookies == CONFIG_BOOLEAN_AUTO && events) || do_cookies == CONFIG_BOOLEAN_YES) {
do_cookies = CONFIG_BOOLEAN_YES;
- st = rrdset_find_localhost(RRD_TYPE_NET_STAT_NETFILTER "." RRD_TYPE_NET_STAT_SYNPROXY "_cookies");
+ static RRDSET *st = NULL;
if(unlikely(!st)) {
- st = rrdset_create_localhost(RRD_TYPE_NET_STAT_NETFILTER, RRD_TYPE_NET_STAT_SYNPROXY "_cookies", NULL
- , RRD_TYPE_NET_STAT_SYNPROXY, NULL, "SYNPROXY TCP Cookies", "cookies/s", 3302
- , update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create_localhost(
+ RRD_TYPE_NET_STAT_NETFILTER
+ , RRD_TYPE_NET_STAT_SYNPROXY "_cookies"
+ , NULL
+ , RRD_TYPE_NET_STAT_SYNPROXY
+ , NULL
+ , "SYNPROXY TCP Cookies"
+ , "cookies/s"
+ , "proc"
+ , "net/stat/synproxy"
+ , 3302
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
rrddim_add(st, "valid", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
rrddim_add(st, "invalid", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
diff --git a/src/proc_softirqs.c b/src/proc_softirqs.c
index 352407a4..a1b9947e 100644
--- a/src/proc_softirqs.c
+++ b/src/proc_softirqs.c
@@ -136,6 +136,8 @@ int do_proc_softirqs(int update_every, usec_t dt) {
, NULL
, "System softirqs"
, "softirqs/s"
+ , "proc"
+ , "softirqs"
, 950
, update_every
, RRDSET_TYPE_STACKED
@@ -212,6 +214,8 @@ int do_proc_softirqs(int update_every, usec_t dt) {
, "cpu.softirqs"
, title
, "softirqs/s"
+ , "proc"
+ , "softirqs"
, 3000 + c
, update_every
, RRDSET_TYPE_STACKED
diff --git a/src/proc_spl_kstat_zfs.c b/src/proc_spl_kstat_zfs.c
index dee7a6b3..9d489d8e 100644
--- a/src/proc_spl_kstat_zfs.c
+++ b/src/proc_spl_kstat_zfs.c
@@ -3,7 +3,7 @@
#define ZFS_PROC_ARCSTATS "/proc/spl/kstat/zfs/arcstats"
-struct arcstats arcstats = { 0 };
+extern struct arcstats arcstats;
int do_proc_spl_kstat_zfs_arcstats(int update_every, usec_t dt) {
(void)dt;
@@ -11,7 +11,7 @@ int do_proc_spl_kstat_zfs_arcstats(int update_every, usec_t dt) {
static procfile *ff = NULL;
static ARL_BASE *arl_base = NULL;
- l2exist = -1;
+ arcstats.l2exist = -1;
if(unlikely(!arl_base)) {
arl_base = arl_create("arcstats", NULL, 60);
@@ -135,19 +135,19 @@ int do_proc_spl_kstat_zfs_arcstats(int update_every, usec_t dt) {
const char *key = procfile_lineword(ff, l, 0);
const char *value = procfile_lineword(ff, l, 2);
- if(unlikely(l2exist == -1)) {
+ if(unlikely(arcstats.l2exist == -1)) {
if(key[0] == 'l' && key[1] == '2' && key[2] == '_')
- l2exist = 1;
+ arcstats.l2exist = 1;
}
if(unlikely(arl_check(arl_base, key, value))) break;
}
- if(unlikely(l2exist == -1))
- l2exist = 0;
+ if(unlikely(arcstats.l2exist == -1))
+ arcstats.l2exist = 0;
- generate_charts_arcstats(update_every);
- generate_charts_arc_summary(update_every);
+ generate_charts_arcstats("proc", update_every);
+ generate_charts_arc_summary("proc", update_every);
return 0;
}
diff --git a/src/proc_stat.c b/src/proc_stat.c
index 40bf5cfa..907b659d 100644
--- a/src/proc_stat.c
+++ b/src/proc_stat.c
@@ -287,6 +287,8 @@ int do_proc_stat(int update_every, usec_t dt) {
, context
, title
, "percentage"
+ , "proc"
+ , "stat"
, priority
, update_every
, RRDSET_TYPE_STACKED
@@ -337,6 +339,8 @@ int do_proc_stat(int update_every, usec_t dt) {
, NULL
, "CPU Interrupts"
, "interrupts/s"
+ , "proc"
+ , "stat"
, 900
, update_every
, RRDSET_TYPE_LINE
@@ -367,6 +371,8 @@ int do_proc_stat(int update_every, usec_t dt) {
, NULL
, "CPU Context Switches"
, "context switches/s"
+ , "proc"
+ , "stat"
, 800
, update_every
, RRDSET_TYPE_LINE
@@ -406,6 +412,8 @@ int do_proc_stat(int update_every, usec_t dt) {
, NULL
, "Started Processes"
, "processes/s"
+ , "proc"
+ , "stat"
, 700
, update_every
, RRDSET_TYPE_LINE
@@ -436,6 +444,8 @@ int do_proc_stat(int update_every, usec_t dt) {
, NULL
, "System Processes"
, "processes"
+ , "proc"
+ , "stat"
, 600
, update_every
, RRDSET_TYPE_LINE
@@ -468,6 +478,8 @@ int do_proc_stat(int update_every, usec_t dt) {
, "cpu.core_throttling"
, "Core Thermal Throttling Events"
, "events/s"
+ , "proc"
+ , "stat"
, 5001
, update_every
, RRDSET_TYPE_LINE
@@ -496,6 +508,8 @@ int do_proc_stat(int update_every, usec_t dt) {
, "cpu.package_throttling"
, "Package Thermal Throttling Events"
, "events/s"
+ , "proc"
+ , "stat"
, 5002
, update_every
, RRDSET_TYPE_LINE
@@ -524,6 +538,8 @@ int do_proc_stat(int update_every, usec_t dt) {
, "cpu.scaling_cur_freq"
, "Per CPU Core, Current CPU Scaling Frequency"
, "MHz"
+ , "proc"
+ , "stat"
, 5003
, update_every
, RRDSET_TYPE_LINE
diff --git a/src/proc_sys_kernel_random_entropy_avail.c b/src/proc_sys_kernel_random_entropy_avail.c
index 267ea271..ca4d7657 100644
--- a/src/proc_sys_kernel_random_entropy_avail.c
+++ b/src/proc_sys_kernel_random_entropy_avail.c
@@ -29,6 +29,8 @@ int do_proc_sys_kernel_random_entropy_avail(int update_every, usec_t dt) {
, NULL
, "Available Entropy"
, "entropy"
+ , "proc"
+ , "sys/kernel/random/entropy_avail"
, 1000
, update_every
, RRDSET_TYPE_LINE
diff --git a/src/proc_uptime.c b/src/proc_uptime.c
index fb05b5cb..8f4b9029 100644
--- a/src/proc_uptime.c
+++ b/src/proc_uptime.c
@@ -50,6 +50,8 @@ int do_proc_uptime(int update_every, usec_t dt) {
, NULL
, "System Uptime"
, "seconds"
+ , "proc"
+ , "uptime"
, 1000
, update_every
, RRDSET_TYPE_LINE
diff --git a/src/proc_vmstat.c b/src/proc_vmstat.c
index 2382116f..72ca3818 100644
--- a/src/proc_vmstat.c
+++ b/src/proc_vmstat.c
@@ -102,6 +102,8 @@ int do_proc_vmstat(int update_every, usec_t dt) {
, NULL
, "Swap I/O"
, "kilobytes/s"
+ , "proc"
+ , "vmstat"
, 250
, update_every
, RRDSET_TYPE_AREA
@@ -126,13 +128,15 @@ int do_proc_vmstat(int update_every, usec_t dt) {
if(unlikely(!st_io)) {
st_io = rrdset_create_localhost(
"system"
- , "io"
+ , "pgpgio"
, NULL
, "disk"
, NULL
- , "Disk I/O"
+ , "Memory Paged from/to disk"
, "kilobytes/s"
- , 150
+ , "proc"
+ , "vmstat"
+ , 151
, update_every
, RRDSET_TYPE_AREA
);
@@ -162,6 +166,8 @@ int do_proc_vmstat(int update_every, usec_t dt) {
, NULL
, "Memory Page Faults"
, "page faults/s"
+ , "proc"
+ , "vmstat"
, 500
, update_every
, RRDSET_TYPE_LINE
@@ -205,6 +211,8 @@ int do_proc_vmstat(int update_every, usec_t dt) {
, NULL
, "NUMA events"
, "events/s"
+ , "proc"
+ , "vmstat"
, 800
, update_every
, RRDSET_TYPE_LINE
diff --git a/src/registry.c b/src/registry.c
index 76e3fa4d..9d382e86 100644
--- a/src/registry.c
+++ b/src/registry.c
@@ -323,11 +323,21 @@ void registry_statistics(void) {
static RRDSET *sts = NULL, *stc = NULL, *stm = NULL;
- if(!sts) sts = rrdset_find_localhost("netdata.registry_sessions");
- if(!sts) {
- sts = rrdset_create_localhost("netdata", "registry_sessions", NULL, "registry", NULL
- , "NetData Registry Sessions", "session", 131000, localhost->rrd_update_every
- , RRDSET_TYPE_LINE);
+ if(unlikely(!sts)) {
+ sts = rrdset_create_localhost(
+ "netdata"
+ , "registry_sessions"
+ , NULL
+ , "registry"
+ , NULL
+ , "NetData Registry Sessions"
+ , "session"
+ , "registry"
+ , "stats"
+ , 131000
+ , localhost->rrd_update_every
+ , RRDSET_TYPE_LINE
+ );
rrddim_add(sts, "sessions", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
}
@@ -338,10 +348,21 @@ void registry_statistics(void) {
// ------------------------------------------------------------------------
- if(!stc) stc = rrdset_find_localhost("netdata.registry_entries");
- if(!stc) {
- stc = rrdset_create_localhost("netdata", "registry_entries", NULL, "registry", NULL, "NetData Registry Entries"
- , "entries", 131100, localhost->rrd_update_every, RRDSET_TYPE_LINE);
+ if(unlikely(!stc)) {
+ stc = rrdset_create_localhost(
+ "netdata"
+ , "registry_entries"
+ , NULL
+ , "registry"
+ , NULL
+ , "NetData Registry Entries"
+ , "entries"
+ , "registry"
+ , "stats"
+ , 131100
+ , localhost->rrd_update_every
+ , RRDSET_TYPE_LINE
+ );
rrddim_add(stc, "persons", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
rrddim_add(stc, "machines", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
@@ -360,10 +381,21 @@ void registry_statistics(void) {
// ------------------------------------------------------------------------
- if(!stm) stm = rrdset_find_localhost("netdata.registry_mem");
- if(!stm) {
- stm = rrdset_create_localhost("netdata", "registry_mem", NULL, "registry", NULL, "NetData Registry Memory", "KB"
- , 131300, localhost->rrd_update_every, RRDSET_TYPE_STACKED);
+ if(unlikely(!stm)) {
+ stm = rrdset_create_localhost(
+ "netdata"
+ , "registry_mem"
+ , NULL
+ , "registry"
+ , NULL
+ , "NetData Registry Memory"
+ , "KB"
+ , "registry"
+ , "stats"
+ , 131300
+ , localhost->rrd_update_every
+ , RRDSET_TYPE_STACKED
+ );
rrddim_add(stm, "persons", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
rrddim_add(stm, "machines", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
diff --git a/src/rrd.h b/src/rrd.h
index 1ebb89e5..02e60808 100644
--- a/src/rrd.h
+++ b/src/rrd.h
@@ -87,7 +87,7 @@ struct rrdfamily {
size_t use_count;
- avl_tree_lock variables_root_index;
+ avl_tree_lock rrdvar_root_index;
};
typedef struct rrdfamily RRDFAMILY;
@@ -266,9 +266,9 @@ struct rrdset {
char *units; // units of measurement
char *context; // the template of this data set
- uint32_t hash_context;
+ uint32_t hash_context; // the hash of the chart's context
- RRDSET_TYPE chart_type;
+ RRDSET_TYPE chart_type; // line, area, stacked
int update_every; // every how many seconds is this updated?
@@ -282,7 +282,7 @@ struct rrdset {
int gap_when_lost_iterations_above; // after how many lost iterations a gap should be stored
// netdata will interpolate values for gaps lower than this
- long priority;
+ long priority; // the sorting priority of this chart
// ------------------------------------------------------------------------
@@ -300,7 +300,11 @@ struct rrdset {
time_t last_accessed_time; // the last time this RRDSET has been accessed
time_t upstream_resync_time; // the timestamp up to which we should resync clock upstream
- size_t unused[8];
+
+ char *plugin_name; // the name of the plugin that generated this
+ char *module_name; // the name of the plugin module that generated this
+
+ size_t unused[6];
uint32_t hash; // a simple hash on the id, to speed up searching
// we first compare hashes, and only if the hashes are equal we do string comparisons
@@ -315,20 +319,20 @@ struct rrdset {
total_number collected_total; // used internally to calculate percentages
total_number last_collected_total; // used internally to calculate percentages
- RRDFAMILY *rrdfamily;
- struct rrdhost *rrdhost;
+ RRDFAMILY *rrdfamily; // pointer to RRDFAMILY this chart belongs to
+ struct rrdhost *rrdhost; // pointer to RRDHOST this chart belongs to
struct rrdset *next; // linking of rrdsets
// ------------------------------------------------------------------------
// local variables
- calculated_number green;
- calculated_number red;
+ calculated_number green; // green threshold for this chart
+ calculated_number red; // red threshold for this chart
- avl_tree_lock variables_root_index;
- RRDSETVAR *variables;
- RRDCALC *alarms;
+ avl_tree_lock rrdvar_root_index; // RRDVAR index for this chart
+ RRDSETVAR *variables; // RRDSETVAR linked list for this chart (one RRDSETVAR, many RRDVARs)
+ RRDCALC *alarms; // RRDCALC linked list for this chart
// ------------------------------------------------------------------------
// members for checking the data when loading from disk
@@ -368,9 +372,9 @@ typedef struct rrdset RRDSET;
// and may lead to missing information.
typedef enum rrdhost_flags {
- RRDHOST_ORPHAN = 1 << 0, // this host is orphan (not receiving data)
- RRDHOST_DELETE_OBSOLETE_CHARTS = 1 << 1, // delete files of obsolete charts
- RRDHOST_DELETE_ORPHAN_HOST = 1 << 2 // delete the entire host when orphan
+ RRDHOST_FLAG_ORPHAN = 1 << 0, // this host is orphan (not receiving data)
+ RRDHOST_FLAG_DELETE_OBSOLETE_CHARTS = 1 << 1, // delete files of obsolete charts
+ RRDHOST_FLAG_DELETE_ORPHAN_HOST = 1 << 2 // delete the entire host when orphan
} RRDHOST_FLAGS;
#ifdef HAVE_C___ATOMIC
@@ -410,6 +414,7 @@ struct rrdhost {
const char *os; // the O/S type of the host
const char *tags; // tags for this host
+ const char *timezone; // the timezone of the host
uint32_t flags; // flags about this RRDHOST
@@ -424,17 +429,26 @@ struct rrdhost {
// ------------------------------------------------------------------------
// streaming of data to remote hosts - rrdpush
- int rrdpush_enabled:1; // 1 when this host sends metrics to another netdata
- char *rrdpush_destination; // where to send metrics to
- char *rrdpush_api_key; // the api key at the receiving netdata
- volatile int rrdpush_connected:1; // 1 when the sender is ready to push metrics
- volatile int rrdpush_spawn:1; // 1 when the sender thread has been spawn
- volatile int rrdpush_error_shown:1; // 1 when we have logged a communication error
- int rrdpush_socket; // the fd of the socket to the remote host, or -1
- pthread_t rrdpush_thread; // the sender thread
- netdata_mutex_t rrdpush_mutex; // exclusive access to rrdpush_buffer
- int rrdpush_pipe[2]; // collector to sender thread communication
- BUFFER *rrdpush_buffer; // collector fills it, sender sends them
+ int rrdpush_send_enabled:1; // 1 when this host sends metrics to another netdata
+ char *rrdpush_send_destination; // where to send metrics to
+ char *rrdpush_send_api_key; // the api key at the receiving netdata
+
+ // the following are state information for the threading
+ // streaming metrics from this netdata to an upstream netdata
+ volatile int rrdpush_sender_spawn:1; // 1 when the sender thread has been spawn
+ pthread_t rrdpush_sender_thread; // the sender thread
+
+ volatile int rrdpush_sender_connected:1; // 1 when the sender is ready to push metrics
+ int rrdpush_sender_socket; // the fd of the socket to the remote host, or -1
+
+ volatile int rrdpush_sender_error_shown:1; // 1 when we have logged a communication error
+ volatile int rrdpush_sender_join:1; // 1 when we have to join the sending thread
+
+ // metrics may be collected asynchronously
+ // these synchronize all the threads willing the write to our sending buffer
+ netdata_mutex_t rrdpush_sender_buffer_mutex; // exclusive access to rrdpush_sender_buffer
+ int rrdpush_sender_pipe[2]; // collector to sender thread signaling
+ BUFFER *rrdpush_sender_buffer; // collector fills it, sender sends it
// ------------------------------------------------------------------------
@@ -483,11 +497,14 @@ struct rrdhost {
netdata_rwlock_t rrdhost_rwlock; // lock for this RRDHOST (protects rrdset_root linked list)
+ // ------------------------------------------------------------------------
+ // indexes
+
avl_tree_lock rrdset_root_index; // the host's charts index (by id)
avl_tree_lock rrdset_root_index_name; // the host's charts index (by name)
avl_tree_lock rrdfamily_root_index; // the host's chart families index
- avl_tree_lock variables_root_index; // the host's chart variables index
+ avl_tree_lock rrdvar_root_index; // the host's chart variables index
struct rrdhost *next;
};
@@ -532,6 +549,7 @@ extern RRDHOST *rrdhost_find_or_create(
, const char *registry_hostname
, const char *guid
, const char *os
+ , const char *timezone
, const char *tags
, int update_every
, long history
@@ -560,8 +578,8 @@ extern void __rrd_check_wrlock(const char *file, const char *function, const uns
#else
#define rrdhost_check_rdlock(host) (void)0
#define rrdhost_check_wrlock(host) (void)0
-#define rrdset_check_rdlock(host) (void)0
-#define rrdset_check_wrlock(host) (void)0
+#define rrdset_check_rdlock(st) (void)0
+#define rrdset_check_wrlock(st) (void)0
#define rrd_check_rdlock() (void)0
#define rrd_check_wrlock() (void)0
#endif
@@ -569,7 +587,7 @@ extern void __rrd_check_wrlock(const char *file, const char *function, const uns
// ----------------------------------------------------------------------------
// RRDSET functions
-extern void rrdset_set_name(RRDSET *st, const char *name);
+extern int rrdset_set_name(RRDSET *st, const char *name);
extern RRDSET *rrdset_create_custom(RRDHOST *host
, const char *type
@@ -579,26 +597,30 @@ extern RRDSET *rrdset_create_custom(RRDHOST *host
, const char *context
, const char *title
, const char *units
+ , const char *plugin
+ , const char *module
, long priority
, int update_every
, RRDSET_TYPE chart_type
, RRD_MEMORY_MODE memory_mode
, long history_entries);
-#define rrdset_create(host, type, id, name, family, context, title, units, priority, update_every, chart_type) \
- rrdset_create_custom(host, type, id, name, family, context, title, units, priority, update_every, chart_type, (host)->rrd_memory_mode, (host)->rrd_history_entries)
+#define rrdset_create(host, type, id, name, family, context, title, units, plugin, module, priority, update_every, chart_type) \
+ rrdset_create_custom(host, type, id, name, family, context, title, units, plugin, module, priority, update_every, chart_type, (host)->rrd_memory_mode, (host)->rrd_history_entries)
-#define rrdset_create_localhost(type, id, name, family, context, title, units, priority, update_every, chart_type) \
- rrdset_create(localhost, type, id, name, family, context, title, units, priority, update_every, chart_type)
+#define rrdset_create_localhost(type, id, name, family, context, title, units, plugin, module, priority, update_every, chart_type) \
+ rrdset_create(localhost, type, id, name, family, context, title, units, plugin, module, priority, update_every, chart_type)
extern void rrdhost_free_all(void);
extern void rrdhost_save_all(void);
extern void rrdhost_cleanup_all(void);
-extern void rrdhost_cleanup_orphan_hosts(RRDHOST *protected);
+extern void rrdhost_cleanup_orphan_hosts_nolock(RRDHOST *protected);
extern void rrdhost_free(RRDHOST *host);
-extern void rrdhost_save(RRDHOST *host);
-extern void rrdhost_delete(RRDHOST *host);
+extern void rrdhost_save_charts(RRDHOST *host);
+extern void rrdhost_delete_charts(RRDHOST *host);
+
+extern int rrdhost_should_be_removed(RRDHOST *host, RRDHOST *protected, time_t now);
extern void rrdset_update_heterogeneous_flag(RRDSET *st);
@@ -678,7 +700,6 @@ extern collected_number rrddim_set(RRDSET *st, const char *id, collected_number
extern long align_entries_to_pagesize(RRD_MEMORY_MODE mode, long entries);
-
// ----------------------------------------------------------------------------
// RRD internal functions
diff --git a/src/rrd2json.c b/src/rrd2json.c
index 84d90448..00d7a552 100644
--- a/src/rrd2json.c
+++ b/src/rrd2json.c
@@ -13,6 +13,8 @@ void rrd_stats_api_v1_chart_with_data(RRDSET *st, BUFFER *wb, size_t *dimensions
"\t\t\t\"context\": \"%s\",\n"
"\t\t\t\"title\": \"%s (%s)\",\n"
"\t\t\t\"priority\": %ld,\n"
+ "\t\t\t\"plugin\": \"%s\",\n"
+ "\t\t\t\"module\": \"%s\",\n"
"\t\t\t\"enabled\": %s,\n"
"\t\t\t\"units\": \"%s\",\n"
"\t\t\t\"data_url\": \"/api/v1/data?chart=%s\",\n"
@@ -29,6 +31,8 @@ void rrd_stats_api_v1_chart_with_data(RRDSET *st, BUFFER *wb, size_t *dimensions
, st->context
, st->title, st->name
, st->priority
+ , st->plugin_name?st->plugin_name:""
+ , st->module_name?st->module_name:""
, rrdset_flag_check(st, RRDSET_FLAG_ENABLED)?"true":"false"
, st->units
, st->name
@@ -48,13 +52,14 @@ void rrd_stats_api_v1_chart_with_data(RRDSET *st, BUFFER *wb, size_t *dimensions
memory += rd->memsize;
- buffer_sprintf(wb,
- "%s"
- "\t\t\t\t\"%s\": { \"name\": \"%s\" }"
- , dimensions?",\n":""
- , rd->id
- , rd->name
- );
+ buffer_sprintf(
+ wb
+ , "%s"
+ "\t\t\t\t\"%s\": { \"name\": \"%s\" }"
+ , dimensions ? ",\n" : ""
+ , rd->id
+ , rd->name
+ );
dimensions++;
}
@@ -67,8 +72,33 @@ void rrd_stats_api_v1_chart_with_data(RRDSET *st, BUFFER *wb, size_t *dimensions
buffer_strcat(wb, ",\n\t\t\t\"red\": ");
buffer_rrd_value(wb, st->red);
+ buffer_strcat(wb, ",\n\t\t\t\"alarms\": {\n");
+ size_t alarms = 0;
+ RRDCALC *rc;
+ for(rc = st->alarms; rc ; rc = rc->rrdset_next) {
+
+ buffer_sprintf(
+ wb
+ , "%s"
+ "\t\t\t\t\"%s\": {\n"
+ "\t\t\t\t\t\"id\": %u,\n"
+ "\t\t\t\t\t\"status\": \"%s\",\n"
+ "\t\t\t\t\t\"units\": \"%s\",\n"
+ "\t\t\t\t\t\"update_every\": %d\n"
+ "\t\t\t\t}"
+ , (alarms) ? ",\n" : ""
+ , rc->name
+ , rc->id
+ , rrdcalc_status2string(rc->status)
+ , rc->units
+ , rc->update_every
+ );
+
+ alarms++;
+ }
+
buffer_sprintf(wb,
- "\n\t\t}"
+ "\n\t\t\t}\n\t\t}"
);
rrdset_unlock(st);
@@ -92,6 +122,7 @@ void rrd_stats_api_v1_charts(RRDHOST *host, BUFFER *wb) {
"\t\"hostname\": \"%s\""
",\n\t\"version\": \"%s\""
",\n\t\"os\": \"%s\""
+ ",\n\t\"timezone\": \"%s\""
",\n\t\"update_every\": %d"
",\n\t\"history\": %ld"
",\n\t\"custom_info\": \"%s\""
@@ -99,6 +130,7 @@ void rrd_stats_api_v1_charts(RRDHOST *host, BUFFER *wb) {
, host->hostname
, program_version
, host->os
+ , host->timezone
, host->rrd_update_every
, host->rrd_history_entries
, custom_dashboard_info_js_filename
@@ -126,7 +158,8 @@ void rrd_stats_api_v1_charts(RRDHOST *host, BUFFER *wb) {
}
rrdhost_unlock(host);
- buffer_sprintf(wb, "\n\t}"
+ buffer_sprintf(wb
+ , "\n\t}"
",\n\t\"charts_count\": %zu"
",\n\t\"dimensions_count\": %zu"
",\n\t\"alarms_count\": %zu"
@@ -142,24 +175,31 @@ void rrd_stats_api_v1_charts(RRDHOST *host, BUFFER *wb) {
if(unlikely(rrd_hosts_available > 1)) {
rrd_rdlock();
+
+ size_t found = 0;
RRDHOST *h;
rrdhost_foreach_read(h) {
- buffer_sprintf(wb,
- "%s\n\t\t{"
- "\n\t\t\t\"hostname\": \"%s\""
- "\n\t\t}"
- , (h != localhost) ? "," : ""
- , h->hostname
- );
+ if(!rrdhost_should_be_removed(h, host, now)) {
+ buffer_sprintf(wb
+ , "%s\n\t\t{"
+ "\n\t\t\t\"hostname\": \"%s\""
+ "\n\t\t}"
+ , (found > 0) ? "," : ""
+ , h->hostname
+ );
+
+ found++;
+ }
}
+
rrd_unlock();
}
else {
- buffer_sprintf(wb,
- "\n\t\t{"
- "\n\t\t\t\"hostname\": \"%s\""
- "\n\t\t}"
- , host->hostname
+ buffer_sprintf(wb
+ , "\n\t\t{"
+ "\n\t\t\t\"hostname\": \"%s\""
+ "\n\t\t}"
+ , host->hostname
);
}
diff --git a/src/rrd2json.h b/src/rrd2json.h
index a3b9c950..7212c0b3 100644
--- a/src/rrd2json.h
+++ b/src/rrd2json.h
@@ -61,6 +61,7 @@
#define RRDR_OPTION_LABEL_QUOTES 0x00000400 // in CSV output, wrap header labels in double quotes
#define RRDR_OPTION_PERCENTAGE 0x00000800 // give values as percentage of total
#define RRDR_OPTION_NOT_ALIGNED 0x00001000 // do not align charts for persistant timeframes
+#define RRDR_OPTION_DISPLAY_ABS 0x00002000 // for badges, display the absolute value, but calculate colors with sign
extern void rrd_stats_api_v1_chart(RRDSET *st, BUFFER *wb);
extern void rrd_stats_api_v1_charts(RRDHOST *host, BUFFER *wb);
diff --git a/src/rrdcalc.c b/src/rrdcalc.c
index bb90a4c6..4177733b 100644
--- a/src/rrdcalc.c
+++ b/src/rrdcalc.c
@@ -4,7 +4,7 @@
// ----------------------------------------------------------------------------
// RRDCALC management
-inline const char *rrdcalc_status2string(int status) {
+inline const char *rrdcalc_status2string(RRDCALC_STATUS status) {
switch(status) {
case RRDCALC_STATUS_REMOVED:
return "REMOVED";
@@ -62,15 +62,15 @@ static void rrdsetcalc_link(RRDSET *st, RRDCALC *rc) {
st->red = rc->red;
}
- rc->local = rrdvar_create_and_index("local", &st->variables_root_index, rc->name, RRDVAR_TYPE_CALCULATED, &rc->value);
- rc->family = rrdvar_create_and_index("family", &st->rrdfamily->variables_root_index, rc->name, RRDVAR_TYPE_CALCULATED, &rc->value);
+ rc->local = rrdvar_create_and_index("local", &st->rrdvar_root_index, rc->name, RRDVAR_TYPE_CALCULATED, &rc->value);
+ rc->family = rrdvar_create_and_index("family", &st->rrdfamily->rrdvar_root_index, rc->name, RRDVAR_TYPE_CALCULATED, &rc->value);
char fullname[RRDVAR_MAX_LENGTH + 1];
snprintfz(fullname, RRDVAR_MAX_LENGTH, "%s.%s", st->id, rc->name);
- rc->hostid = rrdvar_create_and_index("host", &st->rrdhost->variables_root_index, fullname, RRDVAR_TYPE_CALCULATED, &rc->value);
+ rc->hostid = rrdvar_create_and_index("host", &st->rrdhost->rrdvar_root_index, fullname, RRDVAR_TYPE_CALCULATED, &rc->value);
snprintfz(fullname, RRDVAR_MAX_LENGTH, "%s.%s", st->name, rc->name);
- rc->hostname = rrdvar_create_and_index("host", &st->rrdhost->variables_root_index, fullname, RRDVAR_TYPE_CALCULATED, &rc->value);
+ rc->hostname = rrdvar_create_and_index("host", &st->rrdhost->rrdvar_root_index, fullname, RRDVAR_TYPE_CALCULATED, &rc->value);
if(!rc->units) rc->units = strdupz(st->units);
@@ -173,16 +173,16 @@ inline void rrdsetcalc_unlink(RRDCALC *rc) {
rc->rrdset_prev = rc->rrdset_next = NULL;
- rrdvar_free(st->rrdhost, &st->variables_root_index, rc->local);
+ rrdvar_free(st->rrdhost, &st->rrdvar_root_index, rc->local);
rc->local = NULL;
- rrdvar_free(st->rrdhost, &st->rrdfamily->variables_root_index, rc->family);
+ rrdvar_free(st->rrdhost, &st->rrdfamily->rrdvar_root_index, rc->family);
rc->family = NULL;
- rrdvar_free(st->rrdhost, &st->rrdhost->variables_root_index, rc->hostid);
+ rrdvar_free(st->rrdhost, &st->rrdhost->rrdvar_root_index, rc->hostid);
rc->hostid = NULL;
- rrdvar_free(st->rrdhost, &st->rrdhost->variables_root_index, rc->hostname);
+ rrdvar_free(st->rrdhost, &st->rrdhost->rrdvar_root_index, rc->hostname);
rc->hostname = NULL;
rc->rrdset = NULL;
@@ -375,8 +375,27 @@ inline RRDCALC *rrdcalc_create(RRDHOST *host, RRDCALCTEMPLATE *rt, const char *c
return rc;
}
-void rrdcalc_free(RRDHOST *host, RRDCALC *rc) {
- if(!rc) return;
+void rrdcalc_free(RRDCALC *rc) {
+ if(unlikely(!rc)) return;
+
+ expression_free(rc->calculation);
+ expression_free(rc->warning);
+ expression_free(rc->critical);
+
+ freez(rc->name);
+ freez(rc->chart);
+ freez(rc->family);
+ freez(rc->dimensions);
+ freez(rc->exec);
+ freez(rc->recipient);
+ freez(rc->source);
+ freez(rc->units);
+ freez(rc->info);
+ freez(rc);
+}
+
+void rrdcalc_unlink_and_free(RRDHOST *host, RRDCALC *rc) {
+ if(unlikely(!rc)) return;
debug(D_HEALTH, "Health removing alarm '%s.%s' of host '%s'", rc->chart?rc->chart:"NOCHART", rc->name, host->hostname);
@@ -398,18 +417,5 @@ void rrdcalc_free(RRDHOST *host, RRDCALC *rc) {
error("Cannot unlink alarm '%s.%s' from host '%s': not found", rc->chart?rc->chart:"NOCHART", rc->name, host->hostname);
}
- expression_free(rc->calculation);
- expression_free(rc->warning);
- expression_free(rc->critical);
-
- freez(rc->name);
- freez(rc->chart);
- freez(rc->family);
- freez(rc->dimensions);
- freez(rc->exec);
- freez(rc->recipient);
- freez(rc->source);
- freez(rc->units);
- freez(rc->info);
- freez(rc);
+ rrdcalc_free(rc);
}
diff --git a/src/rrdcalctemplate.c b/src/rrdcalctemplate.c
index b5d2c7d6..4ec24cd2 100644
--- a/src/rrdcalctemplate.c
+++ b/src/rrdcalctemplate.c
@@ -22,25 +22,9 @@ void rrdcalctemplate_link_matching(RRDSET *st) {
}
}
-inline void rrdcalctemplate_free(RRDHOST *host, RRDCALCTEMPLATE *rt) {
+inline void rrdcalctemplate_free(RRDCALCTEMPLATE *rt) {
if(unlikely(!rt)) return;
- debug(D_HEALTH, "Health removing template '%s' of host '%s'", rt->name, host->hostname);
-
- if(host->templates == rt) {
- host->templates = rt->next;
- }
- else {
- RRDCALCTEMPLATE *t;
- for (t = host->templates; t && t->next != rt; t = t->next ) ;
- if(t) {
- t->next = rt->next;
- rt->next = NULL;
- }
- else
- error("Cannot find RRDCALCTEMPLATE '%s' linked in host '%s'", rt->name, host->hostname);
- }
-
expression_free(rt->calculation);
expression_free(rt->warning);
expression_free(rt->critical);
@@ -59,4 +43,26 @@ inline void rrdcalctemplate_free(RRDHOST *host, RRDCALCTEMPLATE *rt) {
freez(rt);
}
+inline void rrdcalctemplate_unlink_and_free(RRDHOST *host, RRDCALCTEMPLATE *rt) {
+ if(unlikely(!rt)) return;
+
+ debug(D_HEALTH, "Health removing template '%s' of host '%s'", rt->name, host->hostname);
+
+ if(host->templates == rt) {
+ host->templates = rt->next;
+ }
+ else {
+ RRDCALCTEMPLATE *t;
+ for (t = host->templates; t && t->next != rt; t = t->next ) ;
+ if(t) {
+ t->next = rt->next;
+ rt->next = NULL;
+ }
+ else
+ error("Cannot find RRDCALCTEMPLATE '%s' linked in host '%s'", rt->name, host->hostname);
+ }
+
+ rrdcalctemplate_free(rt);
+}
+
diff --git a/src/rrddim.c b/src/rrddim.c
index 8df54839..6477a1cb 100644
--- a/src/rrddim.c
+++ b/src/rrddim.c
@@ -155,7 +155,7 @@ RRDDIM *rrddim_add_custom(RRDSET *st, const char *id, const char *name, collecte
reset = 1;
}
else if(dt_usec(&now, &rd->last_collected_time) > (rd->entries * rd->update_every * USEC_PER_SEC)) {
- error("File %s is too old (last collected %llu seconds ago, but the database is %ld seconds). Clearing it.", fullfilename, dt_usec(&now, &rd->last_collected_time) / USEC_PER_SEC, rd->entries * rd->update_every);
+ info("File %s is too old (last collected %llu seconds ago, but the database is %ld seconds). Clearing it.", fullfilename, dt_usec(&now, &rd->last_collected_time) / USEC_PER_SEC, rd->entries * rd->update_every);
memset(rd, 0, size);
reset = 1;
}
@@ -262,9 +262,9 @@ RRDDIM *rrddim_add_custom(RRDSET *st, const char *id, const char *name, collecte
}
if(st->rrdhost->health_enabled) {
- rrddimvar_create(rd, RRDVAR_TYPE_CALCULATED, NULL, NULL, &rd->last_stored_value, 0);
- rrddimvar_create(rd, RRDVAR_TYPE_COLLECTED, NULL, "_raw", &rd->last_collected_value, 0);
- rrddimvar_create(rd, RRDVAR_TYPE_TIME_T, NULL, "_last_collected_t", &rd->last_collected_time.tv_sec, 0);
+ rrddimvar_create(rd, RRDVAR_TYPE_CALCULATED, NULL, NULL, &rd->last_stored_value, RRDVAR_OPTION_DEFAULT);
+ rrddimvar_create(rd, RRDVAR_TYPE_COLLECTED, NULL, "_raw", &rd->last_collected_value, RRDVAR_OPTION_DEFAULT);
+ rrddimvar_create(rd, RRDVAR_TYPE_TIME_T, NULL, "_last_collected_t", &rd->last_collected_time.tv_sec, RRDVAR_OPTION_DEFAULT);
}
rrdset_unlock(st);
diff --git a/src/rrddimvar.c b/src/rrddimvar.c
index f6eb6d8e..0d20815b 100644
--- a/src/rrddimvar.c
+++ b/src/rrddimvar.c
@@ -13,38 +13,38 @@ static inline void rrddimvar_free_variables(RRDDIMVAR *rs) {
// CHART VARIABLES FOR THIS DIMENSION
- rrdvar_free(st->rrdhost, &st->variables_root_index, rs->var_local_id);
+ rrdvar_free(st->rrdhost, &st->rrdvar_root_index, rs->var_local_id);
rs->var_local_id = NULL;
- rrdvar_free(st->rrdhost, &st->variables_root_index, rs->var_local_name);
+ rrdvar_free(st->rrdhost, &st->rrdvar_root_index, rs->var_local_name);
rs->var_local_name = NULL;
// FAMILY VARIABLES FOR THIS DIMENSION
- rrdvar_free(st->rrdhost, &st->rrdfamily->variables_root_index, rs->var_family_id);
+ rrdvar_free(st->rrdhost, &st->rrdfamily->rrdvar_root_index, rs->var_family_id);
rs->var_family_id = NULL;
- rrdvar_free(st->rrdhost, &st->rrdfamily->variables_root_index, rs->var_family_name);
+ rrdvar_free(st->rrdhost, &st->rrdfamily->rrdvar_root_index, rs->var_family_name);
rs->var_family_name = NULL;
- rrdvar_free(st->rrdhost, &st->rrdfamily->variables_root_index, rs->var_family_contextid);
+ rrdvar_free(st->rrdhost, &st->rrdfamily->rrdvar_root_index, rs->var_family_contextid);
rs->var_family_contextid = NULL;
- rrdvar_free(st->rrdhost, &st->rrdfamily->variables_root_index, rs->var_family_contextname);
+ rrdvar_free(st->rrdhost, &st->rrdfamily->rrdvar_root_index, rs->var_family_contextname);
rs->var_family_contextname = NULL;
// HOST VARIABLES FOR THIS DIMENSION
- rrdvar_free(st->rrdhost, &st->rrdhost->variables_root_index, rs->var_host_chartidid);
+ rrdvar_free(st->rrdhost, &st->rrdhost->rrdvar_root_index, rs->var_host_chartidid);
rs->var_host_chartidid = NULL;
- rrdvar_free(st->rrdhost, &st->rrdhost->variables_root_index, rs->var_host_chartidname);
+ rrdvar_free(st->rrdhost, &st->rrdhost->rrdvar_root_index, rs->var_host_chartidname);
rs->var_host_chartidname = NULL;
- rrdvar_free(st->rrdhost, &st->rrdhost->variables_root_index, rs->var_host_chartnameid);
+ rrdvar_free(st->rrdhost, &st->rrdhost->rrdvar_root_index, rs->var_host_chartnameid);
rs->var_host_chartnameid = NULL;
- rrdvar_free(st->rrdhost, &st->rrdhost->variables_root_index, rs->var_host_chartnamename);
+ rrdvar_free(st->rrdhost, &st->rrdhost->rrdvar_root_index, rs->var_host_chartnamename);
rs->var_host_chartnamename = NULL;
// KEYS
@@ -115,8 +115,8 @@ static inline void rrddimvar_create_variables(RRDDIMVAR *rs) {
// - $id
// - $name
- rs->var_local_id = rrdvar_create_and_index("local", &st->variables_root_index, rs->key_id, rs->type, rs->value);
- rs->var_local_name = rrdvar_create_and_index("local", &st->variables_root_index, rs->key_name, rs->type, rs->value);
+ rs->var_local_id = rrdvar_create_and_index("local", &st->rrdvar_root_index, rs->key_id, rs->type, rs->value);
+ rs->var_local_name = rrdvar_create_and_index("local", &st->rrdvar_root_index, rs->key_name, rs->type, rs->value);
// FAMILY VARIABLES FOR THIS DIMENSION
// -----------------------------------
@@ -127,10 +127,10 @@ static inline void rrddimvar_create_variables(RRDDIMVAR *rs) {
// - $chart-context.id
// - $chart-context.name
- rs->var_family_id = rrdvar_create_and_index("family", &st->rrdfamily->variables_root_index, rs->key_id, rs->type, rs->value);
- rs->var_family_name = rrdvar_create_and_index("family", &st->rrdfamily->variables_root_index, rs->key_name, rs->type, rs->value);
- rs->var_family_contextid = rrdvar_create_and_index("family", &st->rrdfamily->variables_root_index, rs->key_contextid, rs->type, rs->value);
- rs->var_family_contextname = rrdvar_create_and_index("family", &st->rrdfamily->variables_root_index, rs->key_contextname, rs->type, rs->value);
+ rs->var_family_id = rrdvar_create_and_index("family", &st->rrdfamily->rrdvar_root_index, rs->key_id, rs->type, rs->value);
+ rs->var_family_name = rrdvar_create_and_index("family", &st->rrdfamily->rrdvar_root_index, rs->key_name, rs->type, rs->value);
+ rs->var_family_contextid = rrdvar_create_and_index("family", &st->rrdfamily->rrdvar_root_index, rs->key_contextid, rs->type, rs->value);
+ rs->var_family_contextname = rrdvar_create_and_index("family", &st->rrdfamily->rrdvar_root_index, rs->key_contextname, rs->type, rs->value);
// HOST VARIABLES FOR THIS DIMENSION
// -----------------------------------
@@ -141,13 +141,13 @@ static inline void rrddimvar_create_variables(RRDDIMVAR *rs) {
// - $chart-name.id
// - $chart-name.name
- rs->var_host_chartidid = rrdvar_create_and_index("host", &st->rrdhost->variables_root_index, rs->key_fullidid, rs->type, rs->value);
- rs->var_host_chartidname = rrdvar_create_and_index("host", &st->rrdhost->variables_root_index, rs->key_fullidname, rs->type, rs->value);
- rs->var_host_chartnameid = rrdvar_create_and_index("host", &st->rrdhost->variables_root_index, rs->key_fullnameid, rs->type, rs->value);
- rs->var_host_chartnamename = rrdvar_create_and_index("host", &st->rrdhost->variables_root_index, rs->key_fullnamename, rs->type, rs->value);
+ rs->var_host_chartidid = rrdvar_create_and_index("host", &st->rrdhost->rrdvar_root_index, rs->key_fullidid, rs->type, rs->value);
+ rs->var_host_chartidname = rrdvar_create_and_index("host", &st->rrdhost->rrdvar_root_index, rs->key_fullidname, rs->type, rs->value);
+ rs->var_host_chartnameid = rrdvar_create_and_index("host", &st->rrdhost->rrdvar_root_index, rs->key_fullnameid, rs->type, rs->value);
+ rs->var_host_chartnamename = rrdvar_create_and_index("host", &st->rrdhost->rrdvar_root_index, rs->key_fullnamename, rs->type, rs->value);
}
-RRDDIMVAR *rrddimvar_create(RRDDIM *rd, int type, const char *prefix, const char *suffix, void *value, uint32_t options) {
+RRDDIMVAR *rrddimvar_create(RRDDIM *rd, RRDVAR_TYPE type, const char *prefix, const char *suffix, void *value, RRDVAR_OPTIONS options) {
RRDSET *st = rd->rrdset;
debug(D_VARIABLES, "RRDDIMSET create for chart id '%s' name '%s', dimension id '%s', name '%s%s%s'", st->id, st->name, rd->id, (prefix)?prefix:"", rd->name, (suffix)?suffix:"");
diff --git a/src/rrdfamily.c b/src/rrdfamily.c
index fc203e91..905ae480 100644
--- a/src/rrdfamily.c
+++ b/src/rrdfamily.c
@@ -30,11 +30,11 @@ RRDFAMILY *rrdfamily_create(RRDHOST *host, const char *id) {
rc->hash_family = simple_hash(rc->family);
// initialize the variables index
- avl_init_lock(&rc->variables_root_index, rrdvar_compare);
+ avl_init_lock(&rc->rrdvar_root_index, rrdvar_compare);
RRDFAMILY *ret = rrdfamily_index_add(host, rc);
if(ret != rc)
- fatal("RRDFAMILY: INTERNAL ERROR: Expected to INSERT RRDFAMILY '%s' into index, but inserted '%s'.", rc->family, (ret)?ret->family:"NONE");
+ error("RRDFAMILY: INTERNAL ERROR: Expected to INSERT RRDFAMILY '%s' into index, but inserted '%s'.", rc->family, (ret)?ret->family:"NONE");
}
rc->use_count++;
@@ -46,13 +46,14 @@ void rrdfamily_free(RRDHOST *host, RRDFAMILY *rc) {
if(!rc->use_count) {
RRDFAMILY *ret = rrdfamily_index_del(host, rc);
if(ret != rc)
- fatal("RRDFAMILY: INTERNAL ERROR: Expected to DELETE RRDFAMILY '%s' from index, but deleted '%s'.", rc->family, (ret)?ret->family:"NONE");
-
- if(rc->variables_root_index.avl_tree.root != NULL)
- fatal("RRDFAMILY: INTERNAL ERROR: Variables index of RRDFAMILY '%s' that is freed, is not empty.", rc->family);
-
- freez((void *)rc->family);
- freez(rc);
+ error("RRDFAMILY: INTERNAL ERROR: Expected to DELETE RRDFAMILY '%s' from index, but deleted '%s'.", rc->family, (ret)?ret->family:"NONE");
+ else {
+ debug(D_RRD_CALLS, "RRDFAMILY: Cleaning up remaining family variables for host '%s', family '%s'", host->hostname, rc->family);
+ rrdvar_free_remaining_variables(host, &rc->rrdvar_root_index);
+
+ freez((void *) rc->family);
+ freez(rc);
+ }
}
}
diff --git a/src/rrdhost.c b/src/rrdhost.c
index ff8aa561..831cc46c 100644
--- a/src/rrdhost.c
+++ b/src/rrdhost.c
@@ -86,6 +86,15 @@ static inline void rrdhost_init_os(RRDHOST *host, const char *os) {
freez(old);
}
+static inline void rrdhost_init_timezone(RRDHOST *host, const char *timezone) {
+ if(host->timezone && timezone && !strcmp(host->timezone, timezone))
+ return;
+
+ void *old = (void *)host->timezone;
+ host->timezone = strdupz((timezone && *timezone)?timezone:"unknown");
+ freez(old);
+}
+
static inline void rrdhost_init_machine_guid(RRDHOST *host, const char *machine_guid) {
strncpy(host->machine_guid, machine_guid, GUID_LEN);
host->machine_guid[GUID_LEN] = '\0';
@@ -100,6 +109,7 @@ RRDHOST *rrdhost_create(const char *hostname,
const char *registry_hostname,
const char *guid,
const char *os,
+ const char *timezone,
const char *tags,
int update_every,
long entries,
@@ -120,33 +130,34 @@ RRDHOST *rrdhost_create(const char *hostname,
host->rrd_history_entries = align_entries_to_pagesize(memory_mode, entries);
host->rrd_memory_mode = memory_mode;
host->health_enabled = (memory_mode == RRD_MEMORY_MODE_NONE)? 0 : health_enabled;
- host->rrdpush_enabled = (rrdpush_enabled && rrdpush_destination && *rrdpush_destination && rrdpush_api_key && *rrdpush_api_key);
- host->rrdpush_destination = (host->rrdpush_enabled)?strdupz(rrdpush_destination):NULL;
- host->rrdpush_api_key = (host->rrdpush_enabled)?strdupz(rrdpush_api_key):NULL;
+ host->rrdpush_send_enabled = (rrdpush_enabled && rrdpush_destination && *rrdpush_destination && rrdpush_api_key && *rrdpush_api_key);
+ host->rrdpush_send_destination = (host->rrdpush_send_enabled)?strdupz(rrdpush_destination):NULL;
+ host->rrdpush_send_api_key = (host->rrdpush_send_enabled)?strdupz(rrdpush_api_key):NULL;
- host->rrdpush_pipe[0] = -1;
- host->rrdpush_pipe[1] = -1;
- host->rrdpush_socket = -1;
+ host->rrdpush_sender_pipe[0] = -1;
+ host->rrdpush_sender_pipe[1] = -1;
+ host->rrdpush_sender_socket = -1;
- netdata_mutex_init(&host->rrdpush_mutex);
+ netdata_mutex_init(&host->rrdpush_sender_buffer_mutex);
netdata_rwlock_init(&host->rrdhost_rwlock);
rrdhost_init_hostname(host, hostname);
rrdhost_init_machine_guid(host, guid);
rrdhost_init_os(host, os);
+ rrdhost_init_timezone(host, timezone);
rrdhost_init_tags(host, tags);
host->registry_hostname = strdupz((registry_hostname && *registry_hostname)?registry_hostname:hostname);
avl_init_lock(&(host->rrdset_root_index), rrdset_compare);
avl_init_lock(&(host->rrdset_root_index_name), rrdset_compare_name);
avl_init_lock(&(host->rrdfamily_root_index), rrdfamily_compare);
- avl_init_lock(&(host->variables_root_index), rrdvar_compare);
+ avl_init_lock(&(host->rrdvar_root_index), rrdvar_compare);
if(config_get_boolean(CONFIG_SECTION_GLOBAL, "delete obsolete charts files", 1))
- rrdhost_flag_set(host, RRDHOST_DELETE_OBSOLETE_CHARTS);
+ rrdhost_flag_set(host, RRDHOST_FLAG_DELETE_OBSOLETE_CHARTS);
if(config_get_boolean(CONFIG_SECTION_GLOBAL, "delete orphan hosts files", 1) && !is_localhost)
- rrdhost_flag_set(host, RRDHOST_DELETE_ORPHAN_HOST);
+ rrdhost_flag_set(host, RRDHOST_FLAG_DELETE_ORPHAN_HOST);
// ------------------------------------------------------------------------
@@ -251,7 +262,8 @@ RRDHOST *rrdhost_create(const char *hostname,
}
else {
info("Host '%s' (at registry as '%s') with guid '%s' initialized"
- ", os %s"
+ ", os '%s'"
+ ", timezone '%s'"
", tags '%s'"
", update every %d"
", memory mode %s"
@@ -268,13 +280,14 @@ RRDHOST *rrdhost_create(const char *hostname,
, host->registry_hostname
, host->machine_guid
, host->os
+ , host->timezone
, (host->tags)?host->tags:""
, host->rrd_update_every
, rrd_memory_mode_name(host->rrd_memory_mode)
, host->rrd_history_entries
- , host->rrdpush_enabled?"enabled":"disabled"
- , host->rrdpush_destination?host->rrdpush_destination:""
- , host->rrdpush_api_key?host->rrdpush_api_key:""
+ , host->rrdpush_send_enabled?"enabled":"disabled"
+ , host->rrdpush_send_destination?host->rrdpush_send_destination:""
+ , host->rrdpush_send_api_key?host->rrdpush_send_api_key:""
, host->health_enabled?"enabled":"disabled"
, host->cache_dir
, host->varlib_dir
@@ -294,6 +307,7 @@ RRDHOST *rrdhost_find_or_create(
, const char *registry_hostname
, const char *guid
, const char *os
+ , const char *timezone
, const char *tags
, int update_every
, long history
@@ -313,6 +327,7 @@ RRDHOST *rrdhost_find_or_create(
, registry_hostname
, guid
, os
+ , timezone
, tags
, update_every
, history
@@ -346,16 +361,18 @@ RRDHOST *rrdhost_find_or_create(
// update host tags
rrdhost_init_tags(host, tags);
}
- rrd_unlock();
- rrdhost_cleanup_orphan_hosts(host);
+ rrdhost_cleanup_orphan_hosts_nolock(host);
+
+ rrd_unlock();
return host;
}
-static inline int rrdhost_should_be_removed(RRDHOST *host, RRDHOST *protected, time_t now) {
+inline int rrdhost_should_be_removed(RRDHOST *host, RRDHOST *protected, time_t now) {
if(host != protected
&& host != localhost
+ && rrdhost_flag_check(host, RRDHOST_FLAG_ORPHAN)
&& !host->connected_senders
&& host->senders_disconnected_time
&& host->senders_disconnected_time + rrdhost_free_orphan_time < now)
@@ -364,11 +381,9 @@ static inline int rrdhost_should_be_removed(RRDHOST *host, RRDHOST *protected, t
return 0;
}
-void rrdhost_cleanup_orphan_hosts(RRDHOST *protected) {
+void rrdhost_cleanup_orphan_hosts_nolock(RRDHOST *protected) {
time_t now = now_realtime_sec();
- rrd_wrlock();
-
RRDHOST *host;
restart_after_removal:
@@ -376,17 +391,15 @@ restart_after_removal:
if(rrdhost_should_be_removed(host, protected, now)) {
info("Host '%s' with machine guid '%s' is obsolete - cleaning up.", host->hostname, host->machine_guid);
- if(rrdset_flag_check(host, RRDHOST_DELETE_ORPHAN_HOST) && rrdset_flag_check(host, RRDHOST_ORPHAN))
- rrdhost_delete(host);
+ if(rrdhost_flag_check(host, RRDHOST_FLAG_DELETE_ORPHAN_HOST))
+ rrdhost_delete_charts(host);
else
- rrdhost_save(host);
+ rrdhost_save_charts(host);
rrdhost_free(host);
goto restart_after_removal;
}
}
-
- rrd_unlock();
}
// ----------------------------------------------------------------------------
@@ -406,6 +419,7 @@ void rrd_init(char *hostname) {
, registry_get_this_machine_hostname()
, registry_get_this_machine_guid()
, os_type
+ , netdata_configured_timezone
, config_get(CONFIG_SECTION_BACKEND, "host tags", "")
, default_rrd_update_every
, default_rrd_history_entries
@@ -473,12 +487,19 @@ void rrdhost_free(RRDHOST *host) {
// ------------------------------------------------------------------------
// release its children resources
- while(host->rrdset_root) rrdset_free(host->rrdset_root);
+ while(host->rrdset_root)
+ rrdset_free(host->rrdset_root);
- while(host->alarms) rrdcalc_free(host, host->alarms);
- while(host->templates) rrdcalctemplate_free(host, host->templates);
- health_alarm_log_free(host);
+ while(host->alarms)
+ rrdcalc_unlink_and_free(host, host->alarms);
+ while(host->templates)
+ rrdcalctemplate_unlink_and_free(host, host->templates);
+
+ debug(D_RRD_CALLS, "RRDHOST: Cleaning up remaining host variables for host '%s'", host->hostname);
+ rrdvar_free_remaining_variables(host, &host->rrdvar_root_index);
+
+ health_alarm_log_free(host);
// ------------------------------------------------------------------------
// remove it from the indexes
@@ -508,10 +529,11 @@ void rrdhost_free(RRDHOST *host) {
freez((void *)host->tags);
freez((void *)host->os);
+ freez((void *)host->timezone);
freez(host->cache_dir);
freez(host->varlib_dir);
- freez(host->rrdpush_api_key);
- freez(host->rrdpush_destination);
+ freez(host->rrdpush_send_api_key);
+ freez(host->rrdpush_send_destination);
freez(host->health_default_exec);
freez(host->health_default_recipient);
freez(host->health_log_filename);
@@ -534,7 +556,7 @@ void rrdhost_free_all(void) {
// ----------------------------------------------------------------------------
// RRDHOST - save host files
-void rrdhost_save(RRDHOST *host) {
+void rrdhost_save_charts(RRDHOST *host) {
if(!host) return;
info("Saving/Closing database of host '%s'...", host->hostname);
@@ -557,7 +579,7 @@ void rrdhost_save(RRDHOST *host) {
// ----------------------------------------------------------------------------
// RRDHOST - delete host files
-void rrdhost_delete(RRDHOST *host) {
+void rrdhost_delete_charts(RRDHOST *host) {
if(!host) return;
info("Deleting database of host '%s'...", host->hostname);
@@ -582,12 +604,13 @@ void rrdhost_delete(RRDHOST *host) {
// ----------------------------------------------------------------------------
// RRDHOST - cleanup host files
-void rrdhost_cleanup(RRDHOST *host) {
+void rrdhost_cleanup_charts(RRDHOST *host) {
if(!host) return;
info("Cleaning up database of host '%s'...", host->hostname);
RRDSET *st;
+ uint32_t rrdhost_delete_obsolete_charts = rrdhost_flag_check(host, RRDHOST_FLAG_DELETE_OBSOLETE_CHARTS);
// we get a write lock
// to ensure only one thread is saving the database
@@ -596,7 +619,7 @@ void rrdhost_cleanup(RRDHOST *host) {
rrdset_foreach_write(st, host) {
rrdset_rdlock(st);
- if(rrdset_flag_check(st, RRDSET_FLAG_OBSOLETE) && rrdhost_flag_check(host, RRDHOST_DELETE_OBSOLETE_CHARTS))
+ if(rrdhost_delete_obsolete_charts && rrdset_flag_check(st, RRDSET_FLAG_OBSOLETE))
rrdset_delete(st);
else
rrdset_save(st);
@@ -618,7 +641,7 @@ void rrdhost_save_all(void) {
RRDHOST *host;
rrdhost_foreach_read(host)
- rrdhost_save(host);
+ rrdhost_save_charts(host);
rrd_unlock();
}
@@ -633,10 +656,10 @@ void rrdhost_cleanup_all(void) {
RRDHOST *host;
rrdhost_foreach_read(host) {
- if(host != localhost && rrdhost_flag_check(host, RRDHOST_DELETE_OBSOLETE_CHARTS) && !host->connected_senders)
- rrdhost_delete(host);
+ if(host != localhost && rrdhost_flag_check(host, RRDHOST_FLAG_DELETE_OBSOLETE_CHARTS) && !host->connected_senders)
+ rrdhost_delete_charts(host);
else
- rrdhost_cleanup(host);
+ rrdhost_cleanup_charts(host);
}
rrd_unlock();
@@ -651,6 +674,8 @@ void rrdhost_cleanup_obsolete_charts(RRDHOST *host) {
RRDSET *st;
+ uint32_t rrdhost_delete_obsolete_charts = rrdhost_flag_check(host, RRDHOST_FLAG_DELETE_OBSOLETE_CHARTS);
+
restart_after_removal:
rrdset_foreach_write(st, host) {
if(unlikely(rrdset_flag_check(st, RRDSET_FLAG_OBSOLETE)
@@ -661,7 +686,7 @@ restart_after_removal:
rrdset_rdlock(st);
- if(rrdhost_flag_check(host, RRDHOST_DELETE_OBSOLETE_CHARTS))
+ if(rrdhost_delete_obsolete_charts)
rrdset_delete(st);
else
rrdset_save(st);
diff --git a/src/rrdpush.c b/src/rrdpush.c
index c1d052fd..2d10c3ca 100644
--- a/src/rrdpush.c
+++ b/src/rrdpush.c
@@ -59,72 +59,100 @@ int rrdpush_init() {
// this is for the first iterations of each chart
unsigned int remote_clock_resync_iterations = 60;
-#define rrdpush_lock(host) netdata_mutex_lock(&((host)->rrdpush_mutex))
-#define rrdpush_unlock(host) netdata_mutex_unlock(&((host)->rrdpush_mutex))
+#define rrdpush_buffer_lock(host) netdata_mutex_lock(&((host)->rrdpush_sender_buffer_mutex))
+#define rrdpush_buffer_unlock(host) netdata_mutex_unlock(&((host)->rrdpush_sender_buffer_mutex))
// checks if the current chart definition has been sent
static inline int need_to_send_chart_definition(RRDSET *st) {
+ rrdset_check_rdlock(st);
+
if(unlikely(!(rrdset_flag_check(st, RRDSET_FLAG_EXPOSED_UPSTREAM))))
return 1;
RRDDIM *rd;
rrddim_foreach_read(rd, st)
- if(!rd->exposed)
+ if(unlikely(!rd->exposed))
return 1;
return 0;
}
// sends the current chart definition
-static inline void send_chart_definition(RRDSET *st) {
+static inline void rrdpush_send_chart_definition_nolock(RRDSET *st) {
+ RRDHOST *host = st->rrdhost;
+
rrdset_flag_set(st, RRDSET_FLAG_EXPOSED_UPSTREAM);
- buffer_sprintf(st->rrdhost->rrdpush_buffer, "CHART \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" %ld %d \"%s %s %s\"\n"
- , st->id
- , st->name
- , st->title
- , st->units
- , st->family
- , st->context
- , rrdset_type_name(st->chart_type)
- , st->priority
- , st->update_every
- , rrdset_flag_check(st, RRDSET_FLAG_OBSOLETE)?"obsolete":""
- , rrdset_flag_check(st, RRDSET_FLAG_DETAIL)?"detail":""
- , rrdset_flag_check(st, RRDSET_FLAG_STORE_FIRST)?"store_first":""
+ // send the chart
+ buffer_sprintf(
+ host->rrdpush_sender_buffer
+ , "CHART \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" %ld %d \"%s %s %s\" \"%s\" \"%s\"\n"
+ , st->id
+ , st->name
+ , st->title
+ , st->units
+ , st->family
+ , st->context
+ , rrdset_type_name(st->chart_type)
+ , st->priority
+ , st->update_every
+ , rrdset_flag_check(st, RRDSET_FLAG_OBSOLETE)?"obsolete":""
+ , rrdset_flag_check(st, RRDSET_FLAG_DETAIL)?"detail":""
+ , rrdset_flag_check(st, RRDSET_FLAG_STORE_FIRST)?"store_first":""
+ , (st->plugin_name)?st->plugin_name:""
+ , (st->module_name)?st->module_name:""
);
+ // send the dimensions
RRDDIM *rd;
rrddim_foreach_read(rd, st) {
- buffer_sprintf(st->rrdhost->rrdpush_buffer, "DIMENSION \"%s\" \"%s\" \"%s\" " COLLECTED_NUMBER_FORMAT " " COLLECTED_NUMBER_FORMAT " \"%s %s\"\n"
- , rd->id
- , rd->name
- , rrd_algorithm_name(rd->algorithm)
- , rd->multiplier
- , rd->divisor
- , rrddim_flag_check(rd, RRDDIM_FLAG_HIDDEN)?"hidden":""
- , rrddim_flag_check(rd, RRDDIM_FLAG_DONT_DETECT_RESETS_OR_OVERFLOWS)?"noreset":""
+ buffer_sprintf(
+ host->rrdpush_sender_buffer
+ , "DIMENSION \"%s\" \"%s\" \"%s\" " COLLECTED_NUMBER_FORMAT " " COLLECTED_NUMBER_FORMAT " \"%s %s\"\n"
+ , rd->id
+ , rd->name
+ , rrd_algorithm_name(rd->algorithm)
+ , rd->multiplier
+ , rd->divisor
+ , rrddim_flag_check(rd, RRDDIM_FLAG_HIDDEN)?"hidden":""
+ , rrddim_flag_check(rd, RRDDIM_FLAG_DONT_DETECT_RESETS_OR_OVERFLOWS)?"noreset":""
);
rd->exposed = 1;
}
+ // send the chart local custom variables
+ RRDSETVAR *rs;
+ for(rs = st->variables; rs ;rs = rs->next) {
+ if(unlikely(rs->options && RRDVAR_OPTION_ALLOCATED)) {
+ calculated_number *value = (calculated_number *) rs->value;
+
+ buffer_sprintf(
+ host->rrdpush_sender_buffer
+ , "VARIABLE CHART %s = " CALCULATED_NUMBER_FORMAT "\n"
+ , rs->variable
+ , *value
+ );
+ }
+ }
+
st->upstream_resync_time = st->last_collected_time.tv_sec + (remote_clock_resync_iterations * st->update_every);
}
// sends the current chart dimensions
-static inline void send_chart_metrics(RRDSET *st) {
- buffer_sprintf(st->rrdhost->rrdpush_buffer, "BEGIN \"%s\" %llu\n", st->id, (st->upstream_resync_time > st->last_collected_time.tv_sec)?st->usec_since_last_update:0);
+static inline void rrdpush_send_chart_metrics_nolock(RRDSET *st) {
+ buffer_sprintf(st->rrdhost->rrdpush_sender_buffer, "BEGIN \"%s\" %llu\n", st->id, (st->upstream_resync_time > st->last_collected_time.tv_sec)?st->usec_since_last_update:0);
RRDDIM *rd;
rrddim_foreach_read(rd, st) {
if(rd->updated && rd->exposed)
- buffer_sprintf(st->rrdhost->rrdpush_buffer, "SET \"%s\" = " COLLECTED_NUMBER_FORMAT "\n"
- , rd->id
- , rd->collected_value
+ buffer_sprintf(st->rrdhost->rrdpush_sender_buffer
+ , "SET \"%s\" = " COLLECTED_NUMBER_FORMAT "\n"
+ , rd->id
+ , rd->collected_value
);
}
- buffer_strcat(st->rrdhost->rrdpush_buffer, "END\n");
+ buffer_strcat(st->rrdhost->rrdpush_sender_buffer, "END\n");
}
static void rrdpush_sender_thread_spawn(RRDHOST *host);
@@ -133,9 +161,9 @@ void rrdset_push_chart_definition(RRDSET *st) {
RRDHOST *host = st->rrdhost;
rrdset_rdlock(st);
- rrdpush_lock(host);
- send_chart_definition(st);
- rrdpush_unlock(host);
+ rrdpush_buffer_lock(host);
+ rrdpush_send_chart_definition_nolock(st);
+ rrdpush_buffer_unlock(host);
rrdset_unlock(st);
}
@@ -145,40 +173,81 @@ void rrdset_done_push(RRDSET *st) {
if(unlikely(!rrdset_flag_check(st, RRDSET_FLAG_ENABLED)))
return;
- rrdpush_lock(host);
+ rrdpush_buffer_lock(host);
- if(unlikely(host->rrdpush_enabled && !host->rrdpush_spawn))
+ if(unlikely(host->rrdpush_send_enabled && !host->rrdpush_sender_spawn))
rrdpush_sender_thread_spawn(host);
- if(unlikely(!host->rrdpush_buffer || !host->rrdpush_connected)) {
- if(unlikely(!host->rrdpush_error_shown))
+ if(unlikely(!host->rrdpush_sender_buffer || !host->rrdpush_sender_connected)) {
+ if(unlikely(!host->rrdpush_sender_error_shown))
error("STREAM %s [send]: not ready - discarding collected metrics.", host->hostname);
- host->rrdpush_error_shown = 1;
+ host->rrdpush_sender_error_shown = 1;
- rrdpush_unlock(host);
+ rrdpush_buffer_unlock(host);
return;
}
- else if(unlikely(host->rrdpush_error_shown)) {
- info("STREAM %s [send]: ready - sending metrics...", host->hostname);
- host->rrdpush_error_shown = 0;
+ else if(unlikely(host->rrdpush_sender_error_shown)) {
+ info("STREAM %s [send]: sending metrics...", host->hostname);
+ host->rrdpush_sender_error_shown = 0;
}
if(need_to_send_chart_definition(st))
- send_chart_definition(st);
+ rrdpush_send_chart_definition_nolock(st);
- send_chart_metrics(st);
+ rrdpush_send_chart_metrics_nolock(st);
// signal the sender there are more data
- if(write(host->rrdpush_pipe[PIPE_WRITE], " ", 1) == -1)
+ if(host->rrdpush_sender_pipe[PIPE_WRITE] != -1 && write(host->rrdpush_sender_pipe[PIPE_WRITE], " ", 1) == -1)
error("STREAM %s [send]: cannot write to internal pipe", host->hostname);
- rrdpush_unlock(host);
+ rrdpush_buffer_unlock(host);
}
// ----------------------------------------------------------------------------
// rrdpush sender thread
+static inline void rrdpush_sender_add_host_variable_to_buffer_nolock(RRDHOST *host, RRDVAR *rv) {
+ calculated_number *value = (calculated_number *)rv->value;
+
+ buffer_sprintf(
+ host->rrdpush_sender_buffer
+ , "VARIABLE HOST %s = " CALCULATED_NUMBER_FORMAT "\n"
+ , rv->name
+ , *value
+ );
+
+ debug(D_STREAM, "RRDVAR pushed HOST VARIABLE %s = " CALCULATED_NUMBER_FORMAT, rv->name, *value);
+}
+
+void rrdpush_sender_send_this_host_variable_now(RRDHOST *host, RRDVAR *rv) {
+ if(host->rrdpush_send_enabled && host->rrdpush_sender_spawn && host->rrdpush_sender_connected) {
+ rrdpush_buffer_lock(host);
+ rrdpush_sender_add_host_variable_to_buffer_nolock(host, rv);
+ rrdpush_buffer_unlock(host);
+ }
+}
+
+static int rrdpush_sender_thread_custom_host_variables_callback(void *rrdvar_ptr, void *host_ptr) {
+ RRDVAR *rv = (RRDVAR *)rrdvar_ptr;
+ RRDHOST *host = (RRDHOST *)host_ptr;
+
+ if(unlikely(rv->type == RRDVAR_TYPE_CALCULATED_ALLOCATED)) {
+ rrdpush_sender_add_host_variable_to_buffer_nolock(host, rv);
+
+ // return 1, so that the traversal will return the number of variables sent
+ return 1;
+ }
+
+ // returning a negative number will break the traversal
+ return 0;
+}
+
+static void rrdpush_sender_thread_send_custom_host_variables(RRDHOST *host) {
+ int ret = rrdvar_callback_for_all_host_variables(host, rrdpush_sender_thread_custom_host_variables_callback, host);
+ debug(D_STREAM, "RRDVAR sent %d VARIABLES", ret);
+}
+
// resets all the chart, so that their definitions
// will be resent to the central netdata
static void rrdpush_sender_thread_reset_all_charts(RRDHOST *host) {
@@ -186,6 +255,7 @@ static void rrdpush_sender_thread_reset_all_charts(RRDHOST *host) {
RRDSET *st;
rrdset_foreach_read(st, host) {
+ rrdset_flag_clear(st, RRDSET_FLAG_EXPOSED_UPSTREAM);
st->upstream_resync_time = 0;
@@ -202,68 +272,198 @@ static void rrdpush_sender_thread_reset_all_charts(RRDHOST *host) {
}
static inline void rrdpush_sender_thread_data_flush(RRDHOST *host) {
- rrdpush_lock(host);
+ rrdpush_buffer_lock(host);
- if(buffer_strlen(host->rrdpush_buffer))
- error("STREAM %s [send]: discarding %zu bytes of metrics already in the buffer.", host->hostname, buffer_strlen(host->rrdpush_buffer));
+ if(buffer_strlen(host->rrdpush_sender_buffer))
+ error("STREAM %s [send]: discarding %zu bytes of metrics already in the buffer.", host->hostname, buffer_strlen(host->rrdpush_sender_buffer));
- buffer_flush(host->rrdpush_buffer);
+ buffer_flush(host->rrdpush_sender_buffer);
rrdpush_sender_thread_reset_all_charts(host);
+ rrdpush_sender_thread_send_custom_host_variables(host);
- rrdpush_unlock(host);
+ rrdpush_buffer_unlock(host);
}
-static void rrdpush_sender_thread_cleanup_locked_all(RRDHOST *host) {
- host->rrdpush_connected = 0;
+void rrdpush_sender_thread_stop(RRDHOST *host) {
+ rrdpush_buffer_lock(host);
+ rrdhost_wrlock(host);
+
+ pthread_t thr = 0;
- if(host->rrdpush_socket != -1) {
- close(host->rrdpush_socket);
- host->rrdpush_socket = -1;
+ if(host->rrdpush_sender_spawn) {
+ info("STREAM %s [send]: signaling sending thread to stop...", host->hostname);
+
+ // signal the thread that we want to join it
+ host->rrdpush_sender_join = 1;
+
+ // copy the thread id, so that we will be waiting for the right one
+ // even if a new one has been spawn
+ thr = host->rrdpush_sender_thread;
+
+ // signal it to cancel
+ int ret = pthread_cancel(host->rrdpush_sender_thread);
+ if(ret != 0)
+ error("STREAM %s [send]: pthread_cancel() returned error.", host->hostname);
}
- // close the pipe
- if(host->rrdpush_pipe[PIPE_READ] != -1) {
- close(host->rrdpush_pipe[PIPE_READ]);
- host->rrdpush_pipe[PIPE_READ] = -1;
+ rrdhost_unlock(host);
+ rrdpush_buffer_unlock(host);
+
+ if(thr != 0) {
+ info("STREAM %s [send]: waiting for the sending thread to stop...", host->hostname);
+
+ void *result;
+ int ret = pthread_join(thr, &result);
+ if(ret != 0)
+ error("STREAM %s [send]: pthread_join() returned error.", host->hostname);
+
+ info("STREAM %s [send]: sending thread has exited.", host->hostname);
+ }
+}
+
+static inline void rrdpush_sender_thread_close_socket(RRDHOST *host) {
+ host->rrdpush_sender_connected = 0;
+
+ if(host->rrdpush_sender_socket != -1) {
+ close(host->rrdpush_sender_socket);
+ host->rrdpush_sender_socket = -1;
+ }
+}
+
+static int rrdpush_sender_thread_connect_to_master(RRDHOST *host, int default_port, int timeout, size_t *reconnects_counter, char *connected_to, size_t connected_to_size) {
+ struct timeval tv = {
+ .tv_sec = timeout,
+ .tv_usec = 0
+ };
+
+ // make sure the socket is closed
+ rrdpush_sender_thread_close_socket(host);
+
+ debug(D_STREAM, "STREAM: Attempting to connect...");
+ info("STREAM %s [send to %s]: connecting...", host->hostname, host->rrdpush_send_destination);
+
+ host->rrdpush_sender_socket = connect_to_one_of(
+ host->rrdpush_send_destination
+ , default_port
+ , &tv
+ , reconnects_counter
+ , connected_to
+ , connected_to_size
+ );
+
+ if(unlikely(host->rrdpush_sender_socket == -1)) {
+ error("STREAM %s [send to %s]: failed to connect", host->hostname, host->rrdpush_send_destination);
+ return 0;
+ }
+
+ info("STREAM %s [send to %s]: initializing communication...", host->hostname, connected_to);
+
+ #define HTTP_HEADER_SIZE 8192
+ char http[HTTP_HEADER_SIZE + 1];
+ snprintfz(http, HTTP_HEADER_SIZE,
+ "STREAM key=%s&hostname=%s&registry_hostname=%s&machine_guid=%s&update_every=%d&os=%s&timezone=%s&tags=%s HTTP/1.1\r\n"
+ "User-Agent: netdata-push-service/%s\r\n"
+ "Accept: */*\r\n\r\n"
+ , host->rrdpush_send_api_key
+ , host->hostname
+ , host->registry_hostname
+ , host->machine_guid
+ , default_rrd_update_every
+ , host->os
+ , host->timezone
+ , (host->tags)?host->tags:""
+ , program_version
+ );
+
+ if(send_timeout(host->rrdpush_sender_socket, http, strlen(http), 0, timeout) == -1) {
+ error("STREAM %s [send to %s]: failed to send HTTP header to remote netdata.", host->hostname, connected_to);
+ rrdpush_sender_thread_close_socket(host);
+ return 0;
}
- if(host->rrdpush_pipe[PIPE_WRITE] != -1) {
- close(host->rrdpush_pipe[PIPE_WRITE]);
- host->rrdpush_pipe[PIPE_WRITE] = -1;
+ info("STREAM %s [send to %s]: waiting response from remote netdata...", host->hostname, connected_to);
+
+ if(recv_timeout(host->rrdpush_sender_socket, http, HTTP_HEADER_SIZE, 0, timeout) == -1) {
+ error("STREAM %s [send to %s]: remote netdata does not respond.", host->hostname, connected_to);
+ rrdpush_sender_thread_close_socket(host);
+ return 0;
+ }
+
+ if(strncmp(http, START_STREAMING_PROMPT, strlen(START_STREAMING_PROMPT)) != 0) {
+ error("STREAM %s [send to %s]: server is not replying properly (is it a netdata?).", host->hostname, connected_to);
+ rrdpush_sender_thread_close_socket(host);
+ return 0;
}
- buffer_free(host->rrdpush_buffer);
- host->rrdpush_buffer = NULL;
+ info("STREAM %s [send to %s]: established communication - ready to send metrics...", host->hostname, connected_to);
- host->rrdpush_spawn = 0;
+ if(sock_setnonblock(host->rrdpush_sender_socket) < 0)
+ error("STREAM %s [send to %s]: cannot set non-blocking mode for socket.", host->hostname, connected_to);
+
+ if(sock_enlarge_out(host->rrdpush_sender_socket) < 0)
+ error("STREAM %s [send to %s]: cannot enlarge the socket buffer.", host->hostname, connected_to);
+
+ debug(D_STREAM, "STREAM: Connected on fd %d...", host->rrdpush_sender_socket);
+
+ return 1;
}
-void rrdpush_sender_thread_stop(RRDHOST *host) {
- rrdpush_lock(host);
+static void rrdpush_sender_thread_cleanup_callback(void *ptr) {
+ RRDHOST *host = (RRDHOST *)ptr;
+
+ rrdpush_buffer_lock(host);
rrdhost_wrlock(host);
- if(host->rrdpush_spawn) {
- info("STREAM %s [send]: stopping sending thread...", host->hostname);
- pthread_cancel(host->rrdpush_thread);
- rrdpush_sender_thread_cleanup_locked_all(host);
+ info("STREAM %s [send]: sending thread cleans up...", host->hostname);
+
+ rrdpush_sender_thread_close_socket(host);
+
+ // close the pipe
+ if(host->rrdpush_sender_pipe[PIPE_READ] != -1) {
+ close(host->rrdpush_sender_pipe[PIPE_READ]);
+ host->rrdpush_sender_pipe[PIPE_READ] = -1;
+ }
+
+ if(host->rrdpush_sender_pipe[PIPE_WRITE] != -1) {
+ close(host->rrdpush_sender_pipe[PIPE_WRITE]);
+ host->rrdpush_sender_pipe[PIPE_WRITE] = -1;
}
+ buffer_free(host->rrdpush_sender_buffer);
+ host->rrdpush_sender_buffer = NULL;
+
+ if(!host->rrdpush_sender_join) {
+ info("STREAM %s [send]: sending thread detaches itself.", host->hostname);
+ if(pthread_detach(pthread_self()))
+ error("STREAM %s [send]: pthread_detach() failed.", host->hostname);
+ }
+
+ host->rrdpush_sender_spawn = 0;
+
+ info("STREAM %s [send]: sending thread now exits.", host->hostname);
+
rrdhost_unlock(host);
- rrdpush_unlock(host);
+ rrdpush_buffer_unlock(host);
}
void *rrdpush_sender_thread(void *ptr) {
RRDHOST *host = (RRDHOST *)ptr;
- info("STREAM %s [send]: thread created (task id %d)", host->hostname, gettid());
+ if(!host->rrdpush_send_enabled || !host->rrdpush_send_destination || !*host->rrdpush_send_destination || !host->rrdpush_send_api_key || !*host->rrdpush_send_api_key) {
+ error("STREAM %s [send]: thread created (task id %d), but host has streaming disabled.", host->hostname, gettid());
+ pthread_exit(NULL);
+ return NULL;
+ }
- if(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) != 0)
- error("STREAM %s [send]: cannot set pthread cancel type to DEFERRED.", host->hostname);
+ info("STREAM %s [send]: thread created (task id %d)", host->hostname, gettid());
if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0)
error("STREAM %s [send]: cannot set pthread cancel state to ENABLE.", host->hostname);
+ if(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) != 0)
+ error("STREAM %s [send]: cannot set pthread cancel type to DEFERRED.", host->hostname);
+
int timeout = (int)appconfig_get_number(&stream_config, CONFIG_SECTION_STREAM, "timeout seconds", 60);
int default_port = (int)appconfig_get_number(&stream_config, CONFIG_SECTION_STREAM, "default port", 19999);
size_t max_size = (size_t)appconfig_get_number(&stream_config, CONFIG_SECTION_STREAM, "buffer size bytes", 1024 * 1024);
@@ -271,24 +471,17 @@ void *rrdpush_sender_thread(void *ptr) {
remote_clock_resync_iterations = (unsigned int)appconfig_get_number(&stream_config, CONFIG_SECTION_STREAM, "initial clock resync iterations", remote_clock_resync_iterations);
char connected_to[CONNECTED_TO_SIZE + 1] = "";
- if(!host->rrdpush_enabled || !host->rrdpush_destination || !*host->rrdpush_destination || !host->rrdpush_api_key || !*host->rrdpush_api_key)
- goto cleanup;
-
// initialize rrdpush globals
- host->rrdpush_buffer = buffer_create(1);
- host->rrdpush_connected = 0;
- if(pipe(host->rrdpush_pipe) == -1) fatal("STREAM %s [send]: cannot create required pipe.", host->hostname);
+ host->rrdpush_sender_buffer = buffer_create(1);
+ host->rrdpush_sender_connected = 0;
+ if(pipe(host->rrdpush_sender_pipe) == -1) fatal("STREAM %s [send]: cannot create required pipe.", host->hostname);
// initialize local variables
size_t begin = 0;
size_t reconnects_counter = 0;
size_t sent_bytes = 0;
- size_t sent_connection = 0;
+ size_t sent_bytes_on_this_connection = 0;
- struct timeval tv = {
- .tv_sec = timeout,
- .tv_usec = 0
- };
time_t last_sent_t = 0;
struct pollfd fds[2], *ifd, *ofd;
@@ -297,260 +490,206 @@ void *rrdpush_sender_thread(void *ptr) {
ifd = &fds[0];
ofd = &fds[1];
- for(; host->rrdpush_enabled && !netdata_exit ;) {
- debug(D_STREAM, "STREAM: Checking if we need to timeout the connection...");
- if(host->rrdpush_socket != -1 && now_monotonic_sec() - last_sent_t > timeout) {
- error("STREAM %s [send to %s]: could not send metrics for %d seconds - closing connection - we have sent %zu bytes on this connection.", host->hostname, connected_to, timeout, sent_connection);
- close(host->rrdpush_socket);
- host->rrdpush_socket = -1;
- }
+ size_t not_connected_loops = 0;
- if(unlikely(host->rrdpush_socket == -1)) {
- debug(D_STREAM, "STREAM: Attempting to connect...");
+ pthread_cleanup_push(rrdpush_sender_thread_cleanup_callback, host);
- // stop appending data into rrdpush_buffer
- // they will be lost, so there is no point to do it
- host->rrdpush_connected = 0;
+ for(; host->rrdpush_send_enabled && !netdata_exit ;) {
+ // check for outstanding cancellation requests
+ pthread_testcancel();
- info("STREAM %s [send to %s]: connecting...", host->hostname, host->rrdpush_destination);
- host->rrdpush_socket = connect_to_one_of(host->rrdpush_destination, default_port, &tv, &reconnects_counter, connected_to, CONNECTED_TO_SIZE);
+ // if we don't have socket open, lets wait a bit
+ if(unlikely(host->rrdpush_sender_socket == -1)) {
+ if(not_connected_loops == 0 && sent_bytes_on_this_connection > 0) {
+ // fast re-connection on first disconnect
+ sleep_usec(USEC_PER_MS * 500); // milliseconds
+ }
+ else {
+ // slow re-connection on repeating errors
+ sleep_usec(USEC_PER_SEC * reconnect_delay); // seconds
+ }
- if(unlikely(host->rrdpush_socket == -1)) {
- error("STREAM %s [send to %s]: failed to connect", host->hostname, host->rrdpush_destination);
- sleep(reconnect_delay);
- continue;
- }
+ if(rrdpush_sender_thread_connect_to_master(host, default_port, timeout, &reconnects_counter, connected_to, CONNECTED_TO_SIZE)) {
+ last_sent_t = now_monotonic_sec();
- info("STREAM %s [send to %s]: initializing communication...", host->hostname, connected_to);
+ // reset the buffer, to properly send charts and metrics
+ rrdpush_sender_thread_data_flush(host);
- #define HTTP_HEADER_SIZE 8192
- char http[HTTP_HEADER_SIZE + 1];
- snprintfz(http, HTTP_HEADER_SIZE,
- "STREAM key=%s&hostname=%s&registry_hostname=%s&machine_guid=%s&update_every=%d&os=%s&tags=%s HTTP/1.1\r\n"
- "User-Agent: netdata-push-service/%s\r\n"
- "Accept: */*\r\n\r\n"
- , host->rrdpush_api_key
- , host->hostname
- , host->registry_hostname
- , host->machine_guid
- , default_rrd_update_every
- , host->os
- , (host->tags)?host->tags:""
- , program_version
- );
+ // make sure the next reconnection will be immediate
+ not_connected_loops = 0;
- if(send_timeout(host->rrdpush_socket, http, strlen(http), 0, timeout) == -1) {
- close(host->rrdpush_socket);
- host->rrdpush_socket = -1;
- error("STREAM %s [send to %s]: failed to send http header to netdata", host->hostname, connected_to);
- sleep(reconnect_delay);
- continue;
- }
+ // reset the bytes we have sent for this session
+ sent_bytes_on_this_connection = 0;
- info("STREAM %s [send to %s]: waiting response from remote netdata...", host->hostname, connected_to);
+ // let the data collection threads know we are ready
+ host->rrdpush_sender_connected = 1;
+ }
+ else {
+ // increase the failed connections counter
+ not_connected_loops++;
- if(recv_timeout(host->rrdpush_socket, http, HTTP_HEADER_SIZE, 0, timeout) == -1) {
- close(host->rrdpush_socket);
- host->rrdpush_socket = -1;
- error("STREAM %s [send to %s]: failed to initialize communication", host->hostname, connected_to);
- sleep(reconnect_delay);
- continue;
- }
+ // reset the number of bytes sent
+ sent_bytes_on_this_connection = 0;
+ }
- if(strncmp(http, START_STREAMING_PROMPT, strlen(START_STREAMING_PROMPT))) {
- close(host->rrdpush_socket);
- host->rrdpush_socket = -1;
- error("STREAM %s [send to %s]: server is not replying properly.", host->hostname, connected_to);
- sleep(reconnect_delay);
+ // loop through
continue;
}
-
- info("STREAM %s [send to %s]: established communication - sending metrics...", host->hostname, connected_to);
- last_sent_t = now_monotonic_sec();
-
- if(sock_setnonblock(host->rrdpush_socket) < 0)
- error("STREAM %s [send to %s]: cannot set non-blocking mode for socket.", host->hostname, connected_to);
-
- if(sock_enlarge_out(host->rrdpush_socket) < 0)
- error("STREAM %s [send to %s]: cannot enlarge the socket buffer.", host->hostname, connected_to);
-
- rrdpush_sender_thread_data_flush(host);
- sent_connection = 0;
-
- // allow appending data into rrdpush_buffer
- host->rrdpush_connected = 1;
-
- debug(D_STREAM, "STREAM: Connected on fd %d...", host->rrdpush_socket);
- }
-
- ifd->fd = host->rrdpush_pipe[PIPE_READ];
- ifd->events = POLLIN;
- ifd->revents = 0;
-
- ofd->fd = host->rrdpush_socket;
- ofd->revents = 0;
- if(ofd->fd != -1 && begin < buffer_strlen(host->rrdpush_buffer)) {
- debug(D_STREAM, "STREAM: Requesting data output on streaming socket %d...", ofd->fd);
- ofd->events = POLLOUT;
- fdmax = 2;
- }
- else {
- debug(D_STREAM, "STREAM: Not requesting data output on streaming socket %d (nothing to send now)...", ofd->fd);
- ofd->events = 0;
- fdmax = 1;
- }
-
- debug(D_STREAM, "STREAM: Waiting for poll() events (current buffer length %zu bytes)...", buffer_strlen(host->rrdpush_buffer));
- if(netdata_exit) break;
- int retval = poll(fds, fdmax, 1000);
- if(netdata_exit) break;
-
- if(unlikely(retval == -1)) {
- debug(D_STREAM, "STREAM: poll() failed (current buffer length %zu bytes)...", buffer_strlen(host->rrdpush_buffer));
-
- if(errno == EAGAIN || errno == EINTR) {
- debug(D_STREAM, "STREAM: poll() failed with EAGAIN or EINTR...");
- continue;
+ else if(unlikely(now_monotonic_sec() - last_sent_t > timeout)) {
+ error("STREAM %s [send to %s]: could not send metrics for %d seconds - closing connection - we have sent %zu bytes on this connection.", host->hostname, connected_to, timeout, sent_bytes_on_this_connection);
+ rrdpush_sender_thread_close_socket(host);
}
- error("STREAM %s [send to %s]: failed to poll().", host->hostname, connected_to);
- close(host->rrdpush_socket);
- host->rrdpush_socket = -1;
- break;
- }
- else if(likely(retval)) {
- if (ifd->revents & POLLIN || ifd->revents & POLLPRI) {
- debug(D_STREAM, "STREAM: Data added to send buffer (current buffer length %zu bytes)...", buffer_strlen(host->rrdpush_buffer));
+ ifd->fd = host->rrdpush_sender_pipe[PIPE_READ];
+ ifd->events = POLLIN;
+ ifd->revents = 0;
- char buffer[1000 + 1];
- if (read(host->rrdpush_pipe[PIPE_READ], buffer, 1000) == -1)
- error("STREAM %s [send to %s]: cannot read from internal pipe.", host->hostname, connected_to);
+ ofd->fd = host->rrdpush_sender_socket;
+ ofd->revents = 0;
+ if(ofd->fd != -1 && begin < buffer_strlen(host->rrdpush_sender_buffer)) {
+ debug(D_STREAM, "STREAM: Requesting data output on streaming socket %d...", ofd->fd);
+ ofd->events = POLLOUT;
+ fdmax = 2;
+ }
+ else {
+ debug(D_STREAM, "STREAM: Not requesting data output on streaming socket %d (nothing to send now)...", ofd->fd);
+ ofd->events = 0;
+ fdmax = 1;
}
- if (ofd->revents & POLLOUT) {
- if (begin < buffer_strlen(host->rrdpush_buffer)) {
- debug(D_STREAM, "STREAM: Sending data (current buffer length %zu bytes, begin = %zu)...", buffer_strlen(host->rrdpush_buffer), begin);
+ debug(D_STREAM, "STREAM: Waiting for poll() events (current buffer length %zu bytes)...", buffer_strlen(host->rrdpush_sender_buffer));
+ if(unlikely(netdata_exit)) break;
+ int retval = poll(fds, fdmax, 1000);
+ if(unlikely(netdata_exit)) break;
- // BEGIN RRDPUSH LOCKED SESSION
+ if(unlikely(retval == -1)) {
+ debug(D_STREAM, "STREAM: poll() failed (current buffer length %zu bytes)...", buffer_strlen(host->rrdpush_sender_buffer));
- // during this session, data collectors
- // will not be able to append data to our buffer
- // but the socket is in non-blocking mode
- // so, we will not block at send()
+ if(errno == EAGAIN || errno == EINTR) {
+ debug(D_STREAM, "STREAM: poll() failed with EAGAIN or EINTR...");
+ }
+ else {
+ error("STREAM %s [send to %s]: failed to poll(). Closing socket.", host->hostname, connected_to);
+ rrdpush_sender_thread_close_socket(host);
+ }
- if (pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL) != 0)
- error("STREAM %s [send]: cannot set pthread cancel state to DISABLE.", host->hostname);
+ continue;
+ }
+ else if(likely(retval)) {
+ if (ifd->revents & POLLIN || ifd->revents & POLLPRI) {
+ debug(D_STREAM, "STREAM: Data added to send buffer (current buffer length %zu bytes)...", buffer_strlen(host->rrdpush_sender_buffer));
- debug(D_STREAM, "STREAM: Getting exclusive lock on host...");
- rrdpush_lock(host);
+ char buffer[1000 + 1];
+ if (read(host->rrdpush_sender_pipe[PIPE_READ], buffer, 1000) == -1)
+ error("STREAM %s [send to %s]: cannot read from internal pipe.", host->hostname, connected_to);
+ }
- debug(D_STREAM, "STREAM: Sending data, starting from %zu, size %zu...", begin, buffer_strlen(host->rrdpush_buffer));
- ssize_t ret = send(host->rrdpush_socket, &host->rrdpush_buffer->buffer[begin], buffer_strlen(host->rrdpush_buffer) - begin, MSG_DONTWAIT);
- if (unlikely(ret == -1)) {
- if (errno != EAGAIN && errno != EINTR && errno != EWOULDBLOCK) {
- debug(D_STREAM, "STREAM: Send failed - closing socket...");
- error("STREAM %s [send to %s]: failed to send metrics - closing connection - we have sent %zu bytes on this connection.", host->hostname, connected_to, sent_connection);
- close(host->rrdpush_socket);
- host->rrdpush_socket = -1;
- }
- else {
- debug(D_STREAM, "STREAM: Send failed - will retry...");
+ if (ofd->revents & POLLOUT) {
+ if (begin < buffer_strlen(host->rrdpush_sender_buffer)) {
+ debug(D_STREAM, "STREAM: Sending data (current buffer length %zu bytes, begin = %zu)...", buffer_strlen(host->rrdpush_sender_buffer), begin);
+
+ // BEGIN RRDPUSH LOCKED SESSION
+
+ // during this session, data collectors
+ // will not be able to append data to our buffer
+ // but the socket is in non-blocking mode
+ // so, we will not block at send()
+
+ if (pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL) != 0)
+ error("STREAM %s [send]: cannot set pthread cancel state to DISABLE.", host->hostname);
+
+ debug(D_STREAM, "STREAM: Getting exclusive lock on host...");
+ rrdpush_buffer_lock(host);
+
+ debug(D_STREAM, "STREAM: Sending data, starting from %zu, size %zu...", begin, buffer_strlen(host->rrdpush_sender_buffer));
+ ssize_t ret = send(host->rrdpush_sender_socket, &host->rrdpush_sender_buffer->buffer[begin], buffer_strlen(host->rrdpush_sender_buffer) - begin, MSG_DONTWAIT);
+ if (unlikely(ret == -1)) {
+ if (errno != EAGAIN && errno != EINTR && errno != EWOULDBLOCK) {
+ debug(D_STREAM, "STREAM: Send failed - closing socket...");
+ error("STREAM %s [send to %s]: failed to send metrics - closing connection - we have sent %zu bytes on this connection.", host->hostname, connected_to, sent_bytes_on_this_connection);
+ rrdpush_sender_thread_close_socket(host);
+ }
+ else {
+ debug(D_STREAM, "STREAM: Send failed - will retry...");
+ }
}
- }
- else if (likely(ret > 0)) {
- // DEBUG - dump the scring to see it
- //char c = host->rrdpush_buffer->buffer[begin + ret];
- //host->rrdpush_buffer->buffer[begin + ret] = '\0';
- //debug(D_STREAM, "STREAM: sent from %zu to %zd:\n%s\n", begin, ret, &host->rrdpush_buffer->buffer[begin]);
- //host->rrdpush_buffer->buffer[begin + ret] = c;
-
- sent_connection += ret;
- sent_bytes += ret;
- begin += ret;
-
- if (begin == buffer_strlen(host->rrdpush_buffer)) {
- // we send it all
-
- debug(D_STREAM, "STREAM: Sent %zd bytes (the whole buffer)...", ret);
- buffer_flush(host->rrdpush_buffer);
- begin = 0;
+ else if (likely(ret > 0)) {
+ // DEBUG - dump the string to see it
+ //char c = host->rrdpush_sender_buffer->buffer[begin + ret];
+ //host->rrdpush_sender_buffer->buffer[begin + ret] = '\0';
+ //debug(D_STREAM, "STREAM: sent from %zu to %zd:\n%s\n", begin, ret, &host->rrdpush_sender_buffer->buffer[begin]);
+ //host->rrdpush_sender_buffer->buffer[begin + ret] = c;
+
+ sent_bytes_on_this_connection += ret;
+ sent_bytes += ret;
+ begin += ret;
+
+ if (begin == buffer_strlen(host->rrdpush_sender_buffer)) {
+ // we send it all
+
+ debug(D_STREAM, "STREAM: Sent %zd bytes (the whole buffer)...", ret);
+ buffer_flush(host->rrdpush_sender_buffer);
+ begin = 0;
+ }
+ else {
+ debug(D_STREAM, "STREAM: Sent %zd bytes (part of the data buffer)...", ret);
+ }
+
+ last_sent_t = now_monotonic_sec();
}
else {
- debug(D_STREAM, "STREAM: Sent %zd bytes (part of the data buffer)...", ret);
+ debug(D_STREAM, "STREAM: send() returned %zd - closing the socket...", ret);
+ error("STREAM %s [send to %s]: failed to send metrics (send() returned %zd) - closing connection - we have sent %zu bytes on this connection.",
+ host->hostname, connected_to, ret, sent_bytes_on_this_connection);
+ rrdpush_sender_thread_close_socket(host);
}
- last_sent_t = now_monotonic_sec();
+ debug(D_STREAM, "STREAM: Releasing exclusive lock on host...");
+ rrdpush_buffer_unlock(host);
+
+ if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0)
+ error("STREAM %s [send]: cannot set pthread cancel state to ENABLE.", host->hostname);
+
+ // END RRDPUSH LOCKED SESSION
}
else {
- debug(D_STREAM, "STREAM: send() returned %zd - closing the socket...", ret);
- error("STREAM %s [send to %s]: failed to send metrics (send() returned %zd) - closing connection - we have sent %zu bytes on this connection.",
- host->hostname, connected_to, ret, sent_connection);
- close(host->rrdpush_socket);
- host->rrdpush_socket = -1;
+ debug(D_STREAM, "STREAM: we have sent the entire buffer, but we received POLLOUT...");
}
-
- debug(D_STREAM, "STREAM: Releasing exclusive lock on host...");
- rrdpush_unlock(host);
-
- if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0)
- error("STREAM %s [send]: cannot set pthread cancel state to ENABLE.", host->hostname);
-
- // END RRDPUSH LOCKED SESSION
- }
- else {
- debug(D_STREAM, "STREAM: we have sent the entire buffer, but we received POLLOUT...");
}
- }
- if(unlikely(ofd->revents & POLLERR)) {
- debug(D_STREAM, "STREAM: Send failed (POLLERR) - closing socket...");
- error("STREAM %s [send to %s]: connection reports errors (POLLERR), closing it - we have sent %zu bytes on this connection.", host->hostname, connected_to, sent_connection);
- close(host->rrdpush_socket);
- host->rrdpush_socket = -1;
- }
- else if(unlikely(ofd->revents & POLLHUP)) {
- debug(D_STREAM, "STREAM: Send failed (POLLHUP) - closing socket...");
- error("STREAM %s [send to %s]: connection closed by remote end (POLLHUP) - we have sent %zu bytes on this connection.", host->hostname, connected_to, sent_connection);
- close(host->rrdpush_socket);
- host->rrdpush_socket = -1;
+ if(host->rrdpush_sender_socket != -1) {
+ char *error = NULL;
+
+ if (unlikely(ofd->revents & POLLERR))
+ error = "socket reports errors (POLLERR)";
+
+ else if (unlikely(ofd->revents & POLLHUP))
+ error = "connection closed by remote end (POLLHUP)";
+
+ else if (unlikely(ofd->revents & POLLNVAL))
+ error = "connection is invalid (POLLNVAL)";
+
+ if(unlikely(error)) {
+ debug(D_STREAM, "STREAM: %s - closing socket...", error);
+ error("STREAM %s [send to %s]: %s - reopening socket - we have sent %zu bytes on this connection.", host->hostname, connected_to, error, sent_bytes_on_this_connection);
+ rrdpush_sender_thread_close_socket(host);
+ }
+ }
}
- else if(unlikely(ofd->revents & POLLNVAL)) {
- debug(D_STREAM, "STREAM: Send failed (POLLNVAL) - closing socket...");
- error("STREAM %s [send to %s]: connection is invalid (POLLNVAL), closing it - we have sent %zu bytes on this connection.", host->hostname, connected_to, sent_connection);
- close(host->rrdpush_socket);
- host->rrdpush_socket = -1;
+ else {
+ debug(D_STREAM, "STREAM: poll() timed out.");
}
- }
- else {
- debug(D_STREAM, "STREAM: poll() timed out.");
- }
- // protection from overflow
- if(buffer_strlen(host->rrdpush_buffer) > max_size) {
- debug(D_STREAM, "STREAM: Buffer is too big (%zu bytes), bigger than the max (%zu) - flushing it...", buffer_strlen(host->rrdpush_buffer), max_size);
- errno = 0;
- error("STREAM %s [send to %s]: too many data pending - buffer is %zu bytes long, %zu unsent - we have sent %zu bytes in total, %zu on this connection. Closing connection to flush the data.", host->hostname, connected_to, host->rrdpush_buffer->len, host->rrdpush_buffer->len - begin, sent_bytes, sent_connection);
- if(host->rrdpush_socket != -1) {
- close(host->rrdpush_socket);
- host->rrdpush_socket = -1;
+ // protection from overflow
+ if(buffer_strlen(host->rrdpush_sender_buffer) > max_size) {
+ debug(D_STREAM, "STREAM: Buffer is too big (%zu bytes), bigger than the max (%zu) - flushing it...", buffer_strlen(host->rrdpush_sender_buffer), max_size);
+ errno = 0;
+ error("STREAM %s [send to %s]: too many data pending - buffer is %zu bytes long, %zu unsent - we have sent %zu bytes in total, %zu on this connection. Closing connection to flush the data.", host->hostname, connected_to, host->rrdpush_sender_buffer->len, host->rrdpush_sender_buffer->len - begin, sent_bytes, sent_bytes_on_this_connection);
+ rrdpush_sender_thread_close_socket(host);
}
}
- }
-
-cleanup:
- debug(D_WEB_CLIENT, "STREAM %s [send]: sending thread exits.", host->hostname);
-
- if(pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL) != 0)
- error("STREAM %s [send]: cannot set pthread cancel state to DISABLE.", host->hostname);
-
- rrdpush_lock(host);
- rrdhost_wrlock(host);
- rrdpush_sender_thread_cleanup_locked_all(host);
- rrdhost_unlock(host);
- rrdpush_unlock(host);
- if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0)
- error("STREAM %s [send]: cannot set pthread cancel state to ENABLE.", host->hostname);
+ pthread_cleanup_pop(1);
pthread_exit(NULL);
return NULL;
@@ -560,7 +699,11 @@ cleanup:
// ----------------------------------------------------------------------------
// rrdpush receiver thread
-static int rrdpush_receive(int fd, const char *key, const char *hostname, const char *registry_hostname, const char *machine_guid, const char *os, const char *tags, int update_every, char *client_ip, char *client_port) {
+static void log_stream_connection(const char *client_ip, const char *client_port, const char *api_key, const char *machine_guid, const char *host, const char *msg) {
+ log_access("STREAM: %d '[%s]:%s' '%s' host '%s' api key '%s' machine guid '%s'", gettid(), client_ip, client_port, msg, host, api_key, machine_guid);
+}
+
+static int rrdpush_receive(int fd, const char *key, const char *hostname, const char *registry_hostname, const char *machine_guid, const char *os, const char *timezone, const char *tags, int update_every, char *client_ip, char *client_port) {
RRDHOST *host;
int history = default_rrd_history_entries;
RRD_MEMORY_MODE mode = default_rrd_memory_mode;
@@ -606,6 +749,7 @@ static int rrdpush_receive(int fd, const char *key, const char *hostname, const
, registry_hostname
, machine_guid
, os
+ , timezone
, tags
, update_every
, history
@@ -618,6 +762,7 @@ static int rrdpush_receive(int fd, const char *key, const char *hostname, const
if(!host) {
close(fd);
+ log_stream_connection(client_ip, client_port, key, machine_guid, hostname, "FAILED - CANNOT ACQUIRE HOST");
error("STREAM %s [receive from [%s]:%s]: failed to find/create host structure.", hostname, client_ip, client_port);
return 1;
}
@@ -656,6 +801,7 @@ static int rrdpush_receive(int fd, const char *key, const char *hostname, const
info("STREAM %s [receive from [%s]:%s]: initializing communication...", host->hostname, client_ip, client_port);
if(send_timeout(fd, START_STREAMING_PROMPT, strlen(START_STREAMING_PROMPT), 0, 60) != strlen(START_STREAMING_PROMPT)) {
+ log_stream_connection(client_ip, client_port, key, host->machine_guid, host->hostname, "FAILED - CANNOT REPLY");
error("STREAM %s [receive from [%s]:%s]: cannot send ready command.", host->hostname, client_ip, client_port);
close(fd);
return 0;
@@ -668,6 +814,7 @@ static int rrdpush_receive(int fd, const char *key, const char *hostname, const
// convert the socket to a FILE *
FILE *fp = fdopen(fd, "r");
if(!fp) {
+ log_stream_connection(client_ip, client_port, key, host->machine_guid, host->hostname, "FAILED - SOCKET ERROR");
error("STREAM %s [receive from [%s]:%s]: failed to get a FILE for FD %d.", host->hostname, client_ip, client_port, fd);
close(fd);
return 0;
@@ -677,8 +824,9 @@ static int rrdpush_receive(int fd, const char *key, const char *hostname, const
if(host->connected_senders > 0)
info("STREAM %s [receive from [%s]:%s]: multiple streaming connections for the same host detected. If multiple netdata are pushing metrics for the same charts, at the same time, the result is unexpected.", host->hostname, client_ip, client_port);
+ rrdhost_flag_clear(host, RRDHOST_FLAG_ORPHAN);
host->connected_senders++;
- rrdhost_flag_clear(host, RRDHOST_ORPHAN);
+ host->senders_disconnected_time = 0;
if(health_enabled != CONFIG_BOOLEAN_NO) {
if(alarms_delay > 0) {
host->health_delay_up_to = now_realtime_sec() + alarms_delay;
@@ -692,20 +840,25 @@ static int rrdpush_receive(int fd, const char *key, const char *hostname, const
// call the plugins.d processor to receive the metrics
info("STREAM %s [receive from [%s]:%s]: receiving metrics...", host->hostname, client_ip, client_port);
+ log_stream_connection(client_ip, client_port, key, host->machine_guid, host->hostname, "CONNECTED");
+
size_t count = pluginsd_process(host, &cd, fp, 1);
- error("STREAM %s [receive from [%s]:%s]: disconnected (completed updates %zu).", host->hostname, client_ip, client_port, count);
+
+ log_stream_connection(client_ip, client_port, key, host->machine_guid, host->hostname, "DISCONNECTED");
+ error("STREAM %s [receive from [%s]:%s]: disconnected (completed %zu updates).", host->hostname, client_ip, client_port, count);
rrdhost_wrlock(host);
host->senders_disconnected_time = now_realtime_sec();
host->connected_senders--;
if(!host->connected_senders) {
- rrdhost_flag_set(host, RRDHOST_ORPHAN);
+ rrdhost_flag_set(host, RRDHOST_FLAG_ORPHAN);
if(health_enabled == CONFIG_BOOLEAN_AUTO)
host->health_enabled = 0;
}
rrdhost_unlock(host);
- rrdpush_sender_thread_stop(host);
+ if(host->connected_senders == 0)
+ rrdpush_sender_thread_stop(host);
// cleanup
fclose(fp);
@@ -720,6 +873,7 @@ struct rrdpush_thread {
char *registry_hostname;
char *machine_guid;
char *os;
+ char *timezone;
char *tags;
char *client_ip;
char *client_port;
@@ -737,7 +891,7 @@ static void *rrdpush_receiver_thread(void *ptr) {
info("STREAM %s [%s]:%s: receive thread created (task id %d)", rpt->hostname, rpt->client_ip, rpt->client_port, gettid());
- rrdpush_receive(rpt->fd, rpt->key, rpt->hostname, rpt->registry_hostname, rpt->machine_guid, rpt->os, rpt->tags, rpt->update_every, rpt->client_ip, rpt->client_port);
+ rrdpush_receive(rpt->fd, rpt->key, rpt->hostname, rpt->registry_hostname, rpt->machine_guid, rpt->os, rpt->timezone, rpt->tags, rpt->update_every, rpt->client_ip, rpt->client_port);
info("STREAM %s [receive from [%s]:%s]: receive thread ended (task id %d)", rpt->hostname, rpt->client_ip, rpt->client_port, gettid());
freez(rpt->key);
@@ -745,6 +899,7 @@ static void *rrdpush_receiver_thread(void *ptr) {
freez(rpt->registry_hostname);
freez(rpt->machine_guid);
freez(rpt->os);
+ freez(rpt->timezone);
freez(rpt->tags);
freez(rpt->client_ip);
freez(rpt->client_port);
@@ -757,25 +912,30 @@ static void *rrdpush_receiver_thread(void *ptr) {
static void rrdpush_sender_thread_spawn(RRDHOST *host) {
rrdhost_wrlock(host);
- if(!host->rrdpush_spawn) {
- if(pthread_create(&host->rrdpush_thread, NULL, rrdpush_sender_thread, (void *) host))
+ if(!host->rrdpush_sender_spawn) {
+ if(pthread_create(&host->rrdpush_sender_thread, NULL, rrdpush_sender_thread, (void *) host))
error("STREAM %s [send]: failed to create new thread for client.", host->hostname);
-
- else if(pthread_detach(host->rrdpush_thread))
- error("STREAM %s [send]: cannot request detach newly created thread.", host->hostname);
-
- host->rrdpush_spawn = 1;
+ else
+ host->rrdpush_sender_spawn = 1;
}
rrdhost_unlock(host);
}
+int rrdpush_receiver_permission_denied(struct web_client *w) {
+ // we always respond with the same message and error code
+ // to prevent an attacker from gaining info about the error
+ buffer_flush(w->response.data);
+ buffer_sprintf(w->response.data, "You are not permitted to access this. Check the logs for more info.");
+ return 401;
+}
+
int rrdpush_receiver_thread_spawn(RRDHOST *host, struct web_client *w, char *url) {
(void)host;
info("STREAM [receive from [%s]:%s]: new client connection.", w->client_ip, w->client_port);
- char *key = NULL, *hostname = NULL, *registry_hostname = NULL, *machine_guid = NULL, *os = "unknown", *tags = NULL;
+ char *key = NULL, *hostname = NULL, *registry_hostname = NULL, *machine_guid = NULL, *os = "unknown", *timezone = "unknown", *tags = NULL;
int update_every = default_rrd_update_every;
char buf[GUID_LEN + 1];
@@ -799,6 +959,8 @@ int rrdpush_receiver_thread_spawn(RRDHOST *host, struct web_client *w, char *url
update_every = (int)strtoul(value, NULL, 0);
else if(!strcmp(name, "os"))
os = value;
+ else if(!strcmp(name, "timezone"))
+ timezone = value;
else if(!strcmp(name, "tags"))
tags = value;
else
@@ -806,52 +968,71 @@ int rrdpush_receiver_thread_spawn(RRDHOST *host, struct web_client *w, char *url
}
if(!key || !*key) {
+ log_stream_connection(w->client_ip, w->client_port, (key && *key)?key:"-", (machine_guid && *machine_guid)?machine_guid:"-", (hostname && *hostname)?hostname:"-", "ACCESS DENIED - NO KEY");
error("STREAM [receive from [%s]:%s]: request without an API key. Forbidding access.", w->client_ip, w->client_port);
- buffer_flush(w->response.data);
- buffer_sprintf(w->response.data, "You need an API key for this request.");
- return 401;
+ return rrdpush_receiver_permission_denied(w);
}
if(!hostname || !*hostname) {
+ log_stream_connection(w->client_ip, w->client_port, (key && *key)?key:"-", (machine_guid && *machine_guid)?machine_guid:"-", (hostname && *hostname)?hostname:"-", "ACCESS DENIED - NO HOSTNAME");
error("STREAM [receive from [%s]:%s]: request without a hostname. Forbidding access.", w->client_ip, w->client_port);
- buffer_flush(w->response.data);
- buffer_sprintf(w->response.data, "You need to send a hostname too.");
- return 400;
+ return rrdpush_receiver_permission_denied(w);
}
if(!machine_guid || !*machine_guid) {
+ log_stream_connection(w->client_ip, w->client_port, (key && *key)?key:"-", (machine_guid && *machine_guid)?machine_guid:"-", (hostname && *hostname)?hostname:"-", "ACCESS DENIED - NO MACHINE GUID");
error("STREAM [receive from [%s]:%s]: request without a machine GUID. Forbidding access.", w->client_ip, w->client_port);
- buffer_flush(w->response.data);
- buffer_sprintf(w->response.data, "You need to send a machine GUID too.");
- return 400;
+ return rrdpush_receiver_permission_denied(w);
}
if(regenerate_guid(key, buf) == -1) {
+ log_stream_connection(w->client_ip, w->client_port, (key && *key)?key:"-", (machine_guid && *machine_guid)?machine_guid:"-", (hostname && *hostname)?hostname:"-", "ACCESS DENIED - INVALID KEY");
error("STREAM [receive from [%s]:%s]: API key '%s' is not valid GUID (use the command uuidgen to generate one). Forbidding access.", w->client_ip, w->client_port, key);
- buffer_flush(w->response.data);
- buffer_sprintf(w->response.data, "Your API key is invalid.");
- return 401;
+ return rrdpush_receiver_permission_denied(w);
}
if(regenerate_guid(machine_guid, buf) == -1) {
+ log_stream_connection(w->client_ip, w->client_port, (key && *key)?key:"-", (machine_guid && *machine_guid)?machine_guid:"-", (hostname && *hostname)?hostname:"-", "ACCESS DENIED - INVALID MACHINE GUID");
error("STREAM [receive from [%s]:%s]: machine GUID '%s' is not GUID. Forbidding access.", w->client_ip, w->client_port, machine_guid);
- buffer_flush(w->response.data);
- buffer_sprintf(w->response.data, "Your machine GUID is invalid.");
- return 404;
+ return rrdpush_receiver_permission_denied(w);
}
if(!appconfig_get_boolean(&stream_config, key, "enabled", 0)) {
+ log_stream_connection(w->client_ip, w->client_port, (key && *key)?key:"-", (machine_guid && *machine_guid)?machine_guid:"-", (hostname && *hostname)?hostname:"-", "ACCESS DENIED - KEY NOT ENABLED");
error("STREAM [receive from [%s]:%s]: API key '%s' is not allowed. Forbidding access.", w->client_ip, w->client_port, key);
- buffer_flush(w->response.data);
- buffer_sprintf(w->response.data, "Your API key is not permitted access.");
- return 401;
+ return rrdpush_receiver_permission_denied(w);
+ }
+
+ {
+ SIMPLE_PATTERN *key_allow_from = simple_pattern_create(appconfig_get(&stream_config, key, "allow from", "*"), SIMPLE_PATTERN_EXACT);
+ if(key_allow_from) {
+ if(!simple_pattern_matches(key_allow_from, w->client_ip)) {
+ simple_pattern_free(key_allow_from);
+ log_stream_connection(w->client_ip, w->client_port, (key && *key)?key:"-", (machine_guid && *machine_guid)?machine_guid:"-", (hostname && *hostname) ? hostname : "-", "ACCESS DENIED - KEY NOT ALLOWED FROM THIS IP");
+ error("STREAM [receive from [%s]:%s]: API key '%s' is not permitted from this IP. Forbidding access.", w->client_ip, w->client_port, key);
+ return rrdpush_receiver_permission_denied(w);
+ }
+ simple_pattern_free(key_allow_from);
+ }
}
if(!appconfig_get_boolean(&stream_config, machine_guid, "enabled", 1)) {
+ log_stream_connection(w->client_ip, w->client_port, (key && *key)?key:"-", (machine_guid && *machine_guid)?machine_guid:"-", (hostname && *hostname)?hostname:"-", "ACCESS DENIED - MACHINE GUID NOT ENABLED");
error("STREAM [receive from [%s]:%s]: machine GUID '%s' is not allowed. Forbidding access.", w->client_ip, w->client_port, machine_guid);
- buffer_flush(w->response.data);
- buffer_sprintf(w->response.data, "Your machine guide is not permitted access.");
- return 404;
+ return rrdpush_receiver_permission_denied(w);
+ }
+
+ {
+ SIMPLE_PATTERN *machine_allow_from = simple_pattern_create(appconfig_get(&stream_config, machine_guid, "allow from", "*"), SIMPLE_PATTERN_EXACT);
+ if(machine_allow_from) {
+ if(!simple_pattern_matches(machine_allow_from, w->client_ip)) {
+ simple_pattern_free(machine_allow_from);
+ log_stream_connection(w->client_ip, w->client_port, (key && *key)?key:"-", (machine_guid && *machine_guid)?machine_guid:"-", (hostname && *hostname) ? hostname : "-", "ACCESS DENIED - MACHINE GUID NOT ALLOWED FROM THIS IP");
+ error("STREAM [receive from [%s]:%s]: Machine GUID '%s' is not permitted from this IP. Forbidding access.", w->client_ip, w->client_port, machine_guid);
+ return rrdpush_receiver_permission_denied(w);
+ }
+ simple_pattern_free(machine_allow_from);
+ }
}
struct rrdpush_thread *rpt = mallocz(sizeof(struct rrdpush_thread));
@@ -861,6 +1042,7 @@ int rrdpush_receiver_thread_spawn(RRDHOST *host, struct web_client *w, char *url
rpt->registry_hostname = strdupz((registry_hostname && *registry_hostname)?registry_hostname:hostname);
rpt->machine_guid = strdupz(machine_guid);
rpt->os = strdupz(os);
+ rpt->timezone = strdupz(timezone);
rpt->tags = (tags)?strdupz(tags):NULL;
rpt->client_ip = strdupz(w->client_ip);
rpt->client_port = strdupz(w->client_port);
diff --git a/src/rrdpush.h b/src/rrdpush.h
index c3c7f4a5..bf3d9435 100644
--- a/src/rrdpush.h
+++ b/src/rrdpush.h
@@ -14,4 +14,6 @@ extern void *rrdpush_sender_thread(void *ptr);
extern int rrdpush_receiver_thread_spawn(RRDHOST *host, struct web_client *w, char *url);
extern void rrdpush_sender_thread_stop(RRDHOST *host);
+extern void rrdpush_sender_send_this_host_variable_now(RRDHOST *host, RRDVAR *rv);
+
#endif //NETDATA_RRDPUSH_H
diff --git a/src/rrdset.c b/src/rrdset.c
index c5168f02..8504d1cb 100644
--- a/src/rrdset.c
+++ b/src/rrdset.c
@@ -135,11 +135,11 @@ char *rrdset_strncpyz_name(char *to, const char *from, size_t length) {
return to;
}
-void rrdset_set_name(RRDSET *st, const char *name) {
+int rrdset_set_name(RRDSET *st, const char *name) {
if(unlikely(st->name && !strcmp(st->name, name)))
- return;
+ return 1;
- debug(D_RRD_CALLS, "rrdset_set_name() old: %s, new: %s", st->name, name);
+ debug(D_RRD_CALLS, "rrdset_set_name() old: '%s', new: '%s'", st->name?st->name:"", name);
char b[CONFIG_MAX_VALUE + 1];
char n[RRD_ID_LENGTH_MAX + 1];
@@ -147,6 +147,11 @@ void rrdset_set_name(RRDSET *st, const char *name) {
snprintfz(n, RRD_ID_LENGTH_MAX, "%s.%s", st->type, name);
rrdset_strncpyz_name(b, n, CONFIG_MAX_VALUE);
+ if(rrdset_index_find_name(st->rrdhost, b, 0)) {
+ error("RRDSET: chart name '%s' on host '%s' already exists.", b, st->rrdhost->hostname);
+ return 0;
+ }
+
if(st->name) {
rrdset_index_del_name(st->rrdhost, st);
st->name = config_set_default(st->config_section, "name", b);
@@ -166,6 +171,8 @@ void rrdset_set_name(RRDSET *st, const char *name) {
if(unlikely(rrdset_index_add_name(st->rrdhost, st) != st))
error("RRDSET: INTERNAL ERROR: attempted to index duplicate chart name '%s'", st->name);
+
+ return 1;
}
inline void rrdset_is_obsolete(RRDSET *st) {
@@ -175,7 +182,7 @@ inline void rrdset_is_obsolete(RRDSET *st) {
// the chart will not get more updates (data collection)
// so, we have to push its definition now
- if(unlikely(st->rrdhost->rrdpush_enabled))
+ if(unlikely(st->rrdhost->rrdpush_send_enabled))
rrdset_push_chart_definition(st);
}
}
@@ -309,6 +316,9 @@ void rrdset_free(RRDSET *st) {
rrdfamily_free(st->rrdhost, st->rrdfamily);
+ debug(D_RRD_CALLS, "RRDSET: Cleaning up remaining chart variables for host '%s', chart '%s'", st->rrdhost->hostname, st->id);
+ rrdvar_free_remaining_variables(st->rrdhost, &st->rrdvar_root_index);
+
// ------------------------------------------------------------------------
// unlink it from the host
@@ -334,6 +344,8 @@ void rrdset_free(RRDSET *st) {
// free directly allocated members
freez(st->config_section);
+ freez(st->plugin_name);
+ freez(st->module_name);
switch(st->rrd_memory_mode) {
case RRD_MEMORY_MODE_SAVE:
@@ -416,6 +428,8 @@ RRDSET *rrdset_create_custom(
, const char *context
, const char *title
, const char *units
+ , const char *plugin
+ , const char *module
, long priority
, int update_every
, RRDSET_TYPE chart_type
@@ -423,12 +437,30 @@ RRDSET *rrdset_create_custom(
, long history_entries
) {
if(!type || !type[0]) {
- fatal("Cannot create rrd stats without a type.");
+ fatal("Cannot create rrd stats without a type: id '%s', name '%s', family '%s', context '%s', title '%s', units '%s', plugin '%s', module '%s'."
+ , (id && *id)?id:"<unset>"
+ , (name && *name)?name:"<unset>"
+ , (family && *family)?family:"<unset>"
+ , (context && *context)?context:"<unset>"
+ , (title && *title)?title:"<unset>"
+ , (units && *units)?units:"<unset>"
+ , (plugin && *plugin)?plugin:"<unset>"
+ , (module && *module)?module:"<unset>"
+ );
return NULL;
}
if(!id || !id[0]) {
- fatal("Cannot create rrd stats without an id.");
+ fatal("Cannot create rrd stats without an id: type '%s', name '%s', family '%s', context '%s', title '%s', units '%s', plugin '%s', module '%s'."
+ , type
+ , (name && *name)?name:"<unset>"
+ , (family && *family)?family:"<unset>"
+ , (context && *context)?context:"<unset>"
+ , (title && *title)?title:"<unset>"
+ , (units && *units)?units:"<unset>"
+ , (plugin && *plugin)?plugin:"<unset>"
+ , (module && *module)?module:"<unset>"
+ );
return NULL;
}
@@ -495,7 +527,7 @@ RRDSET *rrdset_create_custom(
if(st) {
memset(&st->avl, 0, sizeof(avl));
memset(&st->avlname, 0, sizeof(avl));
- memset(&st->variables_root_index, 0, sizeof(avl_tree_lock));
+ memset(&st->rrdvar_root_index, 0, sizeof(avl_tree_lock));
memset(&st->dimensions_index, 0, sizeof(avl_tree_lock));
memset(&st->rrdset_rwlock, 0, sizeof(netdata_rwlock_t));
@@ -507,6 +539,8 @@ RRDSET *rrdset_create_custom(
st->units = NULL;
st->context = NULL;
st->cache_dir = NULL;
+ st->plugin_name = NULL;
+ st->module_name = NULL;
st->dimensions = NULL;
st->rrdfamily = NULL;
st->rrdhost = NULL;
@@ -564,6 +598,9 @@ RRDSET *rrdset_create_custom(
st->rrd_memory_mode = (memory_mode == RRD_MEMORY_MODE_NONE) ? RRD_MEMORY_MODE_NONE : RRD_MEMORY_MODE_ALLOC;
}
+ st->plugin_name = plugin?strdup(plugin):NULL;
+ st->module_name = module?strdup(module):NULL;
+
st->config_section = strdup(config_section);
st->rrdhost = host;
st->memsize = size;
@@ -624,12 +661,16 @@ RRDSET *rrdset_create_custom(
st->upstream_resync_time = 0;
avl_init_lock(&st->dimensions_index, rrddim_compare);
- avl_init_lock(&st->variables_root_index, rrdvar_compare);
+ avl_init_lock(&st->rrdvar_root_index, rrdvar_compare);
netdata_rwlock_init(&st->rrdset_rwlock);
- if(name && *name) rrdset_set_name(st, name);
- else rrdset_set_name(st, id);
+ if(name && *name && rrdset_set_name(st, name))
+ // we did set the name
+ ;
+ else
+ // could not use the name, use the id
+ rrdset_set_name(st, id);
st->title = config_get(st->config_section, "title", title);
json_fix_string(st->title);
@@ -640,11 +681,11 @@ RRDSET *rrdset_create_custom(
host->rrdset_root = st;
if(host->health_enabled) {
- rrdsetvar_create(st, "last_collected_t", RRDVAR_TYPE_TIME_T, &st->last_collected_time.tv_sec, 0);
- rrdsetvar_create(st, "collected_total_raw", RRDVAR_TYPE_TOTAL, &st->last_collected_total, 0);
- rrdsetvar_create(st, "green", RRDVAR_TYPE_CALCULATED, &st->green, 0);
- rrdsetvar_create(st, "red", RRDVAR_TYPE_CALCULATED, &st->red, 0);
- rrdsetvar_create(st, "update_every", RRDVAR_TYPE_INT, &st->update_every, 0);
+ rrdsetvar_create(st, "last_collected_t", RRDVAR_TYPE_TIME_T, &st->last_collected_time.tv_sec, RRDVAR_OPTION_DEFAULT);
+ rrdsetvar_create(st, "collected_total_raw", RRDVAR_TYPE_TOTAL, &st->last_collected_total, RRDVAR_OPTION_DEFAULT);
+ rrdsetvar_create(st, "green", RRDVAR_TYPE_CALCULATED, &st->green, RRDVAR_OPTION_DEFAULT);
+ rrdsetvar_create(st, "red", RRDVAR_TYPE_CALCULATED, &st->red, RRDVAR_OPTION_DEFAULT);
+ rrdsetvar_create(st, "update_every", RRDVAR_TYPE_INT, &st->update_every, RRDVAR_OPTION_DEFAULT);
}
if(unlikely(rrdset_index_add(host, st) != st))
@@ -1029,7 +1070,7 @@ void rrdset_done(RRDSET *st) {
if(unlikely(netdata_exit)) return;
if(unlikely(st->rrd_memory_mode == RRD_MEMORY_MODE_NONE)) {
- if(unlikely(st->rrdhost->rrdpush_enabled))
+ if(unlikely(st->rrdhost->rrdpush_send_enabled))
rrdset_done_push_exclusive(st);
return;
@@ -1154,7 +1195,7 @@ void rrdset_done(RRDSET *st) {
}
st->counter_done++;
- if(unlikely(st->rrdhost->rrdpush_enabled))
+ if(unlikely(st->rrdhost->rrdpush_send_enabled))
rrdset_done_push(st);
#ifdef NETDATA_INTERNAL_CHECKS
diff --git a/src/rrdsetvar.c b/src/rrdsetvar.c
index 03d7aece..280156a8 100644
--- a/src/rrdsetvar.c
+++ b/src/rrdsetvar.c
@@ -8,29 +8,29 @@
static inline void rrdsetvar_free_variables(RRDSETVAR *rs) {
RRDSET *st = rs->rrdset;
+ // ------------------------------------------------------------------------
// CHART
-
- rrdvar_free(st->rrdhost, &st->variables_root_index, rs->var_local);
+ rrdvar_free(st->rrdhost, &st->rrdvar_root_index, rs->var_local);
rs->var_local = NULL;
+ // ------------------------------------------------------------------------
// FAMILY
-
- rrdvar_free(st->rrdhost, &st->rrdfamily->variables_root_index, rs->var_family);
+ rrdvar_free(st->rrdhost, &st->rrdfamily->rrdvar_root_index, rs->var_family);
rs->var_family = NULL;
- rrdvar_free(st->rrdhost, &st->rrdhost->variables_root_index, rs->var_host);
- rs->var_host = NULL;
+ rrdvar_free(st->rrdhost, &st->rrdfamily->rrdvar_root_index, rs->var_family_name);
+ rs->var_family_name = NULL;
+ // ------------------------------------------------------------------------
// HOST
+ rrdvar_free(st->rrdhost, &st->rrdhost->rrdvar_root_index, rs->var_host);
+ rs->var_host = NULL;
- rrdvar_free(st->rrdhost, &st->rrdfamily->variables_root_index, rs->var_family_name);
- rs->var_family_name = NULL;
-
- rrdvar_free(st->rrdhost, &st->rrdhost->variables_root_index, rs->var_host_name);
+ rrdvar_free(st->rrdhost, &st->rrdhost->rrdvar_root_index, rs->var_host_name);
rs->var_host_name = NULL;
+ // ------------------------------------------------------------------------
// KEYS
-
freez(rs->key_fullid);
rs->key_fullid = NULL;
@@ -39,10 +39,14 @@ static inline void rrdsetvar_free_variables(RRDSETVAR *rs) {
}
static inline void rrdsetvar_create_variables(RRDSETVAR *rs) {
- rrdsetvar_free_variables(rs);
-
RRDSET *st = rs->rrdset;
+ // ------------------------------------------------------------------------
+ // free the old ones (if any)
+
+ rrdsetvar_free_variables(rs);
+
+ // ------------------------------------------------------------------------
// KEYS
char buffer[RRDVAR_MAX_LENGTH + 1];
@@ -52,27 +56,27 @@ static inline void rrdsetvar_create_variables(RRDSETVAR *rs) {
snprintfz(buffer, RRDVAR_MAX_LENGTH, "%s.%s", st->name, rs->variable);
rs->key_fullname = strdupz(buffer);
+ // ------------------------------------------------------------------------
// CHART
+ rs->var_local = rrdvar_create_and_index("local", &st->rrdvar_root_index, rs->variable, rs->type, rs->value);
- rs->var_local = rrdvar_create_and_index("local", &st->variables_root_index, rs->variable, rs->type, rs->value);
-
+ // ------------------------------------------------------------------------
// FAMILY
+ rs->var_family = rrdvar_create_and_index("family", &st->rrdfamily->rrdvar_root_index, rs->key_fullid, rs->type, rs->value);
+ rs->var_family_name = rrdvar_create_and_index("family", &st->rrdfamily->rrdvar_root_index, rs->key_fullname, rs->type, rs->value);
- rs->var_family = rrdvar_create_and_index("family", &st->rrdfamily->variables_root_index, rs->key_fullid, rs->type, rs->value);
- rs->var_family_name = rrdvar_create_and_index("family", &st->rrdfamily->variables_root_index, rs->key_fullname, rs->type, rs->value);
-
+ // ------------------------------------------------------------------------
// HOST
-
- rs->var_host = rrdvar_create_and_index("host", &st->rrdhost->variables_root_index, rs->key_fullid, rs->type, rs->value);
- rs->var_host_name = rrdvar_create_and_index("host", &st->rrdhost->variables_root_index, rs->key_fullname, rs->type, rs->value);
-
+ rs->var_host = rrdvar_create_and_index("host", &st->rrdhost->rrdvar_root_index, rs->key_fullid, rs->type, rs->value);
+ rs->var_host_name = rrdvar_create_and_index("host", &st->rrdhost->rrdvar_root_index, rs->key_fullname, rs->type, rs->value);
}
-RRDSETVAR *rrdsetvar_create(RRDSET *st, const char *variable, int type, void *value, uint32_t options) {
+RRDSETVAR *rrdsetvar_create(RRDSET *st, const char *variable, RRDVAR_TYPE type, void *value, RRDVAR_OPTIONS options) {
debug(D_VARIABLES, "RRDVARSET create for chart id '%s' name '%s' with variable name '%s'", st->id, st->name, variable);
RRDSETVAR *rs = (RRDSETVAR *)callocz(1, sizeof(RRDSETVAR));
rs->variable = strdupz(variable);
+ rs->hash = simple_hash(rs->variable);
rs->type = type;
rs->value = value;
rs->options = options;
@@ -89,11 +93,9 @@ RRDSETVAR *rrdsetvar_create(RRDSET *st, const char *variable, int type, void *va
void rrdsetvar_rename_all(RRDSET *st) {
debug(D_VARIABLES, "RRDSETVAR rename for chart id '%s' name '%s'", st->id, st->name);
- RRDSETVAR *rs, *next = st->variables;
- while((rs = next)) {
- next = rs->next;
+ RRDSETVAR *rs;
+ for(rs = st->variables; rs ; rs = rs->next)
rrdsetvar_create_variables(rs);
- }
rrdsetcalc_link_matching(st);
}
@@ -115,6 +117,63 @@ void rrdsetvar_free(RRDSETVAR *rs) {
rrdsetvar_free_variables(rs);
freez(rs->variable);
+
+ if(rs->options & RRDVAR_OPTION_ALLOCATED)
+ freez(rs->value);
+
freez(rs);
}
+// --------------------------------------------------------------------------------------------------------------------
+// custom chart variables
+
+RRDSETVAR *rrdsetvar_custom_chart_variable_create(RRDSET *st, const char *name) {
+ char *n = strdupz(name);
+ rrdvar_fix_name(n);
+ uint32_t hash = simple_hash(n);
+
+ rrdset_wrlock(st);
+
+ // find it
+ RRDSETVAR *rs;
+ for(rs = st->variables; rs ; rs = rs->next) {
+ if(hash == rs->hash && strcmp(n, rs->variable) == 0) {
+ rrdset_unlock(st);
+ if(rs->options & RRDVAR_OPTION_ALLOCATED) {
+ free(n);
+ return rs;
+ }
+ else {
+ error("RRDSETVAR: custom variable '%s' on chart '%s' of host '%s', conflicts with an internal chart variable", n, st->id, st->rrdhost->hostname);
+ free(n);
+ return NULL;
+ }
+ }
+ }
+
+ // not found, allocate one
+
+ calculated_number *v = mallocz(sizeof(calculated_number));
+ *v = NAN;
+
+ rs = rrdsetvar_create(st, n, RRDVAR_TYPE_CALCULATED, v, RRDVAR_OPTION_ALLOCATED);
+ rrdset_unlock(st);
+
+ free(n);
+ return rs;
+}
+
+void rrdsetvar_custom_chart_variable_set(RRDSETVAR *rs, calculated_number value) {
+ if(unlikely(!(rs->options & RRDVAR_OPTION_ALLOCATED))) {
+ error("RRDSETVAR: requested to set variable '%s' of chart '%s' on host '%s' to value " CALCULATED_NUMBER_FORMAT " but the variable is not a custom one.", rs->variable, rs->rrdset->id, rs->rrdset->rrdhost->hostname, value);
+ }
+ else {
+ calculated_number *v = rs->value;
+ if(*v != value) {
+ *v = value;
+
+ // mark the chart to be sent upstream
+ rrdset_flag_clear(rs->rrdset, RRDSET_FLAG_EXPOSED_UPSTREAM);
+ }
+ }
+}
diff --git a/src/rrdvar.c b/src/rrdvar.c
index 2223d7c9..9119b538 100644
--- a/src/rrdvar.c
+++ b/src/rrdvar.c
@@ -56,14 +56,17 @@ inline void rrdvar_free(RRDHOST *host, avl_tree_lock *tree, RRDVAR *rv) {
if(tree) {
debug(D_VARIABLES, "Deleting variable '%s'", rv->name);
if(unlikely(!rrdvar_index_del(tree, rv)))
- error("Attempted to delete variable '%s' from host '%s', but it is not found.", rv->name, host->hostname);
+ error("RRDVAR: Attempted to delete variable '%s' from host '%s', but it is not found.", rv->name, host->hostname);
}
+ if(rv->type == RRDVAR_TYPE_CALCULATED_ALLOCATED)
+ freez(rv->value);
+
freez(rv->name);
freez(rv);
}
-inline RRDVAR *rrdvar_create_and_index(const char *scope, avl_tree_lock *tree, const char *name, int type, void *value) {
+inline RRDVAR *rrdvar_create_and_index(const char *scope, avl_tree_lock *tree, const char *name, RRDVAR_TYPE type, void *value) {
char *variable = strdupz(name);
rrdvar_fix_name(variable);
uint32_t hash = simple_hash(variable);
@@ -81,7 +84,8 @@ inline RRDVAR *rrdvar_create_and_index(const char *scope, avl_tree_lock *tree, c
RRDVAR *ret = rrdvar_index_add(tree, rv);
if(unlikely(ret != rv)) {
debug(D_VARIABLES, "Variable '%s' in scope '%s' already exists", variable, scope);
- rrdvar_free(NULL, NULL, rv);
+ freez(rv);
+ freez(variable);
rv = NULL;
}
else
@@ -101,61 +105,64 @@ inline RRDVAR *rrdvar_create_and_index(const char *scope, avl_tree_lock *tree, c
return rv;
}
+void rrdvar_free_remaining_variables(RRDHOST *host, avl_tree_lock *tree_lock) {
+ // FIXME: this is not bullet proof - avl should support some means to destroy it
+ // with a callback for each item already in the index
+
+ RRDVAR *rv, *last = NULL;
+ while((rv = (RRDVAR *)tree_lock->avl_tree.root)) {
+ if(unlikely(rv == last)) {
+ error("RRDVAR: INTERNAL ERROR: Cannot cleanup tree of RRDVARs");
+ break;
+ }
+ last = rv;
+ rrdvar_free(host, tree_lock, rv);
+ }
+}
+
// ----------------------------------------------------------------------------
-// CUSTOM VARIABLES
+// CUSTOM HOST VARIABLES
-RRDVAR *rrdvar_custom_host_variable_create(RRDHOST *host, const char *name) {
+inline int rrdvar_callback_for_all_host_variables(RRDHOST *host, int (*callback)(void *rrdvar, void *data), void *data) {
+ return avl_traverse_lock(&host->rrdvar_root_index, callback, data);
+}
+
+static RRDVAR *rrdvar_custom_variable_create(const char *scope, avl_tree_lock *tree_lock, const char *name) {
calculated_number *v = callocz(1, sizeof(calculated_number));
*v = NAN;
- RRDVAR *rv = rrdvar_create_and_index("host", &host->variables_root_index, name, RRDVAR_TYPE_CALCULATED_ALLOCATED, v);
+
+ RRDVAR *rv = rrdvar_create_and_index(scope, tree_lock, name, RRDVAR_TYPE_CALCULATED_ALLOCATED, v);
if(unlikely(!rv)) {
free(v);
- error("Requested variable '%s' already exists - possibly 2 plugins will be updating it at the same time", name);
+ debug(D_VARIABLES, "Requested variable '%s' already exists - possibly 2 plugins are updating it at the same time.", name);
char *variable = strdupz(name);
rrdvar_fix_name(variable);
uint32_t hash = simple_hash(variable);
- rv = rrdvar_index_find(&host->variables_root_index, variable, hash);
+ rv = rrdvar_index_find(tree_lock, variable, hash);
+
+ freez(variable);
}
return rv;
}
-void rrdvar_custom_host_variable_destroy(RRDHOST *host, const char *name) {
- char *variable = strdupz(name);
- rrdvar_fix_name(variable);
- uint32_t hash = simple_hash(variable);
-
- RRDVAR *rv = rrdvar_index_find(&host->variables_root_index, variable, hash);
- freez(variable);
-
- if(!rv) {
- error("Attempted to remove variable '%s' from host '%s', but it does not exist.", name, host->hostname);
- return;
- }
-
- if(rv->type != RRDVAR_TYPE_CALCULATED_ALLOCATED) {
- error("Attempted to remove variable '%s' from host '%s', but it does not a custom allocated variable.", name, host->hostname);
- return;
- }
-
- if(!rrdvar_index_del(&host->variables_root_index, rv)) {
- error("Attempted to remove variable '%s' from host '%s', but it cannot be found.", name, host->hostname);
- return;
- }
-
- freez(rv->name);
- freez(rv->value);
- freez(rv);
+RRDVAR *rrdvar_custom_host_variable_create(RRDHOST *host, const char *name) {
+ return rrdvar_custom_variable_create("host", &host->rrdvar_root_index, name);
}
-void rrdvar_custom_host_variable_set(RRDVAR *rv, calculated_number value) {
+void rrdvar_custom_host_variable_set(RRDHOST *host, RRDVAR *rv, calculated_number value) {
if(rv->type != RRDVAR_TYPE_CALCULATED_ALLOCATED)
error("requested to set variable '%s' to value " CALCULATED_NUMBER_FORMAT " but the variable is not a custom one.", rv->name, value);
else {
calculated_number *v = rv->value;
- *v = value;
+ if(*v != value) {
+ *v = value;
+
+ // if the host is streaming, send this variable upstream immediately
+ rrdpush_sender_send_this_host_variable_now(host, rv);
+ }
}
}
@@ -191,7 +198,7 @@ static calculated_number rrdvar2number(RRDVAR *rv) {
}
default:
- error("I don't know how to convert RRDVAR type %d to calculated_number", rv->type);
+ error("I don't know how to convert RRDVAR type %u to calculated_number", rv->type);
return NAN;
}
}
@@ -202,19 +209,19 @@ int health_variable_lookup(const char *variable, uint32_t hash, RRDCALC *rc, cal
if(!st) return 0;
- rv = rrdvar_index_find(&st->variables_root_index, variable, hash);
+ rv = rrdvar_index_find(&st->rrdvar_root_index, variable, hash);
if(rv) {
*result = rrdvar2number(rv);
return 1;
}
- rv = rrdvar_index_find(&st->rrdfamily->variables_root_index, variable, hash);
+ rv = rrdvar_index_find(&st->rrdfamily->rrdvar_root_index, variable, hash);
if(rv) {
*result = rrdvar2number(rv);
return 1;
}
- rv = rrdvar_index_find(&st->rrdhost->variables_root_index, variable, hash);
+ rv = rrdvar_index_find(&st->rrdhost->rrdvar_root_index, variable, hash);
if(rv) {
*result = rrdvar2number(rv);
return 1;
@@ -253,13 +260,13 @@ void health_api_v1_chart_variables2json(RRDSET *st, BUFFER *buf) {
};
buffer_sprintf(buf, "{\n\t\"chart\": \"%s\",\n\t\"chart_name\": \"%s\",\n\t\"chart_context\": \"%s\",\n\t\"chart_variables\": {", st->id, st->name, st->context);
- avl_traverse_lock(&st->variables_root_index, single_variable2json, (void *)&helper);
+ avl_traverse_lock(&st->rrdvar_root_index, single_variable2json, (void *)&helper);
buffer_sprintf(buf, "\n\t},\n\t\"family\": \"%s\",\n\t\"family_variables\": {", st->family);
helper.counter = 0;
- avl_traverse_lock(&st->rrdfamily->variables_root_index, single_variable2json, (void *)&helper);
+ avl_traverse_lock(&st->rrdfamily->rrdvar_root_index, single_variable2json, (void *)&helper);
buffer_sprintf(buf, "\n\t},\n\t\"host\": \"%s\",\n\t\"host_variables\": {", st->rrdhost->hostname);
helper.counter = 0;
- avl_traverse_lock(&st->rrdhost->variables_root_index, single_variable2json, (void *)&helper);
+ avl_traverse_lock(&st->rrdhost->rrdvar_root_index, single_variable2json, (void *)&helper);
buffer_strcat(buf, "\n\t}\n}\n");
}
diff --git a/src/signals.h b/src/signals.h
index d8611ede..2fdd3655 100644
--- a/src/signals.h
+++ b/src/signals.h
@@ -4,7 +4,7 @@
extern void signals_init(void);
extern void signals_block(void);
extern void signals_unblock(void);
-extern void signals_handle(void);
extern void signals_reset(void);
+extern void signals_handle(void) NORETURN;
#endif //NETDATA_SIGNALS_H
diff --git a/src/simple_pattern.c b/src/simple_pattern.c
index f72a42d0..469ea396 100644
--- a/src/simple_pattern.c
+++ b/src/simple_pattern.c
@@ -12,12 +12,13 @@ struct simple_pattern {
struct simple_pattern *next;
};
-static inline struct simple_pattern *parse_pattern(const char *str, SIMPLE_PREFIX_MODE default_mode) {
+static inline struct simple_pattern *parse_pattern(char *str, SIMPLE_PREFIX_MODE default_mode) {
+ // fprintf(stderr, "PARSING PATTERN: '%s'\n", str);
+
SIMPLE_PREFIX_MODE mode;
struct simple_pattern *child = NULL;
- char *buf = strdupz(str);
- char *s = buf, *c = buf;
+ char *s = str, *c = str;
// skip asterisks in front
while(*c == '*') c++;
@@ -64,8 +65,6 @@ static inline struct simple_pattern *parse_pattern(const char *str, SIMPLE_PREFI
m->child = child;
- freez(buf);
-
return m;
}
@@ -74,51 +73,63 @@ SIMPLE_PATTERN *simple_pattern_create(const char *list, SIMPLE_PREFIX_MODE defau
if(unlikely(!list || !*list)) return root;
- char *buf = strdupz(list);
- if(buf && *buf) {
- char *s = buf;
+ char *buf = mallocz(strlen(list) + 1);
+ const char *s = list;
- while(s && *s) {
- char negative = 0;
+ while(s && *s) {
+ buf[0] = '\0';
+ char *c = buf;
- // skip all spaces
- while(isspace(*s)) s++;
+ char negative = 0;
- if(*s == '!') {
- negative = 1;
- s++;
- }
+ // skip all spaces
+ while(isspace(*s))
+ s++;
- // empty string
- if(unlikely(!*s)) break;
+ if(*s == '!') {
+ negative = 1;
+ s++;
+ }
- // find the next space
- char *c = s;
- while(*c && !isspace(*c)) c++;
+ // empty string
+ if(unlikely(!*s))
+ break;
- // find the next word
- char *n;
- if(likely(*c)) n = c + 1;
- else n = NULL;
+ // find the next space
+ char escape = 0;
+ while(*s) {
+ if(*s == '\\' && !escape) {
+ escape = 1;
+ s++;
+ }
+ else {
+ if (isspace(*s) && !escape) {
+ s++;
+ break;
+ }
- // terminate our string
- *c = '\0';
+ *c++ = *s++;
+ escape = 0;
+ }
+ }
- struct simple_pattern *m = parse_pattern(s, default_mode);
- m->negative = negative;
+ // terminate our string
+ *c = '\0';
- if(likely(n)) *c = ' ';
+ // if we matched the empty string, skip it
+ if(unlikely(!*buf))
+ continue;
- // link it at the end
- if(unlikely(!root))
- root = last = m;
- else {
- last->next = m;
- last = m;
- }
+ // fprintf(stderr, "FOUND PATTERN: '%s'\n", buf);
+ struct simple_pattern *m = parse_pattern(buf, default_mode);
+ m->negative = negative;
- // prepare for next loop
- s = n;
+ // link it at the end
+ if(unlikely(!root))
+ root = last = m;
+ else {
+ last->next = m;
+ last = m;
}
}
@@ -126,7 +137,28 @@ SIMPLE_PATTERN *simple_pattern_create(const char *list, SIMPLE_PREFIX_MODE defau
return (SIMPLE_PATTERN *)root;
}
-static inline int match_pattern(struct simple_pattern *m, const char *str, size_t len) {
+static inline char *add_wildcarded(const char *matched, size_t matched_size, char *wildcarded, size_t *wildcarded_size) {
+ //if(matched_size) {
+ // char buf[matched_size + 1];
+ // strncpyz(buf, matched, matched_size);
+ // fprintf(stderr, "ADD WILDCARDED '%s' of length %zu\n", buf, matched_size);
+ //}
+
+ if(unlikely(wildcarded && *wildcarded_size && matched && *matched && matched_size)) {
+ size_t wss = *wildcarded_size - 1;
+ size_t len = (matched_size < wss)?matched_size:wss;
+ if(likely(len)) {
+ strncpyz(wildcarded, matched, len);
+
+ *wildcarded_size -= len;
+ return &wildcarded[len];
+ }
+ }
+
+ return wildcarded;
+}
+
+static inline int match_pattern(struct simple_pattern *m, const char *str, size_t len, char *wildcarded, size_t *wildcarded_size) {
char *s;
if(m->len <= len) {
@@ -134,20 +166,28 @@ static inline int match_pattern(struct simple_pattern *m, const char *str, size_
case SIMPLE_PATTERN_SUBSTRING:
if(!m->len) return 1;
if((s = strstr(str, m->match))) {
- if(!m->child) return 1;
- return match_pattern(m->child, &s[m->len], len - (s - str) - m->len);
+ wildcarded = add_wildcarded(str, s - str, wildcarded, wildcarded_size);
+ if(!m->child) {
+ wildcarded = add_wildcarded(&s[m->len], len - (&s[m->len] - str), wildcarded, wildcarded_size);
+ return 1;
+ }
+ return match_pattern(m->child, &s[m->len], len - (s - str) - m->len, wildcarded, wildcarded_size);
}
break;
case SIMPLE_PATTERN_PREFIX:
if(unlikely(strncmp(str, m->match, m->len) == 0)) {
- if(!m->child) return 1;
- return match_pattern(m->child, &str[m->len], len - m->len);
+ if(!m->child) {
+ wildcarded = add_wildcarded(&str[m->len], len - m->len, wildcarded, wildcarded_size);
+ return 1;
+ }
+ return match_pattern(m->child, &str[m->len], len - m->len, wildcarded, wildcarded_size);
}
break;
case SIMPLE_PATTERN_SUFFIX:
if(unlikely(strcmp(&str[len - m->len], m->match) == 0)) {
+ wildcarded = add_wildcarded(str, len - m->len, wildcarded, wildcarded_size);
if(!m->child) return 1;
return 0;
}
@@ -166,17 +206,26 @@ static inline int match_pattern(struct simple_pattern *m, const char *str, size_
return 0;
}
-int simple_pattern_matches(SIMPLE_PATTERN *list, const char *str) {
+int simple_pattern_matches_extract(SIMPLE_PATTERN *list, const char *str, char *wildcarded, size_t wildcarded_size) {
struct simple_pattern *m, *root = (struct simple_pattern *)list;
if(unlikely(!root || !str || !*str)) return 0;
size_t len = strlen(str);
- for(m = root; m ; m = m->next)
- if(match_pattern(m, str, len)) {
- if(m->negative) return 0;
+ for(m = root; m ; m = m->next) {
+ char *ws = wildcarded;
+ size_t wss = wildcarded_size;
+ if(unlikely(ws)) *ws = '\0';
+
+ if (match_pattern(m, str, len, ws, &wss)) {
+
+ //if(ws && wss)
+ // fprintf(stderr, "FINAL WILDCARDED '%s' of length %zu\n", ws, strlen(ws));
+
+ if (m->negative) return 0;
return 1;
}
+ }
return 0;
}
diff --git a/src/simple_pattern.h b/src/simple_pattern.h
index 3768c508..60a25f49 100644
--- a/src/simple_pattern.h
+++ b/src/simple_pattern.h
@@ -15,8 +15,11 @@ typedef void SIMPLE_PATTERN;
// should be considered PREFIX matches.
extern SIMPLE_PATTERN *simple_pattern_create(const char *list, SIMPLE_PREFIX_MODE default_mode);
+// test if string str is matched from the pattern and fill 'wildcarded' with the parts matched by '*'
+extern int simple_pattern_matches_extract(SIMPLE_PATTERN *list, const char *str, char *wildcarded, size_t wildcarded_size);
+
// test if string str is matched from the pattern
-extern int simple_pattern_matches(SIMPLE_PATTERN *list, const char *str);
+#define simple_pattern_matches(list, str) simple_pattern_matches_extract(list, str, NULL, 0)
// free a simple_pattern that was created with simple_pattern_create()
// list can be NULL, in which case, this does nothing.
diff --git a/src/socket.c b/src/socket.c
index d28df81a..906ab33d 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -857,7 +857,7 @@ int accept4(int sock, struct sockaddr *addr, socklen_t *addrlen, int flags) {
// --------------------------------------------------------------------------------------------------------------------
// accept_socket() - accept a socket and store client IP and port
-int accept_socket(int fd, int flags, char *client_ip, size_t ipsize, char *client_port, size_t portsize) {
+int accept_socket(int fd, int flags, char *client_ip, size_t ipsize, char *client_port, size_t portsize, SIMPLE_PATTERN *access_list) {
struct sockaddr_storage sadr;
socklen_t addrlen = sizeof(sadr);
@@ -873,6 +873,13 @@ int accept_socket(int fd, int flags, char *client_ip, size_t ipsize, char *clien
client_port[portsize - 1] = '\0';
switch (((struct sockaddr *)&sadr)->sa_family) {
+ case AF_UNIX:
+ debug(D_LISTENER, "New UNIX domain web client from %s on socket %d.", client_ip, fd);
+ // set the port - certain versions of libc return garbage on unix sockets
+ strncpy(client_port, "UNIX", portsize);
+ client_port[portsize - 1] = '\0';
+ break;
+
case AF_INET:
debug(D_LISTENER, "New IPv4 web client from %s port %s on socket %d.", client_ip, client_port, fd);
break;
@@ -881,7 +888,8 @@ int accept_socket(int fd, int flags, char *client_ip, size_t ipsize, char *clien
if (strncmp(client_ip, "::ffff:", 7) == 0) {
memmove(client_ip, &client_ip[7], strlen(&client_ip[7]) + 1);
debug(D_LISTENER, "New IPv4 web client from %s port %s on socket %d.", client_ip, client_port, fd);
- } else
+ }
+ else
debug(D_LISTENER, "New IPv6 web client from %s port %s on socket %d.", client_ip, client_port, fd);
break;
@@ -889,6 +897,22 @@ int accept_socket(int fd, int flags, char *client_ip, size_t ipsize, char *clien
debug(D_LISTENER, "New UNKNOWN web client from %s port %s on socket %d.", client_ip, client_port, fd);
break;
}
+
+ if(access_list) {
+ if(!strcmp(client_ip, "127.0.0.1") || !strcmp(client_ip, "::1")) {
+ strncpy(client_ip, "localhost", ipsize);
+ client_ip[ipsize - 1] = '\0';
+ }
+
+ if(unlikely(!simple_pattern_matches(access_list, client_ip))) {
+ errno = 0;
+ debug(D_LISTENER, "Permission denied for client '%s', port '%s'", client_ip, client_port);
+ error("DENIED ACCESS to client '%s'", client_ip);
+ close(nfd);
+ nfd = -1;
+ errno = EPERM;
+ }
+ }
}
#ifdef HAVE_ACCEPT4
else if(errno == ENOSYS)
@@ -928,8 +952,8 @@ struct poll {
struct pollinfo *inf;
struct pollinfo *first_free;
- void *(*add_callback)(int fd, short int *events);
- void (*del_callback)(int fd, void *data);
+ void *(*add_callback)(int fd, int socktype, short int *events);
+ void (*del_callback)(int fd, int socktype, void *data);
int (*rcv_callback)(int fd, int socktype, void *data, short int *events);
int (*snd_callback)(int fd, int socktype, void *data, short int *events);
};
@@ -984,7 +1008,7 @@ static inline struct pollinfo *poll_add_fd(struct poll *p, int fd, int socktype,
p->max = pi->slot;
if(pi->flags & POLLINFO_FLAG_CLIENT_SOCKET) {
- pi->data = p->add_callback(fd, &pf->events);
+ pi->data = p->add_callback(fd, pi->socktype, &pf->events);
}
if(pi->flags & POLLINFO_FLAG_SERVER_SOCKET) {
@@ -1003,7 +1027,7 @@ static inline void poll_close_fd(struct poll *p, struct pollinfo *pi) {
if(unlikely(pf->fd == -1)) return;
if(pi->flags & POLLINFO_FLAG_CLIENT_SOCKET) {
- p->del_callback(pf->fd, pi->data);
+ p->del_callback(pf->fd, pi->socktype, pi->data);
}
close(pf->fd);
@@ -1036,14 +1060,16 @@ static inline void poll_close_fd(struct poll *p, struct pollinfo *pi) {
debug(D_POLLFD, "POLLFD: DEL: completed, slots = %zu, used = %zu, min = %zu, max = %zu, next free = %zd", p->slots, p->used, p->min, p->max, p->first_free?(ssize_t)p->first_free->slot:(ssize_t)-1);
}
-static void *add_callback_default(int fd, short int *events) {
+static void *add_callback_default(int fd, int socktype, short int *events) {
(void)fd;
+ (void)socktype;
(void)events;
return NULL;
}
-static void del_callback_default(int fd, void *data) {
+static void del_callback_default(int fd, int socktype, void *data) {
(void)fd;
+ (void)socktype;
(void)data;
if(data)
@@ -1100,10 +1126,11 @@ void poll_events_cleanup(void *data) {
}
void poll_events(LISTEN_SOCKETS *sockets
- , void *(*add_callback)(int fd, short int *events)
- , void (*del_callback)(int fd, void *data)
+ , void *(*add_callback)(int fd, int socktype, short int *events)
+ , void (*del_callback)(int fd, int socktype, void *data)
, int (*rcv_callback)(int fd, int socktype, void *data, short int *events)
, int (*snd_callback)(int fd, int socktype, void *data, short int *events)
+ , SIMPLE_PATTERN *access_list
, void *data
) {
int retval;
@@ -1182,7 +1209,7 @@ void poll_events(LISTEN_SOCKETS *sockets
char client_port[NI_MAXSERV + 1];
debug(D_POLLFD, "POLLFD: LISTENER: calling accept4() slot %zu (fd %d)", i, fd);
- nfd = accept_socket(fd, SOCK_NONBLOCK, client_ip, NI_MAXHOST + 1, client_port, NI_MAXSERV + 1);
+ nfd = accept_socket(fd, SOCK_NONBLOCK, client_ip, NI_MAXHOST + 1, client_port, NI_MAXSERV + 1, access_list);
if (nfd < 0) {
// accept failed
@@ -1212,6 +1239,8 @@ void poll_events(LISTEN_SOCKETS *sockets
debug(D_POLLFD, "POLLFD: LISTENER: reading data from UDP slot %zu (fd %d)", i, fd);
+ // FIXME: access_list is not applied to UDP
+
p.rcv_callback(fd, pi->socktype, pi->data, &pf->events);
break;
}
diff --git a/src/socket.h b/src/socket.h
index 8ca7288c..08b8518b 100644
--- a/src/socket.h
+++ b/src/socket.h
@@ -35,7 +35,7 @@ extern int sock_setreuse_port(int fd, int reuse);
extern int sock_enlarge_in(int fd);
extern int sock_enlarge_out(int fd);
-extern int accept_socket(int fd, int flags, char *client_ip, size_t ipsize, char *client_port, size_t portsize);
+extern int accept_socket(int fd, int flags, char *client_ip, size_t ipsize, char *client_port, size_t portsize, SIMPLE_PATTERN *access_list);
#ifndef HAVE_ACCEPT4
extern int accept4(int sock, struct sockaddr *addr, socklen_t *addrlen, int flags);
@@ -52,10 +52,11 @@ extern int accept4(int sock, struct sockaddr *addr, socklen_t *addrlen, int flag
extern void poll_events(LISTEN_SOCKETS *sockets
- , void *(*add_callback)(int fd, short int *events)
- , void (*del_callback)(int fd, void *data)
+ , void *(*add_callback)(int fd, int socktype, short int *events)
+ , void (*del_callback)(int fd, int socktype, void *data)
, int (*rcv_callback)(int fd, int socktype, void *data, short int *events)
, int (*snd_callback)(int fd, int socktype, void *data, short int *events)
+ , SIMPLE_PATTERN *access_list
, void *data
);
diff --git a/src/statsd.c b/src/statsd.c
index 08ce3e2f..39041ca8 100644
--- a/src/statsd.c
+++ b/src/statsd.c
@@ -54,6 +54,8 @@ typedef struct statsd_histogram_extensions {
collected_number last_stddev;
collected_number last_sum;
+ int zeroed;
+
RRDDIM *rd_min;
RRDDIM *rd_max;
RRDDIM *rd_percentile;
@@ -165,18 +167,21 @@ typedef enum statsd_app_chart_dimension_value_type {
} STATSD_APP_CHART_DIM_VALUE_TYPE;
typedef struct statsd_app_chart_dimension {
- const char *name;
- const char *metric;
- uint32_t metric_hash;
- collected_number multiplier;
- collected_number divisor;
- STATSD_APP_CHART_DIM_VALUE_TYPE value_type;
+ const char *name; // the name of this dimension
+ const char *metric; // the source metric name of this dimension
+ uint32_t metric_hash; // hash for fast string comparisons
+
+ SIMPLE_PATTERN *metric_pattern; // set when the 'metric' is a simple pattern
+
+ collected_number multiplier; // the multipler of the dimension
+ collected_number divisor; // the divisor of the dimension
+ STATSD_APP_CHART_DIM_VALUE_TYPE value_type; // which value to use of the source metric
- RRDDIM *rd;
- collected_number *value_ptr;
- RRD_ALGORITHM algorithm;
+ RRDDIM *rd; // a pointer to the RRDDIM that has been created for this dimension
+ collected_number *value_ptr; // a pointer to the source metric value
+ RRD_ALGORITHM algorithm; // the algorithm of this dimension
- struct statsd_app_chart_dimension *next;
+ struct statsd_app_chart_dimension *next; // the next dimension for this chart
} STATSD_APP_CHART_DIM;
typedef struct statsd_app_chart {
@@ -202,6 +207,7 @@ typedef struct statsd_app {
SIMPLE_PATTERN *metrics;
STATS_METRIC_OPTIONS default_options;
RRD_MEMORY_MODE rrd_memory_mode;
+ DICTIONARY *dict;
long rrd_history_entries;
const char *source;
@@ -482,7 +488,7 @@ static inline void statsd_process_histogram(STATSD_METRIC *m, const char *value,
static inline void statsd_process_timer(STATSD_METRIC *m, const char *value, const char *sampling) {
if(unlikely(!value || !*value)) {
- error("STATSD: metric of type set, with empty value is ignored.");
+ error("STATSD: metric of type timer, with empty value is ignored.");
return;
}
@@ -685,8 +691,9 @@ struct statsd_udp {
#endif
// new TCP client connected
-static void *statsd_add_callback(int fd, short int *events) {
+static void *statsd_add_callback(int fd, int socktype, short int *events) {
(void)fd;
+ (void)socktype;
*events = POLLIN;
struct statsd_tcp *data = (struct statsd_tcp *)callocz(sizeof(struct statsd_tcp) + STATSD_TCP_BUFFER_SIZE, 1);
@@ -697,8 +704,9 @@ static void *statsd_add_callback(int fd, short int *events) {
}
// TCP client disconnected
-static void statsd_del_callback(int fd, void *data) {
+static void statsd_del_callback(int fd, int socktype, void *data) {
(void)fd;
+ (void)socktype;
if(data) {
struct statsd_tcp *t = data;
@@ -912,6 +920,7 @@ void *statsd_collector_thread(void *ptr) {
, statsd_del_callback
, statsd_rcv_callback
, statsd_snd_callback
+ , NULL
, (void *)d
);
@@ -928,6 +937,83 @@ void *statsd_collector_thread(void *ptr) {
#define STATSD_CONF_LINE_MAX 8192
+static STATSD_APP_CHART_DIM_VALUE_TYPE string2valuetype(const char *type, size_t line, const char *path, const char *filename) {
+ if(!type || !*type) type = "last";
+
+ if(!strcmp(type, "events")) return STATSD_APP_CHART_DIM_VALUE_TYPE_EVENTS;
+ else if(!strcmp(type, "last")) return STATSD_APP_CHART_DIM_VALUE_TYPE_LAST;
+ else if(!strcmp(type, "min")) return STATSD_APP_CHART_DIM_VALUE_TYPE_MIN;
+ else if(!strcmp(type, "max")) return STATSD_APP_CHART_DIM_VALUE_TYPE_MAX;
+ else if(!strcmp(type, "sum")) return STATSD_APP_CHART_DIM_VALUE_TYPE_SUM;
+ else if(!strcmp(type, "average")) return STATSD_APP_CHART_DIM_VALUE_TYPE_AVERAGE;
+ else if(!strcmp(type, "median")) return STATSD_APP_CHART_DIM_VALUE_TYPE_MEDIAN;
+ else if(!strcmp(type, "stddev")) return STATSD_APP_CHART_DIM_VALUE_TYPE_STDDEV;
+ else if(!strcmp(type, "percentile")) return STATSD_APP_CHART_DIM_VALUE_TYPE_PERCENTILE;
+
+ error("STATSD: invalid type '%s' at line %zu of file '%s/%s'. Using 'last'.", type, line, path, filename);
+ return STATSD_APP_CHART_DIM_VALUE_TYPE_LAST;
+}
+
+static const char *valuetype2string(STATSD_APP_CHART_DIM_VALUE_TYPE type) {
+ switch(type) {
+ case STATSD_APP_CHART_DIM_VALUE_TYPE_EVENTS: return "events";
+ case STATSD_APP_CHART_DIM_VALUE_TYPE_LAST: return "last";
+ case STATSD_APP_CHART_DIM_VALUE_TYPE_MIN: return "min";
+ case STATSD_APP_CHART_DIM_VALUE_TYPE_MAX: return "max";
+ case STATSD_APP_CHART_DIM_VALUE_TYPE_SUM: return "sum";
+ case STATSD_APP_CHART_DIM_VALUE_TYPE_AVERAGE: return "average";
+ case STATSD_APP_CHART_DIM_VALUE_TYPE_MEDIAN: return "median";
+ case STATSD_APP_CHART_DIM_VALUE_TYPE_STDDEV: return "stddev";
+ case STATSD_APP_CHART_DIM_VALUE_TYPE_PERCENTILE: return "percentile";
+ }
+
+ return "unknown";
+}
+
+static STATSD_APP_CHART_DIM *add_dimension_to_app_chart(
+ STATSD_APP *app
+ , STATSD_APP_CHART *chart
+ , const char *metric_name
+ , const char *dim_name
+ , collected_number multiplier
+ , collected_number divisor
+ , STATSD_APP_CHART_DIM_VALUE_TYPE value_type
+) {
+ STATSD_APP_CHART_DIM *dim = callocz(sizeof(STATSD_APP_CHART_DIM), 1);
+
+ dim->metric = strdupz(metric_name);
+ dim->metric_hash = simple_hash(dim->metric);
+
+ dim->name = strdupz((dim_name)?dim_name:"");
+ dim->multiplier = multiplier;
+ dim->divisor = divisor;
+ dim->value_type = value_type;
+
+ if(!dim->multiplier)
+ dim->multiplier = 1;
+
+ if(!dim->divisor)
+ dim->divisor = 1;
+
+ // append it to the list of dimension
+ STATSD_APP_CHART_DIM *tdim;
+ for(tdim = chart->dimensions; tdim && tdim->next ; tdim = tdim->next) ;
+ if(!tdim) {
+ dim->next = chart->dimensions;
+ chart->dimensions = dim;
+ }
+ else {
+ dim->next = tdim->next;
+ tdim->next = dim;
+ }
+ chart->dimensions_count++;
+
+ debug(D_STATSD, "Added dimension '%s' to chart '%s' of app '%s', for metric '%s', with type %u, multiplier " COLLECTED_NUMBER_FORMAT ", divisor " COLLECTED_NUMBER_FORMAT,
+ dim->name, chart->id, app->name, dim->metric, dim->value_type, dim->multiplier, dim->divisor);
+
+ return dim;
+}
+
int statsd_readfile(const char *path, const char *filename) {
debug(D_STATSD, "STATSD configuration reading file '%s/%s'", path, filename);
@@ -943,6 +1029,7 @@ int statsd_readfile(const char *path, const char *filename) {
STATSD_APP *app = NULL;
STATSD_APP_CHART *chart = NULL;
+ DICTIONARY *dict = NULL;
size_t line = 0;
char *s;
@@ -973,22 +1060,33 @@ int statsd_readfile(const char *path, const char *filename) {
app->next = statsd.apps;
statsd.apps = app;
chart = NULL;
+ dict = NULL;
}
else if(app) {
- // a new chart
- chart = callocz(sizeof(STATSD_APP_CHART), 1);
- netdata_fix_chart_id(s);
- chart->id = strdupz(s);
- chart->name = strdupz(s);
- chart->title = strdupz("Statsd chart");
- chart->context = strdupz(s);
- chart->family = strdupz("overview");
- chart->units = strdupz("value");
- chart->priority = STATSD_CHART_PRIORITY;
- chart->chart_type = RRDSET_TYPE_LINE;
-
- chart->next = app->charts;
- app->charts = chart;
+ if(!strcmp(s, "dictionary")) {
+ if(!app->dict)
+ app->dict = dictionary_create(DICTIONARY_FLAG_SINGLE_THREADED);
+
+ dict = app->dict;
+ }
+ else {
+ dict = NULL;
+
+ // a new chart
+ chart = callocz(sizeof(STATSD_APP_CHART), 1);
+ netdata_fix_chart_id(s);
+ chart->id = strdupz(s);
+ chart->name = strdupz(s);
+ chart->title = strdupz("Statsd chart");
+ chart->context = strdupz(s);
+ chart->family = strdupz("overview");
+ chart->units = strdupz("value");
+ chart->priority = STATSD_CHART_PRIORITY;
+ chart->chart_type = RRDSET_TYPE_LINE;
+
+ chart->next = app->charts;
+ app->charts = chart;
+ }
}
else
error("STATSD: ignoring line %zu ('%s') of file '%s/%s', [app] is not defined.", line, s, path, filename);
@@ -1022,7 +1120,14 @@ int statsd_readfile(const char *path, const char *filename) {
continue;
}
- if(!chart) {
+ if(unlikely(dict)) {
+ // parse [dictionary] members
+
+ dictionary_set(dict, name, value, strlen(value) + 1);
+ }
+ else if(!chart) {
+ // parse [app] members
+
if(!strcmp(name, "name")) {
freez((void *)app->name);
netdata_fix_chart_name(value);
@@ -1056,6 +1161,8 @@ int statsd_readfile(const char *path, const char *filename) {
}
}
else {
+ // parse [chart] members
+
if(!strcmp(name, "name")) {
freez((void *)chart->name);
netdata_fix_chart_id(value);
@@ -1086,63 +1193,50 @@ int statsd_readfile(const char *path, const char *filename) {
}
else if (!strcmp(name, "dimension")) {
// metric [name [type [multiplier [divisor]]]]
- char *words[5];
- pluginsd_split_words(value, words, 5);
-
- char *metric_name = words[0];
- char *dim_name = words[1];
- char *type = words[2];
- char *multipler = words[3];
- char *divisor = words[4];
-
- STATSD_APP_CHART_DIM *dim = callocz(sizeof(STATSD_APP_CHART_DIM), 1);
-
- dim->metric = strdupz(metric_name);
- dim->metric_hash = simple_hash(dim->metric);
-
- dim->name = strdupz((dim_name && *dim_name)?dim_name:metric_name);
- dim->multiplier = (multipler && *multipler)?str2l(multipler):1;
- dim->divisor = (divisor && *divisor)?str2l(divisor):1;
-
- if(!type || !*type) type = "last";
- if(!strcmp(type, "events")) dim->value_type = STATSD_APP_CHART_DIM_VALUE_TYPE_EVENTS;
- else if(!strcmp(type, "last")) dim->value_type = STATSD_APP_CHART_DIM_VALUE_TYPE_LAST;
- else if(!strcmp(type, "min")) dim->value_type = STATSD_APP_CHART_DIM_VALUE_TYPE_MIN;
- else if(!strcmp(type, "max")) dim->value_type = STATSD_APP_CHART_DIM_VALUE_TYPE_MAX;
- else if(!strcmp(type, "sum")) dim->value_type = STATSD_APP_CHART_DIM_VALUE_TYPE_SUM;
- else if(!strcmp(type, "average")) dim->value_type = STATSD_APP_CHART_DIM_VALUE_TYPE_AVERAGE;
- else if(!strcmp(type, "median")) dim->value_type = STATSD_APP_CHART_DIM_VALUE_TYPE_MEDIAN;
- else if(!strcmp(type, "stddev")) dim->value_type = STATSD_APP_CHART_DIM_VALUE_TYPE_STDDEV;
- else if(!strcmp(type, "percentile")) dim->value_type = STATSD_APP_CHART_DIM_VALUE_TYPE_PERCENTILE;
- else {
- error("STATSD: invalid type '%s' at line %zu of file '%s/%s'. Using 'last'.", type, line, path, filename);
- dim->value_type = STATSD_APP_CHART_DIM_VALUE_TYPE_LAST;
- }
+ char *words[10];
+ pluginsd_split_words(value, words, 10);
- if(!dim->multiplier) {
- error("STATSD: invalid multiplier value '%s' at line %zu of file '%s/%s'. Using 1.", multipler, line, path, filename);
- dim->multiplier = 1;
- }
- if(!dim->divisor) {
- error("STATSD: invalid divisor value '%s' at line %zu of file '%s/%s'. Using 1.", divisor, line, path, filename);
- dim->divisor = 1;
- }
+ int pattern = 0;
+ size_t i = 0;
+ char *metric_name = words[i++];
- // append it to the list of dimension
- STATSD_APP_CHART_DIM *tdim;
- for(tdim = chart->dimensions; tdim && tdim->next ; tdim = tdim->next) ;
- if(!tdim) {
- dim->next = chart->dimensions;
- chart->dimensions = dim;
+ if(strcmp(metric_name, "pattern") == 0) {
+ metric_name = words[i++];
+ pattern = 1;
}
- else {
- dim->next = tdim->next;
- tdim->next = dim;
+
+ char *dim_name = words[i++];
+ char *type = words[i++];
+ char *multipler = words[i++];
+ char *divisor = words[i++];
+
+ if(!pattern) {
+ if(app->dict) {
+ if(dim_name && *dim_name) {
+ char *n = dictionary_get(app->dict, dim_name);
+ if(n) dim_name = n;
+ }
+ else {
+ dim_name = dictionary_get(app->dict, metric_name);
+ }
+ }
+
+ if(!dim_name || !*dim_name)
+ dim_name = metric_name;
}
- chart->dimensions_count++;
- debug(D_STATSD, "Added dimension '%s' to chart '%s' of app '%s', for metric '%s', with type %u, multiplier " COLLECTED_NUMBER_FORMAT ", divisor " COLLECTED_NUMBER_FORMAT,
- dim->name, chart->id, app->name, dim->metric, dim->value_type, dim->multiplier, dim->divisor);
+ STATSD_APP_CHART_DIM *dim = add_dimension_to_app_chart(
+ app
+ , chart
+ , metric_name
+ , dim_name
+ , (multipler && *multipler)?str2l(multipler):1
+ , (divisor && *divisor)?str2l(divisor):1
+ , string2valuetype(type, line, path, filename)
+ );
+
+ if(pattern)
+ dim->metric_pattern = simple_pattern_create(dim->metric, SIMPLE_PATTERN_EXACT);
}
else {
error("STATSD: ignoring line %zu ('%s') of file '%s/%s'. Unknown keyword for the [%s] section.", line, name, path, filename, chart->id);
@@ -1248,19 +1342,21 @@ static inline RRDSET *statsd_private_rrdset_create(
statsd.private_charts++;
RRDSET *st = rrdset_create_custom(
- localhost
- , type
- , id
- , name
- , family
- , context
- , title
- , units
- , priority
- , update_every
- , chart_type
- , memory_mode
- , history
+ localhost // host
+ , type // type
+ , id // id
+ , name // name
+ , family // family
+ , context // context
+ , title // title
+ , units // units
+ , "statsd" // plugin
+ , NULL // module
+ , priority // priority
+ , update_every // update every
+ , chart_type // chart type
+ , memory_mode // memory mode
+ , history // history
);
rrdset_flag_set(st, RRDSET_FLAG_STORE_FIRST);
// rrdset_flag_set(st, RRDSET_FLAG_DEBUG);
@@ -1484,6 +1580,22 @@ static inline void statsd_flush_timer_or_histogram(STATSD_METRIC *m, const char
netdata_mutex_lock(&m->histogram.ext->mutex);
+ if(unlikely(!m->histogram.ext->zeroed)) {
+ // reset the metrics
+ // if we collected anything, they will be updated below
+ // this ensures that we report zeros if nothing is collected
+
+ m->histogram.ext->last_min = 0;
+ m->histogram.ext->last_max = 0;
+ m->last = 0;
+ m->histogram.ext->last_median = 0;
+ m->histogram.ext->last_stddev = 0;
+ m->histogram.ext->last_sum = 0;
+ m->histogram.ext->last_percentile = 0;
+
+ m->histogram.ext->zeroed = 1;
+ }
+
int updated = 0;
if(m->count && !m->reset && m->histogram.ext->used > 0) {
size_t len = m->histogram.ext->used;
@@ -1506,11 +1618,11 @@ static inline void statsd_flush_timer_or_histogram(STATSD_METRIC *m, const char
debug(D_STATSD, "STATSD %s metric %s: min " COLLECTED_NUMBER_FORMAT ", max " COLLECTED_NUMBER_FORMAT ", last " COLLECTED_NUMBER_FORMAT ", pcent " COLLECTED_NUMBER_FORMAT ", median " COLLECTED_NUMBER_FORMAT ", stddev " COLLECTED_NUMBER_FORMAT ", sum " COLLECTED_NUMBER_FORMAT,
dim, m->name, m->histogram.ext->last_min, m->histogram.ext->last_max, m->last, m->histogram.ext->last_percentile, m->histogram.ext->last_median, m->histogram.ext->last_stddev, m->histogram.ext->last_sum);
+ m->histogram.ext->zeroed = 0;
m->reset = 1;
updated = 1;
}
-
if(m->options & STATSD_METRIC_OPTION_PRIVATE_CHART_ENABLED && (updated || !(m->options & STATSD_METRIC_OPTION_SHOW_GAPS_WHEN_NOT_COLLECTED)))
statsd_private_chart_timer_or_histogram(m, dim, family, units);
@@ -1540,6 +1652,71 @@ static inline RRD_ALGORITHM statsd_algorithm_for_metric(STATSD_METRIC *m) {
}
}
+static inline void link_metric_to_app_dimension(STATSD_APP *app, STATSD_METRIC *m, STATSD_APP_CHART *chart, STATSD_APP_CHART_DIM *dim) {
+ if(dim->value_type == STATSD_APP_CHART_DIM_VALUE_TYPE_EVENTS) {
+ dim->value_ptr = &m->events;
+ dim->algorithm = RRD_ALGORITHM_INCREMENTAL;
+ }
+ else if(m->type == STATSD_METRIC_TYPE_HISTOGRAM || m->type == STATSD_METRIC_TYPE_TIMER) {
+ dim->algorithm = RRD_ALGORITHM_ABSOLUTE;
+ dim->divisor *= statsd.decimal_detail;
+
+ switch(dim->value_type) {
+ case STATSD_APP_CHART_DIM_VALUE_TYPE_EVENTS:
+ // will never match - added to avoid warning
+ break;
+
+ case STATSD_APP_CHART_DIM_VALUE_TYPE_LAST:
+ case STATSD_APP_CHART_DIM_VALUE_TYPE_AVERAGE:
+ dim->value_ptr = &m->last;
+ break;
+
+ case STATSD_APP_CHART_DIM_VALUE_TYPE_SUM:
+ dim->value_ptr = &m->histogram.ext->last_sum;
+ break;
+
+ case STATSD_APP_CHART_DIM_VALUE_TYPE_MIN:
+ dim->value_ptr = &m->histogram.ext->last_min;
+ break;
+
+ case STATSD_APP_CHART_DIM_VALUE_TYPE_MAX:
+ dim->value_ptr = &m->histogram.ext->last_max;
+ break;
+
+ case STATSD_APP_CHART_DIM_VALUE_TYPE_MEDIAN:
+ dim->value_ptr = &m->histogram.ext->last_median;
+ break;
+
+ case STATSD_APP_CHART_DIM_VALUE_TYPE_PERCENTILE:
+ dim->value_ptr = &m->histogram.ext->last_percentile;
+ break;
+
+ case STATSD_APP_CHART_DIM_VALUE_TYPE_STDDEV:
+ dim->value_ptr = &m->histogram.ext->last_stddev;
+ break;
+ }
+ }
+ else {
+ if (dim->value_type != STATSD_APP_CHART_DIM_VALUE_TYPE_LAST)
+ error("STATSD: unsupported value type for dimension '%s' of chart '%s' of app '%s' on metric '%s'", dim->name, chart->id, app->name, m->name);
+
+ dim->value_ptr = &m->last;
+ dim->algorithm = statsd_algorithm_for_metric(m);
+
+ if(m->type == STATSD_METRIC_TYPE_GAUGE)
+ dim->divisor *= statsd.decimal_detail;
+ }
+
+ if(unlikely(chart->st && dim->rd)) {
+ rrddim_set_algorithm(chart->st, dim->rd, dim->algorithm);
+ rrddim_set_multiplier(chart->st, dim->rd, dim->multiplier);
+ rrddim_set_divisor(chart->st, dim->rd, dim->divisor);
+ }
+
+ chart->dimensions_linked_count++;
+ debug(D_STATSD, "metric '%s' of type %u linked with app '%s', chart '%s', dimension '%s', algorithm '%s'", m->name, m->type, app->name, chart->id, dim->name, rrd_algorithm_name(dim->algorithm));
+}
+
static inline void check_if_metric_is_for_app(STATSD_INDEX *index, STATSD_METRIC *m) {
(void)index;
@@ -1565,78 +1742,103 @@ static inline void check_if_metric_is_for_app(STATSD_INDEX *index, STATSD_METRIC
// check if there is a chart in this app, willing to get this metric
STATSD_APP_CHART *chart;
for(chart = app->charts; chart; chart = chart->next) {
+
STATSD_APP_CHART_DIM *dim;
for(dim = chart->dimensions; dim ; dim = dim->next) {
- if(!dim->value_ptr && dim->metric_hash == m->hash && !strcmp(dim->metric, m->name)) {
- // we have a match - this metric should be linked to this dimension
+ if(unlikely(dim->metric_pattern)) {
+ size_t dim_name_len = strlen(dim->name);
+ size_t wildcarded_len = dim_name_len + strlen(m->name) + 1;
+ char wildcarded[wildcarded_len];
- if(dim->value_type == STATSD_APP_CHART_DIM_VALUE_TYPE_EVENTS) {
- dim->value_ptr = &m->events;
- dim->algorithm = RRD_ALGORITHM_INCREMENTAL;
- }
- else if(m->type == STATSD_METRIC_TYPE_HISTOGRAM || m->type == STATSD_METRIC_TYPE_TIMER) {
- dim->algorithm = RRD_ALGORITHM_ABSOLUTE;
- dim->divisor *= statsd.decimal_detail;
-
- switch(dim->value_type) {
- case STATSD_APP_CHART_DIM_VALUE_TYPE_EVENTS:
- // will never match - added to avoid warning
- break;
-
- case STATSD_APP_CHART_DIM_VALUE_TYPE_LAST:
- case STATSD_APP_CHART_DIM_VALUE_TYPE_AVERAGE:
- dim->value_ptr = &m->last;
- break;
-
- case STATSD_APP_CHART_DIM_VALUE_TYPE_SUM:
- dim->value_ptr = &m->histogram.ext->last_sum;
- break;
-
- case STATSD_APP_CHART_DIM_VALUE_TYPE_MIN:
- dim->value_ptr = &m->histogram.ext->last_min;
- break;
-
- case STATSD_APP_CHART_DIM_VALUE_TYPE_MAX:
- dim->value_ptr = &m->histogram.ext->last_max;
- break;
-
- case STATSD_APP_CHART_DIM_VALUE_TYPE_MEDIAN:
- dim->value_ptr = &m->histogram.ext->last_median;
- break;
-
- case STATSD_APP_CHART_DIM_VALUE_TYPE_PERCENTILE:
- dim->value_ptr = &m->histogram.ext->last_percentile;
- break;
-
- case STATSD_APP_CHART_DIM_VALUE_TYPE_STDDEV:
- dim->value_ptr = &m->histogram.ext->last_stddev;
- break;
- }
- }
- else {
- if (dim->value_type != STATSD_APP_CHART_DIM_VALUE_TYPE_LAST)
- error("STATSD: unsupported value type for dimension '%s' of chart '%s' of app '%s' on metric '%s'", dim->name, chart->id, app->name, m->name);
+ strcpy(wildcarded, dim->name);
+ char *ws = &wildcarded[dim_name_len];
- dim->value_ptr = &m->last;
- dim->algorithm = statsd_algorithm_for_metric(m);
+ if(simple_pattern_matches_extract(dim->metric_pattern, m->name, ws, wildcarded_len - dim_name_len)) {
- if(m->type == STATSD_METRIC_TYPE_GAUGE)
- dim->divisor *= statsd.decimal_detail;
- }
+ char *final_name = NULL;
- if(unlikely(chart->st && dim->rd)) {
- rrddim_set_algorithm(chart->st, dim->rd, dim->algorithm);
- rrddim_set_multiplier(chart->st, dim->rd, dim->multiplier);
- rrddim_set_divisor(chart->st, dim->rd, dim->divisor);
- }
+ if(app->dict) {
+ if(likely(*wildcarded)) {
+ // use the name of the wildcarded string
+ final_name = dictionary_get(app->dict, wildcarded);
+ }
+
+ if(unlikely(!final_name)) {
+ // use the name of the metric
+ final_name = dictionary_get(app->dict, m->name);
+ }
+ }
- chart->dimensions_linked_count++;
- debug(D_STATSD, "metric '%s' of type %u linked with app '%s', chart '%s', dimension '%s', algorithm '%s'", m->name, m->type, app->name, chart->id, dim->name, rrd_algorithm_name(dim->algorithm));
+ if(unlikely(!final_name))
+ final_name = wildcarded;
+
+ add_dimension_to_app_chart(
+ app
+ , chart
+ , m->name
+ , final_name
+ , dim->multiplier
+ , dim->divisor
+ , dim->value_type
+ );
+
+ // the new dimension is appended to the list
+ // so, it will be matched and linked later too
+ }
+ }
+ else if(!dim->value_ptr && dim->metric_hash == m->hash && !strcmp(dim->metric, m->name)) {
+ // we have a match - this metric should be linked to this dimension
+ link_metric_to_app_dimension(app, m, chart, dim);
}
}
+
+ }
+ }
+ }
+}
+
+static inline RRDDIM *statsd_add_dim_to_app_chart(STATSD_APP *app, STATSD_APP_CHART *chart, STATSD_APP_CHART_DIM *dim) {
+ (void)app;
+
+ // allow the same statsd metric to be added multiple times to the same chart
+
+ STATSD_APP_CHART_DIM *tdim;
+ size_t count_same_metric = 0, count_same_metric_value_type = 0;
+ size_t pos_same_metric_value_type = 0;
+
+ for (tdim = chart->dimensions; tdim && tdim->next; tdim = tdim->next) {
+ if (dim->metric_hash == tdim->metric_hash && !strcmp(dim->metric, tdim->metric)) {
+ count_same_metric++;
+
+ if(dim->value_type == tdim->value_type) {
+ count_same_metric_value_type++;
+ if (tdim == dim)
+ pos_same_metric_value_type = count_same_metric_value_type;
}
}
}
+
+ if(count_same_metric > 1) {
+ // the same metric is found multiple times
+
+ size_t len = strlen(dim->metric) + 100;
+ char metric[ len + 1 ];
+
+ if(count_same_metric_value_type > 1) {
+ // the same metric, with the same value type, is added multiple times
+ snprintfz(metric, len, "%s_%s%zu", dim->metric, valuetype2string(dim->value_type), pos_same_metric_value_type);
+ }
+ else {
+ // the same metric, with different value type is added
+ snprintfz(metric, len, "%s_%s", dim->metric, valuetype2string(dim->value_type));
+ }
+
+ dim->rd = rrddim_add(chart->st, metric, dim->name, dim->multiplier, dim->divisor, dim->algorithm);
+ return dim->rd;
+ }
+
+ dim->rd = rrddim_add(chart->st, dim->metric, dim->name, dim->multiplier, dim->divisor, dim->algorithm);
+ return dim->rd;
}
static inline void statsd_update_app_chart(STATSD_APP *app, STATSD_APP_CHART *chart) {
@@ -1644,19 +1846,21 @@ static inline void statsd_update_app_chart(STATSD_APP *app, STATSD_APP_CHART *ch
if(!chart->st) {
chart->st = rrdset_create_custom(
- localhost
- , app->name
- , chart->id
- , chart->name
- , chart->family
- , chart->context
- , chart->title
- , chart->units
- , chart->priority
- , statsd.update_every
- , chart->chart_type
- , app->rrd_memory_mode
- , app->rrd_history_entries
+ localhost // host
+ , app->name // type
+ , chart->id // id
+ , chart->name // name
+ , chart->family // family
+ , chart->context // context
+ , chart->title // title
+ , chart->units // units
+ , "statsd" // plugin
+ , NULL // module
+ , chart->priority // priority
+ , statsd.update_every // update every
+ , chart->chart_type // chart type
+ , app->rrd_memory_mode // memory mode
+ , app->rrd_history_entries // history
);
rrdset_flag_set(chart->st, RRDSET_FLAG_STORE_FIRST);
@@ -1666,12 +1870,14 @@ static inline void statsd_update_app_chart(STATSD_APP *app, STATSD_APP_CHART *ch
STATSD_APP_CHART_DIM *dim;
for(dim = chart->dimensions; dim ;dim = dim->next) {
- if(unlikely(!dim->rd))
- dim->rd = rrddim_add(chart->st, dim->name, NULL, dim->multiplier, dim->divisor, dim->algorithm);
+ if(likely(!dim->metric_pattern)) {
+ if (unlikely(!dim->rd))
+ statsd_add_dim_to_app_chart(app, chart, dim);
- if(unlikely(dim->value_ptr)) {
- debug(D_STATSD, "updating dimension '%s' (%s) of chart '%s' (%s) for app '%s' with value " COLLECTED_NUMBER_FORMAT, dim->name, dim->rd->id, chart->id, chart->st->id, app->name, *dim->value_ptr);
- rrddim_set_by_pointer(chart->st, dim->rd, *dim->value_ptr);
+ if (unlikely(dim->value_ptr)) {
+ debug(D_STATSD, "updating dimension '%s' (%s) of chart '%s' (%s) for app '%s' with value " COLLECTED_NUMBER_FORMAT, dim->name, dim->rd->id, chart->id, chart->st->id, app->name, *dim->value_ptr);
+ rrddim_set_by_pointer(chart->st, dim->rd, *dim->value_ptr);
+ }
}
}
@@ -1871,6 +2077,8 @@ void *statsd_main(void *ptr) {
, NULL
, "Metrics in the netdata statsd database"
, "metrics"
+ , "netdata"
+ , "stats"
, 132000
, statsd.update_every
, RRDSET_TYPE_STACKED
@@ -1890,6 +2098,8 @@ void *statsd_main(void *ptr) {
, NULL
, "Events processed by the netdata statsd server"
, "events/s"
+ , "netdata"
+ , "stats"
, 132001
, statsd.update_every
, RRDSET_TYPE_STACKED
@@ -1911,6 +2121,8 @@ void *statsd_main(void *ptr) {
, NULL
, "Read operations made by the netdata statsd server"
, "reads/s"
+ , "netdata"
+ , "stats"
, 132002
, statsd.update_every
, RRDSET_TYPE_STACKED
@@ -1926,6 +2138,8 @@ void *statsd_main(void *ptr) {
, NULL
, "Bytes read by the netdata statsd server"
, "kilobits/s"
+ , "netdata"
+ , "stats"
, 132003
, statsd.update_every
, RRDSET_TYPE_STACKED
@@ -1941,6 +2155,8 @@ void *statsd_main(void *ptr) {
, NULL
, "Network packets processed by the netdata statsd server"
, "packets/s"
+ , "netdata"
+ , "stats"
, 132004
, statsd.update_every
, RRDSET_TYPE_STACKED
@@ -1956,6 +2172,8 @@ void *statsd_main(void *ptr) {
, NULL
, "Private metric charts created by the netdata statsd server"
, "charts"
+ , "netdata"
+ , "stats"
, 132010
, statsd.update_every
, RRDSET_TYPE_AREA
diff --git a/src/storage_number.c b/src/storage_number.c
index 05494120..3fd22a41 100644
--- a/src/storage_number.c
+++ b/src/storage_number.c
@@ -39,7 +39,9 @@ storage_number pack_storage_number(calculated_number value, uint32_t flags)
r += (1 << 30) + (m << 27); // the multiplier m
if(n > (calculated_number)0x00ffffff) {
+ #ifdef NETDATA_INTERNAL_CHECKS
error("Number " CALCULATED_NUMBER_FORMAT " is too big.", value);
+ #endif
r += 0x00ffffff;
return r;
}
diff --git a/src/storage_number.h b/src/storage_number.h
index 3c1b6bab..616ff881 100644
--- a/src/storage_number.h
+++ b/src/storage_number.h
@@ -17,6 +17,9 @@ typedef long double collected_number;
#define calculated_number_llrint(x) llrintl(x)
#define calculated_number_round(x) roundl(x)
#define calculated_number_fabs(x) fabsl(x)
+#define calculated_number_epsilon (calculated_number)0.0000001
+
+#define calculated_number_equal(a, b) (calculated_number_fabs((a) - (b)) < calculated_number_epsilon)
typedef uint32_t storage_number;
#define STORAGE_NUMBER_FORMAT "%u"
diff --git a/src/sys_devices_system_edac_mc.c b/src/sys_devices_system_edac_mc.c
index 7ec98943..9eac8a12 100644
--- a/src/sys_devices_system_edac_mc.c
+++ b/src/sys_devices_system_edac_mc.c
@@ -140,6 +140,8 @@ int do_proc_sys_devices_system_edac_mc(int update_every, usec_t dt) {
, NULL
, "ECC Memory Correctable Errors"
, "errors"
+ , "proc"
+ , "/sys/devices/system/edac/mc"
, 6600
, update_every
, RRDSET_TYPE_LINE
@@ -176,6 +178,8 @@ int do_proc_sys_devices_system_edac_mc(int update_every, usec_t dt) {
, NULL
, "ECC Memory Uncorrectable Errors"
, "errors"
+ , "proc"
+ , "/sys/devices/system/edac/mc"
, 6610
, update_every
, RRDSET_TYPE_LINE
diff --git a/src/sys_devices_system_node.c b/src/sys_devices_system_node.c
index a7690e7b..86d55b29 100644
--- a/src/sys_devices_system_node.c
+++ b/src/sys_devices_system_node.c
@@ -105,6 +105,8 @@ int do_proc_sys_devices_system_node(int update_every, usec_t dt) {
, NULL
, "NUMA events"
, "events/s"
+ , "proc"
+ , "/sys/devices/system/node"
, 1000
, update_every
, RRDSET_TYPE_LINE
diff --git a/src/sys_fs_cgroup.c b/src/sys_fs_cgroup.c
index c047547e..946831af 100644
--- a/src/sys_fs_cgroup.c
+++ b/src/sys_fs_cgroup.c
@@ -151,7 +151,8 @@ void read_cgroup_plugin_configuration() {
// ----------------------------------------------------------------
" !*/init.scope " // ignore init.scope
- " *.scope " // we need all *.scope for sure
+ " !/system.slice/run-*.scope " // ignore system.slice/run-XXXX.scope
+ " *.scope " // we need all other *.scope for sure
// ----------------------------------------------------------------
@@ -180,6 +181,7 @@ void read_cgroup_plugin_configuration() {
config_get("plugin:cgroups", "search for cgroups in subpaths matching",
" !*/init.scope " // ignore init.scope
" !*-qemu " // #345
+ " !*.libvirt-qemu " // #3010
" !/init.scope "
" !/system "
" !/systemd "
@@ -201,6 +203,9 @@ void read_cgroup_plugin_configuration() {
" *docker* "
" *lxc* "
" *qemu* "
+ " *.libvirt-qemu " // #3010
+ " !*/vcpu* " // libvirtd adds these sub-cgroups
+ " !*/emulator* " // libvirtd adds these sub-cgroups
" !/ "
" !*.mount "
" !*.partition "
@@ -762,7 +767,7 @@ static inline void read_cgroup_network_interfaces(struct cgroup *cg) {
}
if(!*t) {
- error("CGROUP: empty container interface returned by script");
+ error("CGROUP: empty guest interface returned by script");
continue;
}
@@ -1447,6 +1452,8 @@ void update_systemd_services_charts(
, "services.cpu"
, title
, "%"
+ , "cgroup"
+ , "systemd"
, CHART_PRIORITY_SYSTEMD_SERVICES
, update_every
, RRDSET_TYPE_STACKED
@@ -1469,6 +1476,8 @@ void update_systemd_services_charts(
, (cgroup_used_memory_without_cache) ? "Systemd Services Used Memory without Cache"
: "Systemd Services Used Memory"
, "MB"
+ , "cgroup"
+ , "systemd"
, CHART_PRIORITY_SYSTEMD_SERVICES + 10
, update_every
, RRDSET_TYPE_STACKED
@@ -1490,6 +1499,8 @@ void update_systemd_services_charts(
, "services.mem_rss"
, "Systemd Services RSS Memory"
, "MB"
+ , "cgroup"
+ , "systemd"
, CHART_PRIORITY_SYSTEMD_SERVICES + 20
, update_every
, RRDSET_TYPE_STACKED
@@ -1509,6 +1520,8 @@ void update_systemd_services_charts(
, "services.mem_mapped"
, "Systemd Services Mapped Memory"
, "MB"
+ , "cgroup"
+ , "systemd"
, CHART_PRIORITY_SYSTEMD_SERVICES + 30
, update_every
, RRDSET_TYPE_STACKED
@@ -1528,6 +1541,8 @@ void update_systemd_services_charts(
, "services.mem_cache"
, "Systemd Services Cache Memory"
, "MB"
+ , "cgroup"
+ , "systemd"
, CHART_PRIORITY_SYSTEMD_SERVICES + 40
, update_every
, RRDSET_TYPE_STACKED
@@ -1547,6 +1562,8 @@ void update_systemd_services_charts(
, "services.mem_writeback"
, "Systemd Services Writeback Memory"
, "MB"
+ , "cgroup"
+ , "systemd"
, CHART_PRIORITY_SYSTEMD_SERVICES + 50
, update_every
, RRDSET_TYPE_STACKED
@@ -1566,6 +1583,8 @@ void update_systemd_services_charts(
, "services.mem_pgfault"
, "Systemd Services Memory Minor Page Faults"
, "MB/s"
+ , "cgroup"
+ , "systemd"
, CHART_PRIORITY_SYSTEMD_SERVICES + 60
, update_every
, RRDSET_TYPE_STACKED
@@ -1584,6 +1603,8 @@ void update_systemd_services_charts(
, "services.mem_pgmajfault"
, "Systemd Services Memory Major Page Faults"
, "MB/s"
+ , "cgroup"
+ , "systemd"
, CHART_PRIORITY_SYSTEMD_SERVICES + 70
, update_every
, RRDSET_TYPE_STACKED
@@ -1603,6 +1624,8 @@ void update_systemd_services_charts(
, "services.mem_pgpgin"
, "Systemd Services Memory Charging Activity"
, "MB/s"
+ , "cgroup"
+ , "systemd"
, CHART_PRIORITY_SYSTEMD_SERVICES + 80
, update_every
, RRDSET_TYPE_STACKED
@@ -1622,6 +1645,8 @@ void update_systemd_services_charts(
, "services.mem_pgpgout"
, "Systemd Services Memory Uncharging Activity"
, "MB/s"
+ , "cgroup"
+ , "systemd"
, CHART_PRIORITY_SYSTEMD_SERVICES + 90
, update_every
, RRDSET_TYPE_STACKED
@@ -1643,6 +1668,8 @@ void update_systemd_services_charts(
, "services.mem_failcnt"
, "Systemd Services Memory Limit Failures"
, "MB"
+ , "cgroup"
+ , "systemd"
, CHART_PRIORITY_SYSTEMD_SERVICES + 110
, update_every
, RRDSET_TYPE_STACKED
@@ -1664,6 +1691,8 @@ void update_systemd_services_charts(
, "services.swap_usage"
, "Systemd Services Swap Memory Used"
, "MB"
+ , "cgroup"
+ , "systemd"
, CHART_PRIORITY_SYSTEMD_SERVICES + 100
, update_every
, RRDSET_TYPE_STACKED
@@ -1685,6 +1714,8 @@ void update_systemd_services_charts(
, "services.io_read"
, "Systemd Services Disk Read Bandwidth"
, "KB/s"
+ , "cgroup"
+ , "systemd"
, CHART_PRIORITY_SYSTEMD_SERVICES + 120
, update_every
, RRDSET_TYPE_STACKED
@@ -1704,6 +1735,8 @@ void update_systemd_services_charts(
, "services.io_write"
, "Systemd Services Disk Write Bandwidth"
, "KB/s"
+ , "cgroup"
+ , "systemd"
, CHART_PRIORITY_SYSTEMD_SERVICES + 130
, update_every
, RRDSET_TYPE_STACKED
@@ -1725,6 +1758,8 @@ void update_systemd_services_charts(
, "services.io_ops_read"
, "Systemd Services Disk Read Operations"
, "operations/s"
+ , "cgroup"
+ , "systemd"
, CHART_PRIORITY_SYSTEMD_SERVICES + 140
, update_every
, RRDSET_TYPE_STACKED
@@ -1744,6 +1779,8 @@ void update_systemd_services_charts(
, "services.io_ops_write"
, "Systemd Services Disk Write Operations"
, "operations/s"
+ , "cgroup"
+ , "systemd"
, CHART_PRIORITY_SYSTEMD_SERVICES + 150
, update_every
, RRDSET_TYPE_STACKED
@@ -1765,6 +1802,8 @@ void update_systemd_services_charts(
, "services.throttle_io_read"
, "Systemd Services Throttle Disk Read Bandwidth"
, "KB/s"
+ , "cgroup"
+ , "systemd"
, CHART_PRIORITY_SYSTEMD_SERVICES + 160
, update_every
, RRDSET_TYPE_STACKED
@@ -1784,6 +1823,8 @@ void update_systemd_services_charts(
, "services.throttle_io_write"
, "Systemd Services Throttle Disk Write Bandwidth"
, "KB/s"
+ , "cgroup"
+ , "systemd"
, CHART_PRIORITY_SYSTEMD_SERVICES + 170
, update_every
, RRDSET_TYPE_STACKED
@@ -1805,6 +1846,8 @@ void update_systemd_services_charts(
, "services.throttle_io_ops_read"
, "Systemd Services Throttle Disk Read Operations"
, "operations/s"
+ , "cgroup"
+ , "systemd"
, CHART_PRIORITY_SYSTEMD_SERVICES + 180
, update_every
, RRDSET_TYPE_STACKED
@@ -1824,6 +1867,8 @@ void update_systemd_services_charts(
, "services.throttle_io_ops_write"
, "Systemd Services Throttle Disk Write Operations"
, "operations/s"
+ , "cgroup"
+ , "systemd"
, CHART_PRIORITY_SYSTEMD_SERVICES + 190
, update_every
, RRDSET_TYPE_STACKED
@@ -1845,6 +1890,8 @@ void update_systemd_services_charts(
, "services.queued_io_ops_read"
, "Systemd Services Queued Disk Read Operations"
, "operations/s"
+ , "cgroup"
+ , "systemd"
, CHART_PRIORITY_SYSTEMD_SERVICES + 200
, update_every
, RRDSET_TYPE_STACKED
@@ -1864,6 +1911,8 @@ void update_systemd_services_charts(
, "services.queued_io_ops_write"
, "Systemd Services Queued Disk Write Operations"
, "operations/s"
+ , "cgroup"
+ , "systemd"
, CHART_PRIORITY_SYSTEMD_SERVICES + 210
, update_every
, RRDSET_TYPE_STACKED
@@ -1885,6 +1934,8 @@ void update_systemd_services_charts(
, "services.merged_io_ops_read"
, "Systemd Services Merged Disk Read Operations"
, "operations/s"
+ , "cgroup"
+ , "systemd"
, CHART_PRIORITY_SYSTEMD_SERVICES + 220
, update_every
, RRDSET_TYPE_STACKED
@@ -1904,6 +1955,8 @@ void update_systemd_services_charts(
, "services.merged_io_ops_write"
, "Systemd Services Merged Disk Write Operations"
, "operations/s"
+ , "cgroup"
+ , "systemd"
, CHART_PRIORITY_SYSTEMD_SERVICES + 230
, update_every
, RRDSET_TYPE_STACKED
@@ -2184,6 +2237,8 @@ void update_cgroup_charts(int update_every) {
, "cgroup.cpu"
, title
, "%"
+ , "cgroup"
+ , "default"
, CHART_PRIORITY_CONTAINERS
, update_every
, RRDSET_TYPE_STACKED
@@ -2215,6 +2270,8 @@ void update_cgroup_charts(int update_every) {
, "cgroup.cpu_per_core"
, title
, "%"
+ , "cgroup"
+ , "default"
, CHART_PRIORITY_CONTAINERS + 100
, update_every
, RRDSET_TYPE_STACKED
@@ -2247,6 +2304,8 @@ void update_cgroup_charts(int update_every) {
, "cgroup.mem"
, title
, "MB"
+ , "cgroup"
+ , "default"
, CHART_PRIORITY_CONTAINERS + 210
, update_every
, RRDSET_TYPE_STACKED
@@ -2285,6 +2344,8 @@ void update_cgroup_charts(int update_every) {
, "cgroup.writeback"
, title
, "MB"
+ , "cgroup"
+ , "default"
, CHART_PRIORITY_CONTAINERS + 300
, update_every
, RRDSET_TYPE_AREA
@@ -2315,6 +2376,8 @@ void update_cgroup_charts(int update_every) {
, "cgroup.mem_activity"
, title
, "MB/s"
+ , "cgroup"
+ , "default"
, CHART_PRIORITY_CONTAINERS + 400
, update_every
, RRDSET_TYPE_LINE
@@ -2341,6 +2404,8 @@ void update_cgroup_charts(int update_every) {
, "cgroup.pgfaults"
, title
, "MB/s"
+ , "cgroup"
+ , "default"
, CHART_PRIORITY_CONTAINERS + 500
, update_every
, RRDSET_TYPE_LINE
@@ -2369,6 +2434,8 @@ void update_cgroup_charts(int update_every) {
, "cgroup.mem_usage"
, title
, "MB"
+ , "cgroup"
+ , "default"
, CHART_PRIORITY_CONTAINERS + 200
, update_every
, RRDSET_TYPE_STACKED
@@ -2397,6 +2464,8 @@ void update_cgroup_charts(int update_every) {
, "cgroup.mem_failcnt"
, title
, "count"
+ , "cgroup"
+ , "default"
, CHART_PRIORITY_CONTAINERS + 250
, update_every
, RRDSET_TYPE_LINE
@@ -2423,6 +2492,8 @@ void update_cgroup_charts(int update_every) {
, "cgroup.io"
, title
, "KB/s"
+ , "cgroup"
+ , "default"
, CHART_PRIORITY_CONTAINERS + 1200
, update_every
, RRDSET_TYPE_AREA
@@ -2451,6 +2522,8 @@ void update_cgroup_charts(int update_every) {
, "cgroup.serviced_ops"
, title
, "operations/s"
+ , "cgroup"
+ , "default"
, CHART_PRIORITY_CONTAINERS + 1200
, update_every
, RRDSET_TYPE_LINE
@@ -2479,6 +2552,8 @@ void update_cgroup_charts(int update_every) {
, "cgroup.throttle_io"
, title
, "KB/s"
+ , "cgroup"
+ , "default"
, CHART_PRIORITY_CONTAINERS + 1200
, update_every
, RRDSET_TYPE_AREA
@@ -2507,6 +2582,8 @@ void update_cgroup_charts(int update_every) {
, "cgroup.throttle_serviced_ops"
, title
, "operations/s"
+ , "cgroup"
+ , "default"
, CHART_PRIORITY_CONTAINERS + 1200
, update_every
, RRDSET_TYPE_LINE
@@ -2535,6 +2612,8 @@ void update_cgroup_charts(int update_every) {
, "cgroup.queued_ops"
, title
, "operations"
+ , "cgroup"
+ , "default"
, CHART_PRIORITY_CONTAINERS + 2000
, update_every
, RRDSET_TYPE_LINE
@@ -2563,6 +2642,8 @@ void update_cgroup_charts(int update_every) {
, "cgroup.merged_ops"
, title
, "operations/s"
+ , "cgroup"
+ , "default"
, CHART_PRIORITY_CONTAINERS + 2100
, update_every
, RRDSET_TYPE_LINE
@@ -2650,6 +2731,8 @@ void *cgroups_main(void *ptr) {
, NULL
, "NetData CGroups Plugin CPU usage"
, "milliseconds/s"
+ , "cgroup"
+ , "stats"
, 132000
, cgroup_update_every
, RRDSET_TYPE_STACKED
diff --git a/src/sys_kernel_mm_ksm.c b/src/sys_kernel_mm_ksm.c
index 6b04ef28..356315be 100644
--- a/src/sys_kernel_mm_ksm.c
+++ b/src/sys_kernel_mm_ksm.c
@@ -102,6 +102,8 @@ int do_sys_kernel_mm_ksm(int update_every, usec_t dt) {
, NULL
, "Kernel Same Page Merging"
, "MB"
+ , "proc"
+ , "/sys/kernel/mm/ksm"
, 5000
, update_every
, RRDSET_TYPE_AREA
@@ -140,6 +142,8 @@ int do_sys_kernel_mm_ksm(int update_every, usec_t dt) {
, NULL
, "Kernel Same Page Merging Savings"
, "MB"
+ , "proc"
+ , "/sys/kernel/mm/ksm"
, 5001
, update_every
, RRDSET_TYPE_AREA
@@ -172,6 +176,8 @@ int do_sys_kernel_mm_ksm(int update_every, usec_t dt) {
, NULL
, "Kernel Same Page Merging Effectiveness"
, "percentage"
+ , "proc"
+ , "/sys/kernel/mm/ksm"
, 5002
, update_every
, RRDSET_TYPE_LINE
diff --git a/src/unit_test.c b/src/unit_test.c
index 3c963211..821063ba 100644
--- a/src/unit_test.c
+++ b/src/unit_test.c
@@ -1,5 +1,62 @@
#include "common.h"
+static int check_rrdcalc_comparisons(void) {
+ RRDCALC_STATUS a, b;
+
+ // make sure calloc() sets the status to UNINITIALIZED
+ memset(&a, 0, sizeof(RRDCALC_STATUS));
+ if(a != RRDCALC_STATUS_UNINITIALIZED) {
+ fprintf(stderr, "%s is not zero.\n", rrdcalc_status2string(RRDCALC_STATUS_UNINITIALIZED));
+ return 1;
+ }
+
+ a = RRDCALC_STATUS_REMOVED;
+ b = RRDCALC_STATUS_UNDEFINED;
+ if(!(a < b)) {
+ fprintf(stderr, "%s is not less than %s\n", rrdcalc_status2string(a), rrdcalc_status2string(b));
+ return 1;
+ }
+
+ a = RRDCALC_STATUS_UNDEFINED;
+ b = RRDCALC_STATUS_UNINITIALIZED;
+ if(!(a < b)) {
+ fprintf(stderr, "%s is not less than %s\n", rrdcalc_status2string(a), rrdcalc_status2string(b));
+ return 1;
+ }
+
+ a = RRDCALC_STATUS_UNINITIALIZED;
+ b = RRDCALC_STATUS_CLEAR;
+ if(!(a < b)) {
+ fprintf(stderr, "%s is not less than %s\n", rrdcalc_status2string(a), rrdcalc_status2string(b));
+ return 1;
+ }
+
+ a = RRDCALC_STATUS_CLEAR;
+ b = RRDCALC_STATUS_RAISED;
+ if(!(a < b)) {
+ fprintf(stderr, "%s is not less than %s\n", rrdcalc_status2string(a), rrdcalc_status2string(b));
+ return 1;
+ }
+
+ a = RRDCALC_STATUS_RAISED;
+ b = RRDCALC_STATUS_WARNING;
+ if(!(a < b)) {
+ fprintf(stderr, "%s is not less than %s\n", rrdcalc_status2string(a), rrdcalc_status2string(b));
+ return 1;
+ }
+
+ a = RRDCALC_STATUS_WARNING;
+ b = RRDCALC_STATUS_CRITICAL;
+ if(!(a < b)) {
+ fprintf(stderr, "%s is not less than %s\n", rrdcalc_status2string(a), rrdcalc_status2string(b));
+ return 1;
+ }
+
+ fprintf(stderr, "RRDCALC_STATUSes are sortable.\n");
+
+ return 0;
+}
+
int check_storage_number(calculated_number n, int debug) {
char buffer[100];
uint32_t flags = SN_EXISTS;
@@ -973,7 +1030,7 @@ int run_test(struct test *test)
snprintfz(name, 100, "unittest-%s", test->name);
// create the chart
- RRDSET *st = rrdset_create_localhost("netdata", name, name, "netdata", NULL, "Unit Testing", "a value", 1
+ RRDSET *st = rrdset_create_localhost("netdata", name, name, "netdata", NULL, "Unit Testing", "a value", "unittest", NULL, 1
, test->update_every, RRDSET_TYPE_LINE);
RRDDIM *rd = rrddim_add(st, "dim1", NULL, test->multiplier, test->divisor, test->algorithm);
@@ -1062,7 +1119,7 @@ int run_test(struct test *test)
static int test_variable_renames(void) {
fprintf(stderr, "Creating chart\n");
- RRDSET *st = rrdset_create_localhost("chart", "ID", NULL, "family", "context", "Unit Testing", "a value", 1, 1, RRDSET_TYPE_LINE);
+ RRDSET *st = rrdset_create_localhost("chart", "ID", NULL, "family", "context", "Unit Testing", "a value", "unittest", NULL, 1, 1, RRDSET_TYPE_LINE);
fprintf(stderr, "Created chart with id '%s', name '%s'\n", st->id, st->name);
fprintf(stderr, "Creating dimension DIM1\n");
@@ -1106,6 +1163,9 @@ static int test_variable_renames(void) {
int run_all_mockup_tests(void)
{
+ if(check_rrdcalc_comparisons())
+ return 1;
+
if(!test_variable_renames())
return 1;
@@ -1182,7 +1242,7 @@ int unit_test(long delay, long shift)
int do_abst = 0;
int do_absi = 0;
- RRDSET *st = rrdset_create_localhost("netdata", name, name, "netdata", NULL, "Unit Testing", "a value", 1, 1
+ RRDSET *st = rrdset_create_localhost("netdata", name, name, "netdata", NULL, "Unit Testing", "a value", "unittest", NULL, 1, 1
, RRDSET_TYPE_LINE);
rrdset_flag_set(st, RRDSET_FLAG_DEBUG);
diff --git a/src/web_api_v1.c b/src/web_api_v1.c
index 9514f8db..02c6b0ed 100644
--- a/src/web_api_v1.c
+++ b/src/web_api_v1.c
@@ -1,20 +1,105 @@
#include "common.h"
-inline int web_client_api_request_v1_data_group(char *name, int def) {
- if(!strcmp(name, "average"))
- return GROUP_AVERAGE;
-
- else if(!strcmp(name, "min"))
- return GROUP_MIN;
-
- else if(!strcmp(name, "max"))
- return GROUP_MAX;
+static struct {
+ const char *name;
+ uint32_t hash;
+ int value;
+} api_v1_data_groups[] = {
+ { "average" , 0 , GROUP_AVERAGE}
+ , {"min" , 0 , GROUP_MIN}
+ , {"max" , 0 , GROUP_MAX}
+ , {"sum" , 0 , GROUP_SUM}
+ , {"incremental_sum", 0 , GROUP_INCREMENTAL_SUM}
+ , {"incremental-sum", 0 , GROUP_INCREMENTAL_SUM}
+ , { NULL, 0, 0}
+};
+
+static struct {
+ const char *name;
+ uint32_t hash;
+ uint32_t value;
+} api_v1_data_options[] = {
+ { "nonzero" , 0 , RRDR_OPTION_NONZERO}
+ , {"flip" , 0 , RRDR_OPTION_REVERSED}
+ , {"reversed" , 0 , RRDR_OPTION_REVERSED}
+ , {"reverse" , 0 , RRDR_OPTION_REVERSED}
+ , {"jsonwrap" , 0 , RRDR_OPTION_JSON_WRAP}
+ , {"min2max" , 0 , RRDR_OPTION_MIN2MAX}
+ , {"ms" , 0 , RRDR_OPTION_MILLISECONDS}
+ , {"milliseconds" , 0 , RRDR_OPTION_MILLISECONDS}
+ , {"abs" , 0 , RRDR_OPTION_ABSOLUTE}
+ , {"absolute" , 0 , RRDR_OPTION_ABSOLUTE}
+ , {"absolute_sum" , 0 , RRDR_OPTION_ABSOLUTE}
+ , {"absolute-sum" , 0 , RRDR_OPTION_ABSOLUTE}
+ , {"display_absolute", 0 , RRDR_OPTION_DISPLAY_ABS}
+ , {"display-absolute", 0 , RRDR_OPTION_DISPLAY_ABS}
+ , {"seconds" , 0 , RRDR_OPTION_SECONDS}
+ , {"null2zero" , 0 , RRDR_OPTION_NULL2ZERO}
+ , {"objectrows" , 0 , RRDR_OPTION_OBJECTSROWS}
+ , {"google_json" , 0 , RRDR_OPTION_GOOGLE_JSON}
+ , {"google-json" , 0 , RRDR_OPTION_GOOGLE_JSON}
+ , {"percentage" , 0 , RRDR_OPTION_PERCENTAGE}
+ , {"unaligned" , 0 , RRDR_OPTION_NOT_ALIGNED}
+ , { NULL, 0, 0}
+};
+
+static struct {
+ const char *name;
+ uint32_t hash;
+ uint32_t value;
+} api_v1_data_formats[] = {
+ { DATASOURCE_FORMAT_DATATABLE_JSON , 0 , DATASOURCE_DATATABLE_JSON}
+ , {DATASOURCE_FORMAT_DATATABLE_JSONP, 0 , DATASOURCE_DATATABLE_JSONP}
+ , {DATASOURCE_FORMAT_JSON , 0 , DATASOURCE_JSON}
+ , {DATASOURCE_FORMAT_JSONP , 0 , DATASOURCE_JSONP}
+ , {DATASOURCE_FORMAT_SSV , 0 , DATASOURCE_SSV}
+ , {DATASOURCE_FORMAT_CSV , 0 , DATASOURCE_CSV}
+ , {DATASOURCE_FORMAT_TSV , 0 , DATASOURCE_TSV}
+ , {"tsv-excel" , 0 , DATASOURCE_TSV}
+ , {DATASOURCE_FORMAT_HTML , 0 , DATASOURCE_HTML}
+ , {DATASOURCE_FORMAT_JS_ARRAY , 0 , DATASOURCE_JS_ARRAY}
+ , {DATASOURCE_FORMAT_SSV_COMMA , 0 , DATASOURCE_SSV_COMMA}
+ , {DATASOURCE_FORMAT_CSV_JSON_ARRAY , 0 , DATASOURCE_CSV_JSON_ARRAY}
+ , { NULL, 0, 0}
+};
+
+static struct {
+ const char *name;
+ uint32_t hash;
+ uint32_t value;
+} api_v1_data_google_formats[] = {
+ // this is not error - when google requests json, it expects javascript
+ // https://developers.google.com/chart/interactive/docs/dev/implementing_data_source#responseformat
+ { "json" , 0 , DATASOURCE_DATATABLE_JSONP}
+ , {"html" , 0 , DATASOURCE_HTML}
+ , {"csv" , 0 , DATASOURCE_CSV}
+ , {"tsv-excel", 0 , DATASOURCE_TSV}
+ , { NULL, 0, 0}
+};
+
+void web_client_api_v1_init(void) {
+ int i;
+
+ for(i = 0; api_v1_data_groups[i].name ; i++)
+ api_v1_data_groups[i].hash = simple_hash(api_v1_data_groups[i].name);
+
+ for(i = 0; api_v1_data_options[i].name ; i++)
+ api_v1_data_options[i].hash = simple_hash(api_v1_data_options[i].name);
+
+ for(i = 0; api_v1_data_formats[i].name ; i++)
+ api_v1_data_formats[i].hash = simple_hash(api_v1_data_formats[i].name);
+
+ for(i = 0; api_v1_data_google_formats[i].name ; i++)
+ api_v1_data_google_formats[i].hash = simple_hash(api_v1_data_google_formats[i].name);
+}
- else if(!strcmp(name, "sum"))
- return GROUP_SUM;
+inline int web_client_api_request_v1_data_group(char *name, int def) {
+ int i;
- else if(!strcmp(name, "incremental-sum"))
- return GROUP_INCREMENTAL_SUM;
+ uint32_t hash = simple_hash(name);
+ for(i = 0; api_v1_data_groups[i].name ; i++)
+ if(unlikely(hash == api_v1_data_groups[i].hash && !strcmp(name, api_v1_data_groups[i].name)))
+ return api_v1_data_groups[i].value;
return def;
}
@@ -26,84 +111,41 @@ inline uint32_t web_client_api_request_v1_data_options(char *o) {
while(o && *o && (tok = mystrsep(&o, ", |"))) {
if(!*tok) continue;
- if(!strcmp(tok, "nonzero"))
- ret |= RRDR_OPTION_NONZERO;
- else if(!strcmp(tok, "flip") || !strcmp(tok, "reversed") || !strcmp(tok, "reverse"))
- ret |= RRDR_OPTION_REVERSED;
- else if(!strcmp(tok, "jsonwrap"))
- ret |= RRDR_OPTION_JSON_WRAP;
- else if(!strcmp(tok, "min2max"))
- ret |= RRDR_OPTION_MIN2MAX;
- else if(!strcmp(tok, "ms") || !strcmp(tok, "milliseconds"))
- ret |= RRDR_OPTION_MILLISECONDS;
- else if(!strcmp(tok, "abs") || !strcmp(tok, "absolute") || !strcmp(tok, "absolute_sum") || !strcmp(tok, "absolute-sum"))
- ret |= RRDR_OPTION_ABSOLUTE;
- else if(!strcmp(tok, "seconds"))
- ret |= RRDR_OPTION_SECONDS;
- else if(!strcmp(tok, "null2zero"))
- ret |= RRDR_OPTION_NULL2ZERO;
- else if(!strcmp(tok, "objectrows"))
- ret |= RRDR_OPTION_OBJECTSROWS;
- else if(!strcmp(tok, "google_json"))
- ret |= RRDR_OPTION_GOOGLE_JSON;
- else if(!strcmp(tok, "percentage"))
- ret |= RRDR_OPTION_PERCENTAGE;
- else if(!strcmp(tok, "unaligned"))
- ret |= RRDR_OPTION_NOT_ALIGNED;
+ uint32_t hash = simple_hash(tok);
+ int i;
+ for(i = 0; api_v1_data_options[i].name ; i++) {
+ if (unlikely(hash == api_v1_data_options[i].hash && !strcmp(tok, api_v1_data_options[i].name))) {
+ ret |= api_v1_data_options[i].value;
+ break;
+ }
+ }
}
return ret;
}
inline uint32_t web_client_api_request_v1_data_format(char *name) {
- if(!strcmp(name, DATASOURCE_FORMAT_DATATABLE_JSON)) // datatable
- return DATASOURCE_DATATABLE_JSON;
-
- else if(!strcmp(name, DATASOURCE_FORMAT_DATATABLE_JSONP)) // datasource
- return DATASOURCE_DATATABLE_JSONP;
-
- else if(!strcmp(name, DATASOURCE_FORMAT_JSON)) // json
- return DATASOURCE_JSON;
-
- else if(!strcmp(name, DATASOURCE_FORMAT_JSONP)) // jsonp
- return DATASOURCE_JSONP;
-
- else if(!strcmp(name, DATASOURCE_FORMAT_SSV)) // ssv
- return DATASOURCE_SSV;
-
- else if(!strcmp(name, DATASOURCE_FORMAT_CSV)) // csv
- return DATASOURCE_CSV;
-
- else if(!strcmp(name, DATASOURCE_FORMAT_TSV) || !strcmp(name, "tsv-excel")) // tsv
- return DATASOURCE_TSV;
-
- else if(!strcmp(name, DATASOURCE_FORMAT_HTML)) // html
- return DATASOURCE_HTML;
-
- else if(!strcmp(name, DATASOURCE_FORMAT_JS_ARRAY)) // array
- return DATASOURCE_JS_ARRAY;
+ uint32_t hash = simple_hash(name);
+ int i;
- else if(!strcmp(name, DATASOURCE_FORMAT_SSV_COMMA)) // ssvcomma
- return DATASOURCE_SSV_COMMA;
-
- else if(!strcmp(name, DATASOURCE_FORMAT_CSV_JSON_ARRAY)) // csvjsonarray
- return DATASOURCE_CSV_JSON_ARRAY;
+ for(i = 0; api_v1_data_formats[i].name ; i++) {
+ if (unlikely(hash == api_v1_data_formats[i].hash && !strcmp(name, api_v1_data_formats[i].name))) {
+ return api_v1_data_formats[i].value;
+ }
+ }
return DATASOURCE_JSON;
}
inline uint32_t web_client_api_request_v1_data_google_format(char *name) {
- if(!strcmp(name, "json"))
- return DATASOURCE_DATATABLE_JSONP;
-
- else if(!strcmp(name, "html"))
- return DATASOURCE_HTML;
+ uint32_t hash = simple_hash(name);
+ int i;
- else if(!strcmp(name, "csv"))
- return DATASOURCE_CSV;
-
- else if(!strcmp(name, "tsv-excel"))
- return DATASOURCE_TSV;
+ for(i = 0; api_v1_data_google_formats[i].name ; i++) {
+ if (unlikely(hash == api_v1_data_google_formats[i].hash && !strcmp(name, api_v1_data_google_formats[i].name))) {
+ return api_v1_data_google_formats[i].value;
+ }
+ }
return DATASOURCE_JSON;
}
@@ -371,7 +413,7 @@ int web_client_api_request_v1_badge(RRDHOST *host, struct web_client *w, char *u
if(!st) st = rrdset_find_byname(host, chart);
if(!st) {
buffer_no_cacheable(w->response.data);
- buffer_svg(w->response.data, "chart not found", NAN, "", NULL, NULL, -1);
+ buffer_svg(w->response.data, "chart not found", NAN, "", NULL, NULL, -1, 0);
ret = 200;
goto cleanup;
}
@@ -382,7 +424,7 @@ int web_client_api_request_v1_badge(RRDHOST *host, struct web_client *w, char *u
rc = rrdcalc_find(st, alarm);
if (!rc) {
buffer_no_cacheable(w->response.data);
- buffer_svg(w->response.data, "alarm not found", NAN, "", NULL, NULL, -1);
+ buffer_svg(w->response.data, "alarm not found", NAN, "", NULL, NULL, -1, 0);
ret = 200;
goto cleanup;
}
@@ -498,7 +540,9 @@ int web_client_api_request_v1_badge(RRDHOST *host, struct web_client *w, char *u
units,
label_color,
value_color,
- precision);
+ precision,
+ options
+ );
ret = 200;
}
else {
@@ -532,7 +576,9 @@ int web_client_api_request_v1_badge(RRDHOST *host, struct web_client *w, char *u
units,
label_color,
value_color,
- precision);
+ precision,
+ options
+ );
}
cleanup:
@@ -816,55 +862,65 @@ inline int web_client_api_request_v1_registry(RRDHOST *host, struct web_client *
#endif /* NETDATA_INTERNAL_CHECKS */
}
- if(respect_web_browser_do_not_track_policy && web_client_has_donottrack(w)) {
+ if(unlikely(respect_web_browser_do_not_track_policy && web_client_has_donottrack(w))) {
buffer_flush(w->response.data);
buffer_sprintf(w->response.data, "Your web browser is sending 'DNT: 1' (Do Not Track). The registry requires persistent cookies on your browser to work.");
return 400;
}
- if(action == 'A' && (!machine_guid || !machine_url || !url_name)) {
- error("Invalid registry request - access requires these parameters: machine ('%s'), url ('%s'), name ('%s')",
- machine_guid?machine_guid:"UNSET", machine_url?machine_url:"UNSET", url_name?url_name:"UNSET");
- buffer_flush(w->response.data);
- buffer_strcat(w->response.data, "Invalid registry Access request.");
- return 400;
- }
- else if(action == 'D' && (!machine_guid || !machine_url || !delete_url)) {
- error("Invalid registry request - delete requires these parameters: machine ('%s'), url ('%s'), delete_url ('%s')",
- machine_guid?machine_guid:"UNSET", machine_url?machine_url:"UNSET", delete_url?delete_url:"UNSET");
- buffer_flush(w->response.data);
- buffer_strcat(w->response.data, "Invalid registry Delete request.");
- return 400;
+ if(unlikely(action == 'H')) {
+ // HELLO request, dashboard ACL
+ if(unlikely(!web_client_can_access_dashboard(w)))
+ return web_client_permission_denied(w);
}
- else if(action == 'S' && (!machine_guid || !machine_url || !search_machine_guid)) {
- error("Invalid registry request - search requires these parameters: machine ('%s'), url ('%s'), for ('%s')",
- machine_guid?machine_guid:"UNSET", machine_url?machine_url:"UNSET", search_machine_guid?search_machine_guid:"UNSET");
- buffer_flush(w->response.data);
- buffer_strcat(w->response.data, "Invalid registry Search request.");
- return 400;
- }
- else if(action == 'W' && (!machine_guid || !machine_url || !to_person_guid)) {
- error("Invalid registry request - switching identity requires these parameters: machine ('%s'), url ('%s'), to ('%s')",
- machine_guid?machine_guid:"UNSET", machine_url?machine_url:"UNSET", to_person_guid?to_person_guid:"UNSET");
- buffer_flush(w->response.data);
- buffer_strcat(w->response.data, "Invalid registry Switch request.");
- return 400;
+ else {
+ // everything else, registry ACL
+ if(unlikely(!web_client_can_access_registry(w)))
+ return web_client_permission_denied(w);
}
switch(action) {
case 'A':
+ if(unlikely(!machine_guid || !machine_url || !url_name)) {
+ error("Invalid registry request - access requires these parameters: machine ('%s'), url ('%s'), name ('%s')", machine_guid ? machine_guid : "UNSET", machine_url ? machine_url : "UNSET", url_name ? url_name : "UNSET");
+ buffer_flush(w->response.data);
+ buffer_strcat(w->response.data, "Invalid registry Access request.");
+ return 400;
+ }
+
web_client_enable_tracking_required(w);
return registry_request_access_json(host, w, person_guid, machine_guid, machine_url, url_name, now_realtime_sec());
case 'D':
+ if(unlikely(!machine_guid || !machine_url || !delete_url)) {
+ error("Invalid registry request - delete requires these parameters: machine ('%s'), url ('%s'), delete_url ('%s')", machine_guid?machine_guid:"UNSET", machine_url?machine_url:"UNSET", delete_url?delete_url:"UNSET");
+ buffer_flush(w->response.data);
+ buffer_strcat(w->response.data, "Invalid registry Delete request.");
+ return 400;
+ }
+
web_client_enable_tracking_required(w);
return registry_request_delete_json(host, w, person_guid, machine_guid, machine_url, delete_url, now_realtime_sec());
case 'S':
+ if(unlikely(!machine_guid || !machine_url || !search_machine_guid)) {
+ error("Invalid registry request - search requires these parameters: machine ('%s'), url ('%s'), for ('%s')", machine_guid?machine_guid:"UNSET", machine_url?machine_url:"UNSET", search_machine_guid?search_machine_guid:"UNSET");
+ buffer_flush(w->response.data);
+ buffer_strcat(w->response.data, "Invalid registry Search request.");
+ return 400;
+ }
+
web_client_enable_tracking_required(w);
return registry_request_search_json(host, w, person_guid, machine_guid, machine_url, search_machine_guid, now_realtime_sec());
case 'W':
+ if(unlikely(!machine_guid || !machine_url || !to_person_guid)) {
+ error("Invalid registry request - switching identity requires these parameters: machine ('%s'), url ('%s'), to ('%s')", machine_guid?machine_guid:"UNSET", machine_url?machine_url:"UNSET", to_person_guid?to_person_guid:"UNSET");
+ buffer_flush(w->response.data);
+ buffer_strcat(w->response.data, "Invalid registry Switch request.");
+ return 400;
+ }
+
web_client_enable_tracking_required(w);
return registry_request_switch_json(host, w, person_guid, machine_guid, machine_url, to_person_guid, now_realtime_sec());
@@ -878,19 +934,40 @@ inline int web_client_api_request_v1_registry(RRDHOST *host, struct web_client *
}
}
+static struct api_command {
+ const char *command;
+ uint32_t hash;
+ WEB_CLIENT_ACL acl;
+ int (*callback)(RRDHOST *host, struct web_client *w, char *url);
+} api_commands[] = {
+ { "data", 0, WEB_CLIENT_ACL_DASHBOARD, web_client_api_request_v1_data },
+ { "chart", 0, WEB_CLIENT_ACL_DASHBOARD, web_client_api_request_v1_chart },
+ { "charts", 0, WEB_CLIENT_ACL_DASHBOARD, web_client_api_request_v1_charts },
+
+ // registry checks the ACL by itself, so we allow everything
+ { "registry", 0, WEB_CLIENT_ACL_NOCHECK, web_client_api_request_v1_registry },
+
+ // badges can be fetched with both dashboard and badge permissions
+ { "badge.svg", 0, WEB_CLIENT_ACL_DASHBOARD|WEB_CLIENT_ACL_BADGE, web_client_api_request_v1_badge },
+
+ { "alarms", 0, WEB_CLIENT_ACL_DASHBOARD, web_client_api_request_v1_alarms },
+ { "alarm_log", 0, WEB_CLIENT_ACL_DASHBOARD, web_client_api_request_v1_alarm_log },
+ { "alarm_variables", 0, WEB_CLIENT_ACL_DASHBOARD, web_client_api_request_v1_alarm_variables },
+ { "allmetrics", 0, WEB_CLIENT_ACL_DASHBOARD, web_client_api_request_v1_allmetrics },
+
+ // terminator
+ { NULL, 0, WEB_CLIENT_ACL_NONE, NULL },
+};
+
inline int web_client_api_request_v1(RRDHOST *host, struct web_client *w, char *url) {
- static uint32_t hash_data = 0, hash_chart = 0, hash_charts = 0, hash_registry = 0, hash_badge = 0, hash_alarms = 0, hash_alarm_log = 0, hash_alarm_variables = 0, hash_raw = 0;
+ static int initialized = 0;
+ int i;
+
+ if(unlikely(initialized == 0)) {
+ initialized = 1;
- if(unlikely(hash_data == 0)) {
- hash_data = simple_hash("data");
- hash_chart = simple_hash("chart");
- hash_charts = simple_hash("charts");
- hash_registry = simple_hash("registry");
- hash_badge = simple_hash("badge.svg");
- hash_alarms = simple_hash("alarms");
- hash_alarm_log = simple_hash("alarm_log");
- hash_alarm_variables = simple_hash("alarm_variables");
- hash_raw = simple_hash("allmetrics");
+ for(i = 0; api_commands[i].command ; i++)
+ api_commands[i].hash = simple_hash(api_commands[i].command);
}
// get the command
@@ -899,39 +976,19 @@ inline int web_client_api_request_v1(RRDHOST *host, struct web_client *w, char *
debug(D_WEB_CLIENT, "%llu: Searching for API v1 command '%s'.", w->id, tok);
uint32_t hash = simple_hash(tok);
- if(hash == hash_data && !strcmp(tok, "data"))
- return web_client_api_request_v1_data(host, w, url);
-
- else if(hash == hash_chart && !strcmp(tok, "chart"))
- return web_client_api_request_v1_chart(host, w, url);
-
- else if(hash == hash_charts && !strcmp(tok, "charts"))
- return web_client_api_request_v1_charts(host, w, url);
-
- else if(hash == hash_registry && !strcmp(tok, "registry"))
- return web_client_api_request_v1_registry(host, w, url);
-
- else if(hash == hash_badge && !strcmp(tok, "badge.svg"))
- return web_client_api_request_v1_badge(host, w, url);
-
- else if(hash == hash_alarms && !strcmp(tok, "alarms"))
- return web_client_api_request_v1_alarms(host, w, url);
-
- else if(hash == hash_alarm_log && !strcmp(tok, "alarm_log"))
- return web_client_api_request_v1_alarm_log(host, w, url);
+ for(i = 0; api_commands[i].command ;i++) {
+ if(unlikely(hash == api_commands[i].hash && !strcmp(tok, api_commands[i].command))) {
+ if(unlikely(api_commands[i].acl != WEB_CLIENT_ACL_NOCHECK) && !(w->acl & api_commands[i].acl))
+ return web_client_permission_denied(w);
- else if(hash == hash_alarm_variables && !strcmp(tok, "alarm_variables"))
- return web_client_api_request_v1_alarm_variables(host, w, url);
-
- else if(hash == hash_raw && !strcmp(tok, "allmetrics"))
- return web_client_api_request_v1_allmetrics(host, w, url);
-
- else {
- buffer_flush(w->response.data);
- buffer_strcat(w->response.data, "Unsupported v1 API command: ");
- buffer_strcat_htmlescape(w->response.data, tok);
- return 404;
+ return api_commands[i].callback(host, w, url);
+ }
}
+
+ buffer_flush(w->response.data);
+ buffer_strcat(w->response.data, "Unsupported v1 API command: ");
+ buffer_strcat_htmlescape(w->response.data, tok);
+ return 404;
}
else {
buffer_flush(w->response.data);
diff --git a/src/web_api_v1.h b/src/web_api_v1.h
index e980edb1..6f4de1ab 100644
--- a/src/web_api_v1.h
+++ b/src/web_api_v1.h
@@ -18,4 +18,6 @@ extern int web_client_api_request_v1_data(RRDHOST *host, struct web_client *w, c
extern int web_client_api_request_v1_registry(RRDHOST *host, struct web_client *w, char *url);
extern int web_client_api_request_v1(RRDHOST *host, struct web_client *w, char *url);
+extern void web_client_api_v1_init(void);
+
#endif //NETDATA_WEB_API_V1_H
diff --git a/src/web_buffer_svg.c b/src/web_buffer_svg.c
index 287bbd6b..25128bd3 100644
--- a/src/web_buffer_svg.c
+++ b/src/web_buffer_svg.c
@@ -382,7 +382,7 @@ static inline char *format_value_with_precision_and_unit(char *value_string, siz
calculated_number abs = value;
if(isless(value, 0)) {
lstop = 1;
- abs = -value;
+ abs = calculated_number_fabs(value);
}
if(isgreaterequal(abs, 1000)) {
@@ -610,16 +610,22 @@ static inline const char *color_map(const char *color) {
return color;
}
+typedef enum color_comparison {
+ COLOR_COMPARE_EQUAL,
+ COLOR_COMPARE_NOTEQUAL,
+ COLOR_COMPARE_LESS,
+ COLOR_COMPARE_LESSEQUAL,
+ COLOR_COMPARE_GREATER,
+ COLOR_COMPARE_GREATEREQUAL,
+} BADGE_COLOR_COMPARISON;
+
static inline void calc_colorz(const char *color, char *final, size_t len, calculated_number value) {
- int value_is_null = 0;
- if(isnan(value) || isinf(value)) {
- value = 0.0;
- value_is_null = 1;
- }
+ if(isnan(value) || isinf(value))
+ value = NAN;
char color_buffer[256 + 1] = "";
char value_buffer[256 + 1] = "";
- char comparison = '>';
+ BADGE_COLOR_COMPARISON comparison = COLOR_COMPARE_GREATER;
// example input:
// color<max|color>min|color:null...
@@ -633,8 +639,15 @@ static inline void calc_colorz(const char *color, char *final, size_t len, calcu
while(*t && *t != '|') {
switch(*t) {
+ case '!':
+ if(t[1] == '=') t++;
+ comparison = COLOR_COMPARE_NOTEQUAL;
+ dv = value_buffer;
+ break;
+
+ case '=':
case ':':
- comparison = '=';
+ comparison = COLOR_COMPARE_EQUAL;
dv = value_buffer;
break;
@@ -642,11 +655,11 @@ static inline void calc_colorz(const char *color, char *final, size_t len, calcu
case ')':
case '>':
if(t[1] == '=') {
- comparison = ')';
+ comparison = COLOR_COMPARE_GREATEREQUAL;
t++;
}
else
- comparison = '>';
+ comparison = COLOR_COMPARE_GREATER;
dv = value_buffer;
break;
@@ -654,11 +667,15 @@ static inline void calc_colorz(const char *color, char *final, size_t len, calcu
case '(':
case '<':
if(t[1] == '=') {
- comparison = '(';
+ comparison = COLOR_COMPARE_LESSEQUAL;
+ t++;
+ }
+ else if(t[1] == '>' || t[1] == ')' || t[1] == '}') {
+ comparison = COLOR_COMPARE_NOTEQUAL;
t++;
}
else
- comparison = '<';
+ comparison = COLOR_COMPARE_LESS;
dv = value_buffer;
break;
@@ -689,19 +706,28 @@ static inline void calc_colorz(const char *color, char *final, size_t len, calcu
*dc = '\0';
if(dv) {
*dv = '\0';
+ calculated_number v;
- if(value_is_null) {
- if(!*value_buffer || !strcmp(value_buffer, "null"))
- break;
+ if(!*value_buffer || !strcmp(value_buffer, "null")) {
+ v = NAN;
}
else {
- calculated_number v = str2l(value_buffer);
+ v = str2l(value_buffer);
+ if(isnan(v) || isinf(v))
+ v = NAN;
+ }
- if(comparison == '<' && value < v) break;
- else if(comparison == '(' && value <= v) break;
- else if(comparison == '>' && value > v) break;
- else if(comparison == ')' && value >= v) break;
- else if(comparison == '=' && value == v) break;
+ if(unlikely(isnan(value) || isnan(v))) {
+ if(isnan(value) && isnan(v))
+ break;
+ }
+ else {
+ if (unlikely(comparison == COLOR_COMPARE_LESS && isless(value, v))) break;
+ else if (unlikely(comparison == COLOR_COMPARE_LESSEQUAL && islessequal(value, v))) break;
+ else if (unlikely(comparison == COLOR_COMPARE_GREATER && isgreater(value, v))) break;
+ else if (unlikely(comparison == COLOR_COMPARE_GREATEREQUAL && isgreaterequal(value, v))) break;
+ else if (unlikely(comparison == COLOR_COMPARE_EQUAL && !islessgreater(value, v))) break;
+ else if (unlikely(comparison == COLOR_COMPARE_NOTEQUAL && islessgreater(value, v))) break;
}
}
else
@@ -726,7 +752,7 @@ static inline void calc_colorz(const char *color, char *final, size_t len, calcu
// colors
#define COLOR_STRING_SIZE 100
-void buffer_svg(BUFFER *wb, const char *label, calculated_number value, const char *units, const char *label_color, const char *value_color, int precision) {
+void buffer_svg(BUFFER *wb, const char *label, calculated_number value, const char *units, const char *label_color, const char *value_color, int precision, uint32_t options) {
char label_buffer[LABEL_STRING_SIZE + 1]
, value_color_buffer[COLOR_STRING_SIZE + 1]
, value_string[VALUE_STRING_SIZE + 1]
@@ -744,7 +770,7 @@ void buffer_svg(BUFFER *wb, const char *label, calculated_number value, const ch
value_color = (isnan(value) || isinf(value))?"#999":"#4c1";
calc_colorz(value_color, value_color_buffer, COLOR_STRING_SIZE, value);
- format_value_and_unit(value_string, VALUE_STRING_SIZE, value, units, precision);
+ format_value_and_unit(value_string, VALUE_STRING_SIZE, (options & RRDR_OPTION_DISPLAY_ABS)?calculated_number_fabs(value):value, units, precision);
// we need to copy the label, since verdana11_width may write to it
strncpyz(label_buffer, label, LABEL_STRING_SIZE);
diff --git a/src/web_buffer_svg.h b/src/web_buffer_svg.h
index 49f73e44..c09ef7bc 100644
--- a/src/web_buffer_svg.h
+++ b/src/web_buffer_svg.h
@@ -1,7 +1,7 @@
#ifndef NETDATA_WEB_BUFFER_SVG_H
#define NETDATA_WEB_BUFFER_SVG_H 1
-extern void buffer_svg(BUFFER *wb, const char *label, calculated_number value, const char *units, const char *label_color, const char *value_color, int precision);
+extern void buffer_svg(BUFFER *wb, const char *label, calculated_number value, const char *units, const char *label_color, const char *value_color, int precision, uint32_t options);
extern char *format_value_and_unit(char *value_string, size_t value_string_len, calculated_number value, const char *units, int precision);
#endif /* NETDATA_WEB_BUFFER_SVG_H */
diff --git a/src/web_client.c b/src/web_client.c
index 6ec3e11e..e17bac92 100644
--- a/src/web_client.c
+++ b/src/web_client.c
@@ -8,6 +8,15 @@ int web_client_timeout = DEFAULT_DISCONNECT_IDLE_WEB_CLIENTS_AFTER_SECONDS;
int respect_web_browser_do_not_track_policy = 0;
char *web_x_frame_options = NULL;
+SIMPLE_PATTERN *web_allow_connections_from = NULL;
+SIMPLE_PATTERN *web_allow_streaming_from = NULL;
+SIMPLE_PATTERN *web_allow_netdataconf_from = NULL;
+
+// WEB_CLIENT_ACL
+SIMPLE_PATTERN *web_allow_dashboard_from = NULL;
+SIMPLE_PATTERN *web_allow_registry_from = NULL;
+SIMPLE_PATTERN *web_allow_badges_from = NULL;
+
#ifdef NETDATA_WITH_ZLIB
int web_enable_gzip = 1, web_gzip_level = 3, web_gzip_strategy = Z_DEFAULT_STRATEGY;
#endif /* NETDATA_WITH_ZLIB */
@@ -50,6 +59,31 @@ static inline int web_client_uncrock_socket(struct web_client *w) {
return 0;
}
+inline int web_client_permission_denied(struct web_client *w) {
+ w->response.data->contenttype = CT_TEXT_PLAIN;
+ buffer_flush(w->response.data);
+ buffer_strcat(w->response.data, "You are not allowed to access this resource.");
+ w->response.code = 403;
+ return 403;
+}
+
+static void log_connection(struct web_client *w, const char *msg) {
+ log_access("%llu: %d '[%s]:%s' '%s'", w->id, gettid(), w->client_ip, w->client_port, msg);
+}
+
+static void web_client_update_acl_matches(struct web_client *w) {
+ w->acl = WEB_CLIENT_ACL_NONE;
+
+ if(!web_allow_dashboard_from || simple_pattern_matches(web_allow_dashboard_from, w->client_ip))
+ w->acl |= WEB_CLIENT_ACL_DASHBOARD;
+
+ if(!web_allow_registry_from || simple_pattern_matches(web_allow_registry_from, w->client_ip))
+ w->acl |= WEB_CLIENT_ACL_REGISTRY;
+
+ if(!web_allow_badges_from || simple_pattern_matches(web_allow_badges_from, w->client_ip))
+ w->acl |= WEB_CLIENT_ACL_BADGE;
+}
+
struct web_client *web_client_create(int listener) {
struct web_client *w;
@@ -58,12 +92,25 @@ struct web_client *web_client_create(int listener) {
w->mode = WEB_CLIENT_MODE_NORMAL;
{
- w->ifd = accept_socket(listener, SOCK_NONBLOCK, w->client_ip, sizeof(w->client_ip), w->client_port, sizeof(w->client_port));
+ w->ifd = accept_socket(listener, SOCK_NONBLOCK, w->client_ip, sizeof(w->client_ip), w->client_port, sizeof(w->client_port), web_allow_connections_from);
+
+ if(unlikely(!*w->client_ip)) strcpy(w->client_ip, "-");
+ if(unlikely(!*w->client_port)) strcpy(w->client_port, "-");
+
if (w->ifd == -1) {
- error("%llu: Cannot accept new incoming connection.", w->id);
+ if(errno == EPERM)
+ log_connection(w, "ACCESS DENIED");
+ else {
+ log_connection(w, "CONNECTION FAILED");
+ error("%llu: Failed to accept new incoming connection.", w->id);
+ }
+
freez(w);
return NULL;
}
+ else
+ log_connection(w, "CONNECTED");
+
w->ofd = w->ifd;
int flag = 1;
@@ -75,6 +122,8 @@ struct web_client *web_client_create(int listener) {
error("%llu: Cannot set SO_KEEPALIVE on socket.", w->id);
}
+ web_client_update_acl_matches(w);
+
w->response.data = buffer_create(INITIAL_WEB_DATA_LENGTH);
w->response.header = buffer_create(HTTP_RESPONSE_HEADER_SIZE);
w->response.header_output = buffer_create(HTTP_RESPONSE_HEADER_SIZE);
@@ -119,18 +168,45 @@ void web_client_reset(struct web_client *w) {
// --------------------------------------------------------------------
- // access log
- log_access("%llu: (sent/all = %zu/%zu bytes %0.0f%%, prep/sent/total = %0.2f/%0.2f/%0.2f ms) %s: %d '%s'",
- w->id,
- sent, size, -((size > 0) ? ((size - sent) / (double) size * 100.0) : 0.0),
- dt_usec(&w->tv_ready, &w->tv_in) / 1000.0,
- dt_usec(&tv, &w->tv_ready) / 1000.0,
- dt_usec(&tv, &w->tv_in) / 1000.0,
- (w->mode == WEB_CLIENT_MODE_FILECOPY) ? "filecopy" : ((w->mode == WEB_CLIENT_MODE_OPTIONS)
- ? "options" : "data"),
- w->response.code,
- w->last_url
+ const char *mode;
+ switch(w->mode) {
+ case WEB_CLIENT_MODE_FILECOPY:
+ mode = "FILECOPY";
+ break;
+
+ case WEB_CLIENT_MODE_OPTIONS:
+ mode = "OPTIONS";
+ break;
+
+ case WEB_CLIENT_MODE_STREAM:
+ mode = "STREAM";
+ break;
+
+ case WEB_CLIENT_MODE_NORMAL:
+ mode = "DATA";
+ break;
+
+ default:
+ mode = "UNKNOWN";
+ break;
+ }
+
+ // access log
+ log_access("%llu: %d '[%s]:%s' '%s' (sent/all = %zu/%zu bytes %0.0f%%, prep/sent/total = %0.2f/%0.2f/%0.2f ms) %d '%s'",
+ w->id
+ , gettid()
+ , w->client_ip
+ , w->client_port
+ , mode
+ , sent
+ , size
+ , -((size > 0) ? ((size - sent) / (double) size * 100.0) : 0.0)
+ , dt_usec(&w->tv_ready, &w->tv_in) / 1000.0
+ , dt_usec(&tv, &w->tv_ready) / 1000.0
+ , dt_usec(&tv, &w->tv_in) / 1000.0
+ , w->response.code
+ , w->last_url
);
}
@@ -271,6 +347,9 @@ gid_t web_files_gid(void) {
int mysendfile(struct web_client *w, char *filename) {
debug(D_WEB_CLIENT, "%llu: Looking for file '%s/%s'", w->id, netdata_configured_web_dir, filename);
+ if(!web_client_can_access_dashboard(w))
+ return web_client_permission_denied(w);
+
// skip leading slashes
while (*filename == '/') filename++;
@@ -553,6 +632,13 @@ static inline int check_host_and_call(RRDHOST *host, struct web_client *w, char
return func(host, w, url);
}
+static inline int check_host_and_dashboard_acl_and_call(RRDHOST *host, struct web_client *w, char *url, int (*func)(RRDHOST *, struct web_client *, char *)) {
+ if(!web_client_can_access_dashboard(w))
+ return web_client_permission_denied(w);
+
+ return check_host_and_call(host, w, url, func);
+}
+
int web_client_api_request(RRDHOST *host, struct web_client *w, char *url)
{
// get the api version
@@ -1082,25 +1168,28 @@ static inline int web_client_process_url(RRDHOST *host, struct web_client *w, ch
}
else if(unlikely(hash == hash_data && strcmp(tok, WEB_PATH_DATA) == 0)) { // old API "data"
debug(D_WEB_CLIENT_ACCESS, "%llu: old API data request...", w->id);
- return check_host_and_call(host, w, url, web_client_api_old_data_request_json);
+ return check_host_and_dashboard_acl_and_call(host, w, url, web_client_api_old_data_request_json);
}
else if(unlikely(hash == hash_datasource && strcmp(tok, WEB_PATH_DATASOURCE) == 0)) { // old API "datasource"
debug(D_WEB_CLIENT_ACCESS, "%llu: old API datasource request...", w->id);
- return check_host_and_call(host, w, url, web_client_api_old_data_request_jsonp);
+ return check_host_and_dashboard_acl_and_call(host, w, url, web_client_api_old_data_request_jsonp);
}
else if(unlikely(hash == hash_graph && strcmp(tok, WEB_PATH_GRAPH) == 0)) { // old API "graph"
debug(D_WEB_CLIENT_ACCESS, "%llu: old API graph request...", w->id);
- return check_host_and_call(host, w, url, web_client_api_old_graph_request);
+ return check_host_and_dashboard_acl_and_call(host, w, url, web_client_api_old_graph_request);
}
else if(unlikely(hash == hash_list && strcmp(tok, "list") == 0)) { // old API "list"
debug(D_WEB_CLIENT_ACCESS, "%llu: old API list request...", w->id);
- return check_host_and_call(host, w, url, web_client_api_old_list_request);
+ return check_host_and_dashboard_acl_and_call(host, w, url, web_client_api_old_list_request);
}
else if(unlikely(hash == hash_all_json && strcmp(tok, "all.json") == 0)) { // old API "all.json"
debug(D_WEB_CLIENT_ACCESS, "%llu: old API all.json request...", w->id);
- return check_host_and_call(host, w, url, web_client_api_old_all_json);
+ return check_host_and_dashboard_acl_and_call(host, w, url, web_client_api_old_all_json);
}
else if(unlikely(hash == hash_netdata_conf && strcmp(tok, "netdata.conf") == 0)) { // netdata.conf
+ if(unlikely(!web_client_can_access_netdataconf(w)))
+ return web_client_permission_denied(w);
+
debug(D_WEB_CLIENT_ACCESS, "%llu: generating netdata.conf ...", w->id);
w->response.data->contenttype = CT_TEXT_PLAIN;
buffer_flush(w->response.data);
@@ -1109,6 +1198,9 @@ static inline int web_client_process_url(RRDHOST *host, struct web_client *w, ch
}
#ifdef NETDATA_INTERNAL_CHECKS
else if(unlikely(hash == hash_exit && strcmp(tok, "exit") == 0)) {
+ if(unlikely(!web_client_can_access_netdataconf(w)))
+ return web_client_permission_denied(w);
+
w->response.data->contenttype = CT_TEXT_PLAIN;
buffer_flush(w->response.data);
@@ -1122,6 +1214,9 @@ static inline int web_client_process_url(RRDHOST *host, struct web_client *w, ch
return 200;
}
else if(unlikely(hash == hash_debug && strcmp(tok, "debug") == 0)) {
+ if(unlikely(!web_client_can_access_netdataconf(w)))
+ return web_client_permission_denied(w);
+
buffer_flush(w->response.data);
// get the name of the data to show
@@ -1159,6 +1254,9 @@ static inline int web_client_process_url(RRDHOST *host, struct web_client *w, ch
return 400;
}
else if(unlikely(hash == hash_mirror && strcmp(tok, "mirror") == 0)) {
+ if(unlikely(!web_client_can_access_netdataconf(w)))
+ return web_client_permission_denied(w);
+
debug(D_WEB_CLIENT_ACCESS, "%llu: Mirroring...", w->id);
// replace the zero bytes with spaces
@@ -1189,10 +1287,20 @@ void web_client_process_request(struct web_client *w) {
case HTTP_VALIDATION_OK:
switch(w->mode) {
case WEB_CLIENT_MODE_STREAM:
+ if(unlikely(!web_client_can_access_stream(w))) {
+ web_client_permission_denied(w);
+ return;
+ }
+
w->response.code = rrdpush_receiver_thread_spawn(localhost, w, w->decoded_url);
return;
case WEB_CLIENT_MODE_OPTIONS:
+ if(unlikely(!web_client_can_access_dashboard(w) && !web_client_can_access_registry(w) && !web_client_can_access_badges(w))) {
+ web_client_permission_denied(w);
+ return;
+ }
+
w->response.data->contenttype = CT_TEXT_PLAIN;
buffer_flush(w->response.data);
buffer_strcat(w->response.data, "OK");
@@ -1201,6 +1309,11 @@ void web_client_process_request(struct web_client *w) {
case WEB_CLIENT_MODE_FILECOPY:
case WEB_CLIENT_MODE_NORMAL:
+ if(unlikely(!web_client_can_access_dashboard(w) && !web_client_can_access_registry(w) && !web_client_can_access_badges(w))) {
+ web_client_permission_denied(w);
+ return;
+ }
+
w->response.code = web_client_process_url(localhost, w, w->decoded_url);
break;
}
@@ -1607,8 +1720,6 @@ void *web_client_main(void *ptr)
int retval, timeout;
nfds_t fdmax = 0;
- log_access("%llu: %s port %s connected on thread task id %d", w->id, w->client_ip, w->client_port, gettid());
-
for(;;) {
if(unlikely(netdata_exit)) break;
@@ -1716,9 +1827,11 @@ void *web_client_main(void *ptr)
}
}
+ if(w->mode != WEB_CLIENT_MODE_STREAM)
+ log_connection(w, "DISCONNECTED");
+
web_client_reset(w);
- log_access("%llu: %s port %s disconnected from thread task id %d", w->id, w->client_ip, w->client_port, gettid());
debug(D_WEB_CLIENT, "%llu: done...", w->id);
// close the sockets/files now
diff --git a/src/web_client.h b/src/web_client.h
index 126a494f..a07558e1 100644
--- a/src/web_client.h
+++ b/src/web_client.h
@@ -44,7 +44,7 @@ typedef enum web_client_flags {
//#define web_client_flag_set(w, flag) __atomic_or_fetch(&((w)->flags), flag, __ATOMIC_SEQ_CST)
//#define web_client_flag_clear(w, flag) __atomic_and_fetch(&((w)->flags), ~flag, __ATOMIC_SEQ_CST)
//#else
-#define web_client_flag_check(w, flag) ((w)->flags & flag)
+#define web_client_flag_check(w, flag) ((w)->flags & (flag))
#define web_client_flag_set(w, flag) (w)->flags |= flag
#define web_client_flag_clear(w, flag) (w)->flags &= ~flag
//#endif
@@ -77,6 +77,7 @@ typedef enum web_client_flags {
#define web_client_set_tcp(w) web_client_flag_set(w, WEB_CLIENT_FLAG_TCP_CLIENT)
#define web_client_set_unix(w) web_client_flag_set(w, WEB_CLIENT_FLAG_UNIX_CLIENT)
+#define web_client_check_unix(w) web_client_flag_check(w, WEB_CLIENT_FLAG_UNIX_CLIENT)
#define web_client_is_corkable(w) web_client_flag_check(w, WEB_CLIENT_FLAG_TCP_CLIENT)
@@ -107,11 +108,30 @@ struct response {
};
+typedef enum web_client_acl {
+ WEB_CLIENT_ACL_NONE = 0,
+ WEB_CLIENT_ACL_NOCHECK = 0,
+ WEB_CLIENT_ACL_DASHBOARD = 1 << 0,
+ WEB_CLIENT_ACL_REGISTRY = 1 << 1,
+ WEB_CLIENT_ACL_BADGE = 1 << 2
+} WEB_CLIENT_ACL;
+
+#define web_client_can_access_dashboard(w) ((w)->acl & WEB_CLIENT_ACL_DASHBOARD)
+#define web_client_can_access_registry(w) ((w)->acl & WEB_CLIENT_ACL_REGISTRY)
+#define web_client_can_access_badges(w) ((w)->acl & WEB_CLIENT_ACL_BADGE)
+
+#define web_client_can_access_stream(w) \
+ (!web_allow_streaming_from || simple_pattern_matches(web_allow_streaming_from, (w)->client_ip))
+
+#define web_client_can_access_netdataconf(w) \
+ (!web_allow_netdataconf_from || simple_pattern_matches(web_allow_netdataconf_from, (w)->client_ip))
+
struct web_client {
unsigned long long id;
WEB_CLIENT_FLAGS flags; // status flags for the client
WEB_CLIENT_MODE mode; // the operational mode of the client
+ WEB_CLIENT_ACL acl; // the access list of the client
int tcp_cork; // 1 = we have a cork on the socket
@@ -142,10 +162,18 @@ struct web_client {
};
extern struct web_client *web_clients;
+extern SIMPLE_PATTERN *web_allow_connections_from;
+extern SIMPLE_PATTERN *web_allow_dashboard_from;
+extern SIMPLE_PATTERN *web_allow_registry_from;
+extern SIMPLE_PATTERN *web_allow_badges_from;
+extern SIMPLE_PATTERN *web_allow_streaming_from;
+extern SIMPLE_PATTERN *web_allow_netdataconf_from;
extern uid_t web_files_uid(void);
extern uid_t web_files_gid(void);
+extern int web_client_permission_denied(struct web_client *w);
+
extern struct web_client *web_client_create(int listener);
extern struct web_client *web_client_free(struct web_client *w);
extern ssize_t web_client_send(struct web_client *w);
diff --git a/src/web_server.c b/src/web_server.c
index 72168d15..d231cbb5 100644
--- a/src/web_server.c
+++ b/src/web_server.c
@@ -168,6 +168,11 @@ void *socket_listen_main_multi_threaded(void *ptr) {
continue;
}
+ if(api_sockets.fds_families[i] == AF_UNIX)
+ web_client_set_unix(w);
+ else
+ web_client_set_tcp(w);
+
if(pthread_create(&w->thread, NULL, web_client_main, w) != 0) {
error("%llu: failed to create new thread for web client.", w->id);
WEB_CLIENT_IS_OBSOLETE(w);
@@ -203,8 +208,8 @@ static inline int single_threaded_link_client(struct web_client *w, fd_set *ifds
if(unlikely(web_client_check_obsolete(w) || web_client_check_dead(w) || (!web_client_has_wait_receive(w) && !web_client_has_wait_send(w))))
return 1;
- if(unlikely(w->ifd < 0 || w->ifd >= FD_SETSIZE || w->ofd < 0 || w->ofd >= FD_SETSIZE)) {
- error("%llu: invalid file descriptor, ifd = %d, ofd = %d (required 0 <= fd < FD_SETSIZE (%d)", w->id, w->ifd, w->ofd, FD_SETSIZE);
+ if(unlikely(w->ifd < 0 || w->ifd >= (int)FD_SETSIZE || w->ofd < 0 || w->ofd >= (int)FD_SETSIZE)) {
+ error("%llu: invalid file descriptor, ifd = %d, ofd = %d (required 0 <= fd < FD_SETSIZE (%d)", w->id, w->ifd, w->ofd, (int)FD_SETSIZE);
return 1;
}
@@ -261,7 +266,7 @@ void *socket_listen_main_single_threaded(void *ptr) {
fatal("LISTENER: no listen sockets available.");
size_t i;
- for(i = 0; i < FD_SETSIZE ; i++)
+ for(i = 0; i < (size_t)FD_SETSIZE ; i++)
single_threaded_clients[i] = NULL;
fd_set ifds, ofds, efds, rifds, rofds, refds;
@@ -271,7 +276,7 @@ void *socket_listen_main_single_threaded(void *ptr) {
int fdmax = 0;
for(i = 0; i < api_sockets.opened ; i++) {
- if (api_sockets.fds[i] < 0 || api_sockets.fds[i] >= FD_SETSIZE)
+ if (api_sockets.fds[i] < 0 || api_sockets.fds[i] >= (int)FD_SETSIZE)
fatal("LISTENER: Listen socket %d is not ready, or invalid.", api_sockets.fds[i]);
info("Listening on '%s'", (api_sockets.fds_names[i])?api_sockets.fds_names[i]:"UNKNOWN");
@@ -372,3 +377,142 @@ void *socket_listen_main_single_threaded(void *ptr) {
pthread_exit(NULL);
return NULL;
}
+
+
+#if 0
+// new TCP client connected
+static void *web_server_add_callback(int fd, int socktype, short int *events) {
+ (void)fd;
+ (void)socktype;
+
+ *events = POLLIN;
+
+ debug(D_WEB_CLIENT_ACCESS, "LISTENER on %d: new connection.", fd);
+ struct web_client *w = web_client_create(fd);
+
+ if(unlikely(socktype == AF_UNIX))
+ web_client_set_unix(w);
+ else
+ web_client_set_tcp(w);
+
+ return (void *)w;
+}
+
+// TCP client disconnected
+static void web_server_del_callback(int fd, int socktype, void *data) {
+ (void)fd;
+ (void)socktype;
+
+ struct web_client *w = (struct web_client *)data;
+
+ if(w) {
+ if(w->ofd == -1 || fd == w->ofd) {
+ // we free the client, only if the closing fd
+ // is the client socket
+ web_client_free(w);
+ }
+ }
+
+ return;
+}
+
+// Receive data
+static int web_server_rcv_callback(int fd, int socktype, void *data, short int *events) {
+ (void)fd;
+ (void)socktype;
+
+ *events = 0;
+
+ struct web_client *w = (struct web_client *)data;
+
+ if(unlikely(!web_client_has_wait_receive(w)))
+ return -1;
+
+ if(unlikely(web_client_receive(w) < 0))
+ return -1;
+
+ if(unlikely(w->mode == WEB_CLIENT_MODE_FILECOPY)) {
+ if(unlikely(w->ifd != -1 && w->ifd != fd)) {
+ // FIXME: we switched input fd
+ // add a new socket to poll_events, with the same
+ }
+ else if(unlikely(w->ifd == -1)) {
+ // FIXME: we closed input fd
+ // instruct poll_events() to close fd
+ return -1;
+ }
+ }
+ else {
+ debug(D_WEB_CLIENT, "%llu: Processing received data.", w->id);
+ web_client_process_request(w);
+ }
+
+ if(unlikely(w->ifd == fd && web_client_has_wait_receive(w)))
+ *events |= POLLIN;
+
+ if(unlikely(w->ofd == fd && web_client_has_wait_send(w)))
+ *events |= POLLOUT;
+
+ if(unlikely(*events == 0))
+ return -1;
+
+ return 0;
+}
+
+static int web_server_snd_callback(int fd, int socktype, void *data, short int *events) {
+ (void)fd;
+ (void)socktype;
+
+ struct web_client *w = (struct web_client *)data;
+
+ if(unlikely(!web_client_has_wait_send(w)))
+ return -1;
+
+ if(unlikely(web_client_send(w) < 0))
+ return -1;
+
+ if(unlikely(w->ifd == fd && web_client_has_wait_receive(w)))
+ *events |= POLLIN;
+
+ if(unlikely(w->ofd == fd && web_client_has_wait_send(w)))
+ *events |= POLLOUT;
+
+ if(unlikely(*events == 0))
+ return -1;
+
+ return 0;
+}
+
+void *socket_listen_main_single_threaded(void *ptr) {
+ struct netdata_static_thread *static_thread = (struct netdata_static_thread *)ptr;
+
+ web_server_mode = WEB_SERVER_MODE_SINGLE_THREADED;
+
+ info("Single-threaded WEB SERVER thread created with task id %d", gettid());
+
+ if(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) != 0)
+ error("Cannot set pthread cancel type to DEFERRED.");
+
+ if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0)
+ error("Cannot set pthread cancel state to ENABLE.");
+
+ if(!api_sockets.opened)
+ fatal("LISTENER: no listen sockets available.");
+
+ poll_events(&api_sockets
+ , web_server_add_callback
+ , web_server_del_callback
+ , web_server_rcv_callback
+ , web_server_snd_callback
+ , web_allow_connections_from
+ , NULL
+ );
+
+ debug(D_WEB_CLIENT, "LISTENER: exit!");
+ listen_sockets_close(&api_sockets);
+
+ static_thread->enabled = 0;
+ pthread_exit(NULL);
+ return NULL;
+}
+#endif
diff --git a/src/zfs_common.c b/src/zfs_common.c
index 7fa05b03..0915416f 100644
--- a/src/zfs_common.c
+++ b/src/zfs_common.c
@@ -1,9 +1,9 @@
#include "common.h"
#include "zfs_common.h"
-extern struct arcstats arcstats;
+struct arcstats arcstats = { 0 };
-void generate_charts_arcstats(int update_every) {
+void generate_charts_arcstats(const char *plugin, int update_every) {
// ARC reads
unsigned long long aread = arcstats.hits + arcstats.misses;
@@ -24,8 +24,8 @@ void generate_charts_arcstats(int update_every) {
unsigned long long mread = mhit + mmiss;
// l2 reads
- unsigned long long l2hit = arcstats.l2_hits + arcstats.l2_misses;
- unsigned long long l2miss = arcstats.prefetch_metadata_misses + arcstats.demand_metadata_misses;
+ unsigned long long l2hit = arcstats.l2_hits;
+ unsigned long long l2miss = arcstats.l2_misses;
unsigned long long l2read = l2hit + l2miss;
// --------------------------------------------------------------------
@@ -46,6 +46,8 @@ void generate_charts_arcstats(int update_every) {
, NULL
, "ZFS ARC Size"
, "MB"
+ , plugin
+ , "zfs"
, 2000
, update_every
, RRDSET_TYPE_AREA
@@ -68,7 +70,7 @@ void generate_charts_arcstats(int update_every) {
// --------------------------------------------------------------------
- if(likely(l2exist)) {
+ if(likely(arcstats.l2exist)) {
static RRDSET *st_l2_size = NULL;
static RRDDIM *rd_l2_size = NULL;
static RRDDIM *rd_l2_asize = NULL;
@@ -82,6 +84,8 @@ void generate_charts_arcstats(int update_every) {
, NULL
, "ZFS L2 ARC Size"
, "MB"
+ , plugin
+ , "zfs"
, 2000
, update_every
, RRDSET_TYPE_AREA
@@ -117,6 +121,8 @@ void generate_charts_arcstats(int update_every) {
, NULL
, "ZFS Reads"
, "reads/s"
+ , plugin
+ , "zfs"
, 2010
, update_every
, RRDSET_TYPE_AREA
@@ -127,7 +133,7 @@ void generate_charts_arcstats(int update_every) {
rd_pread = rrddim_add(st_reads, "preads", "prefetch", 1, 1, RRD_ALGORITHM_INCREMENTAL);
rd_mread = rrddim_add(st_reads, "mreads", "metadata", 1, 1, RRD_ALGORITHM_INCREMENTAL);
- if(l2exist)
+ if(arcstats.l2exist)
rd_l2read = rrddim_add(st_reads, "l2reads", "l2", 1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else
@@ -138,7 +144,7 @@ void generate_charts_arcstats(int update_every) {
rrddim_set_by_pointer(st_reads, rd_pread, pread);
rrddim_set_by_pointer(st_reads, rd_mread, mread);
- if(l2exist)
+ if(arcstats.l2exist)
rrddim_set_by_pointer(st_reads, rd_l2read, l2read);
rrdset_done(st_reads);
@@ -146,7 +152,7 @@ void generate_charts_arcstats(int update_every) {
// --------------------------------------------------------------------
- if(likely(l2exist)) {
+ if(likely(arcstats.l2exist)) {
static RRDSET *st_l2bytes = NULL;
static RRDDIM *rd_l2_read_bytes = NULL;
static RRDDIM *rd_l2_write_bytes = NULL;
@@ -160,6 +166,8 @@ void generate_charts_arcstats(int update_every) {
, NULL
, "ZFS ARC L2 Read/Write Rate"
, "kilobytes/s"
+ , plugin
+ , "zfs"
, 2200
, update_every
, RRDSET_TYPE_AREA
@@ -192,6 +200,8 @@ void generate_charts_arcstats(int update_every) {
, NULL
, "ZFS ARC Hits"
, "percentage"
+ , plugin
+ , "zfs"
, 2020
, update_every
, RRDSET_TYPE_STACKED
@@ -224,6 +234,8 @@ void generate_charts_arcstats(int update_every) {
, NULL
, "ZFS Demand Hits"
, "percentage"
+ , plugin
+ , "zfs"
, 2030
, update_every
, RRDSET_TYPE_STACKED
@@ -256,6 +268,8 @@ void generate_charts_arcstats(int update_every) {
, NULL
, "ZFS Prefetch Hits"
, "percentage"
+ , plugin
+ , "zfs"
, 2040
, update_every
, RRDSET_TYPE_STACKED
@@ -288,6 +302,8 @@ void generate_charts_arcstats(int update_every) {
, NULL
, "ZFS Metadata Hits"
, "percentage"
+ , plugin
+ , "zfs"
, 2050
, update_every
, RRDSET_TYPE_STACKED
@@ -306,7 +322,7 @@ void generate_charts_arcstats(int update_every) {
// --------------------------------------------------------------------
- if(likely(l2exist)) {
+ if(likely(arcstats.l2exist)) {
static RRDSET *st_l2hits = NULL;
static RRDDIM *rd_l2hits = NULL;
static RRDDIM *rd_l2misses = NULL;
@@ -320,6 +336,8 @@ void generate_charts_arcstats(int update_every) {
, NULL
, "ZFS L2 Hits"
, "percentage"
+ , plugin
+ , "zfs"
, 2060
, update_every
, RRDSET_TYPE_STACKED
@@ -354,6 +372,8 @@ void generate_charts_arcstats(int update_every) {
, NULL
, "ZFS List Hits"
, "hits/s"
+ , plugin
+ , "zfs"
, 2100
, update_every
, RRDSET_TYPE_AREA
@@ -375,7 +395,7 @@ void generate_charts_arcstats(int update_every) {
}
}
-void generate_charts_arc_summary(int update_every) {
+void generate_charts_arc_summary(const char *plugin, int update_every) {
unsigned long long arc_accesses_total = arcstats.hits + arcstats.misses;
unsigned long long real_hits = arcstats.mfu_hits + arcstats.mru_hits;
unsigned long long real_misses = arc_accesses_total - real_hits;
@@ -411,6 +431,8 @@ void generate_charts_arc_summary(int update_every) {
, NULL
, "ZFS ARC Size Breakdown"
, "percentage"
+ , plugin
+ , "zfs"
, 2020
, update_every
, RRDSET_TYPE_STACKED
@@ -448,6 +470,8 @@ void generate_charts_arc_summary(int update_every) {
, NULL
, "ZFS Memory Operations"
, "operations/s"
+ , plugin
+ , "zfs"
, 2023
, update_every
, RRDSET_TYPE_LINE
@@ -492,6 +516,8 @@ void generate_charts_arc_summary(int update_every) {
, NULL
, "ZFS Important Operations"
, "operations/s"
+ , plugin
+ , "zfs"
, 2022
, update_every
, RRDSET_TYPE_LINE
@@ -528,6 +554,8 @@ void generate_charts_arc_summary(int update_every) {
, NULL
, "ZFS Actual Cache Hits"
, "percentage"
+ , plugin
+ , "zfs"
, 2019
, update_every
, RRDSET_TYPE_STACKED
@@ -560,6 +588,8 @@ void generate_charts_arc_summary(int update_every) {
, NULL
, "ZFS Data Demand Efficiency"
, "percentage"
+ , plugin
+ , "zfs"
, 2031
, update_every
, RRDSET_TYPE_STACKED
@@ -592,6 +622,8 @@ void generate_charts_arc_summary(int update_every) {
, NULL
, "ZFS Data Prefetch Efficiency"
, "percentage"
+ , plugin
+ , "zfs"
, 2032
, update_every
, RRDSET_TYPE_STACKED
@@ -624,6 +656,8 @@ void generate_charts_arc_summary(int update_every) {
, NULL
, "ZFS ARC Hash Elements"
, "elements"
+ , plugin
+ , "zfs"
, 2300
, update_every
, RRDSET_TYPE_LINE
@@ -656,6 +690,8 @@ void generate_charts_arc_summary(int update_every) {
, NULL
, "ZFS ARC Hash Chains"
, "chains"
+ , plugin
+ , "zfs"
, 2310
, update_every
, RRDSET_TYPE_LINE
diff --git a/src/zfs_common.h b/src/zfs_common.h
index 9d3aa7df..4494e70c 100644
--- a/src/zfs_common.h
+++ b/src/zfs_common.h
@@ -8,6 +8,7 @@
#define ZFS_FAMILY_HASH "hashes"
struct arcstats {
+ // values
unsigned long long hits;
unsigned long long misses;
unsigned long long demand_data_hits;
@@ -99,11 +100,12 @@ struct arcstats {
unsigned long long arc_meta_min;
unsigned long long arc_need_free;
unsigned long long arc_sys_free;
-};
-int l2exist;
+ // flags
+ int l2exist;
+};
-void generate_charts_arcstats(int update_every);
-void generate_charts_arc_summary(int update_every);
+void generate_charts_arcstats(const char *plugin, int update_every);
+void generate_charts_arc_summary(const char *plugin, int update_every);
#endif //NETDATA_ZFS_COMMON_H