]> arthur.barton.de Git - netdata.git/commitdiff
allow any pattern of network interfaces and disk paths to be excluded; fixes #1556...
authorCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Sat, 14 Jan 2017 00:42:17 +0000 (02:42 +0200)
committerCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Sat, 14 Jan 2017 00:42:17 +0000 (02:42 +0200)
src/common.c
src/common.h
src/plugin_proc.c
src/proc_diskstats.c
src/proc_net_dev.c

index 36fa0c9be53468ff5cea44affbf86149da8b4422..8abd2d447ba44213981a029a50882936a5c620de 100644 (file)
@@ -1187,3 +1187,128 @@ int read_single_number_file(const char *filename, unsigned long long *result) {
     *result = strtoull(buffer, NULL, 0);
     return 0;
 }
+
+// ----------------------------------------------------------------------------
+// simple_pattern_match
+
+struct simple_pattern {
+    const char *match;
+    size_t len;
+    NETDATA_SIMPLE_PREFIX_MODE mode;
+    struct simple_pattern *next;
+};
+
+NETDATA_SIMPLE_PATTERN *netdata_simple_pattern_list_create(const char *list, NETDATA_SIMPLE_PREFIX_MODE default_mode) {
+    struct simple_pattern *root = NULL;
+
+    if(unlikely(!list || !*list)) return root;
+
+    char *a = strdupz(list);
+    if(a && *a) {
+        char *s = a;
+
+        while(s && *s) {
+            // skip all spaces
+            while(isspace(*s)) s++;
+
+            // empty string
+            if(unlikely(!*s)) break;
+
+            // find the next space
+            char *c = s;
+            while(*c && !isspace(*c)) c++;
+
+            // find the next word
+            char *n;
+            if(likely(*c)) n = c + 1;
+            else n = NULL;
+
+            // terminate our string
+            *c = '\0';
+
+            char buf[100 + 1];
+            strncpy(buf, s, 100);
+            buf[100] = '\0';
+            if(likely(n)) *c = ' ';
+            s = buf;
+
+            NETDATA_SIMPLE_PREFIX_MODE mode;
+            size_t len = strlen(s);
+            if(len >= 2 && *s == '*' && s[len - 1] == '*') {
+                s[len - 1] = '\0';
+                s++;
+                len -= 2;
+                mode = NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING;
+            }
+            else if(len >= 1 && *s == '*') {
+                s++;
+                len--;
+                mode = NETDATA_SIMPLE_PATTERN_MODE_SUFFIX;
+            }
+            else if(len >= 1 && s[len - 1] == '*') {
+                s[len - 1] = '\0';
+                len--;
+                mode = NETDATA_SIMPLE_PATTERN_MODE_PREFIX;
+            }
+            else
+                mode = default_mode;
+
+            if(len) {
+                if(*s == '*')
+                    error("simple pattern '%s' includes '%s' that is invalid", a, s);
+
+                // allocate the structure
+                struct simple_pattern *m = mallocz(sizeof(struct simple_pattern));
+                m->match = strdup(s);
+                m->len = strlen(m->match);
+                m->mode = mode;
+                m->next = root;
+                root = m;
+            }
+            else
+                error("simple pattern '%s' includes invalid matches", a);
+
+            // prepare for next loop
+            s = n;
+        }
+    }
+
+    free(a);
+    return (NETDATA_SIMPLE_PATTERN *)root;
+}
+
+int netdata_simple_pattern_list_matches(NETDATA_SIMPLE_PATTERN *list, const char *str) {
+    struct simple_pattern *m, *root = (struct simple_pattern *)list;
+
+    if(unlikely(!root)) return 0;
+
+    size_t len = strlen(str);
+    for(m = root; m ; m = m->next) {
+        if(m->len <= len) {
+            switch(m->mode) {
+                case NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING:
+                    if(unlikely(strstr(str, m->match)))
+                        return 1;
+                    break;
+
+                case NETDATA_SIMPLE_PATTERN_MODE_PREFIX:
+                    if(unlikely(strncmp(str, m->match, m->len) == 0))
+                        return 1;
+                    break;
+
+                case NETDATA_SIMPLE_PATTERN_MODE_SUFFIX:
+                    if(unlikely(strcmp(&str[len - m->len], m->match) == 0))
+                        return 1;
+                    break;
+
+                case NETDATA_SIMPLE_PATTERN_MODE_EXACT:
+                default:
+                    if(unlikely(strcmp(str, m->match) == 0))
+                        return 1;
+                    break;
+            }
+        }
+    }
+
+    return 0;
+}
index 48b7c311670d37eaa57b68439ff0933ab33f0432..de4ff7a5d89190d06b3cccc950f50ee71e906760 100644 (file)
@@ -277,4 +277,14 @@ extern void get_system_HZ(void);
 
 extern int read_single_number_file(const char *filename, unsigned long long *result);
 
+typedef enum {
+    NETDATA_SIMPLE_PATTERN_MODE_EXACT,
+    NETDATA_SIMPLE_PATTERN_MODE_PREFIX,
+    NETDATA_SIMPLE_PATTERN_MODE_SUFFIX,
+    NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING
+} NETDATA_SIMPLE_PREFIX_MODE;
+typedef void NETDATA_SIMPLE_PATTERN;
+extern NETDATA_SIMPLE_PATTERN *netdata_simple_pattern_list_create(const char *list, NETDATA_SIMPLE_PREFIX_MODE default_mode);
+extern int netdata_simple_pattern_list_matches(NETDATA_SIMPLE_PATTERN *list, const char *str);
+
 #endif /* NETDATA_COMMON_H */
index 260252b1e1c0d054e34af59f600e9493dbbec794..9b99d82e1d15a79bbd762a38266f924c65683340 100644 (file)
@@ -68,12 +68,7 @@ void *proc_main(void *ptr)
     if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0)
         error("Cannot set pthread cancel state to ENABLE.");
 
-    // disable (by default) various interface that are not needed
-    config_get_boolean("plugin:proc:/proc/net/dev:lo", "enabled", 0);
-    config_get_boolean("plugin:proc:/proc/net/dev:fireqos_monitor", "enabled", 0);
-
-    // when ZERO, attempt to do it
-    int vdo_cpu_netdata             = !config_get_boolean("plugin:proc", "netdata server resources", 1);
+    int vdo_cpu_netdata = config_get_boolean("plugin:proc", "netdata server resources", 1);
 
     // check the enabled status for each module
     int i;
@@ -116,7 +111,7 @@ void *proc_main(void *ptr)
 
         // --------------------------------------------------------------------
 
-        if(!vdo_cpu_netdata) {
+        if(vdo_cpu_netdata) {
             static RRDSET *st = NULL;
             if(unlikely(!st)) {
                 st = rrdset_find_bytype("netdata", "plugin_proc_modules");
index f768f97441643b615ac9aa747bcdc9ad053713b2..574470dc86b501c3396eed7762ab896c4bb71ead 100644 (file)
@@ -54,71 +54,6 @@ static inline void mountinfo_reload(int force) {
 }
 
 
-// linked list of mount points that are by default disabled
-static struct excluded_mount_point {
-    const char *prefix;
-    size_t len;
-    struct excluded_mount_point *next;
-} *excluded_mount_points = NULL;
-
-static inline int is_mount_point_excluded(const char *mount_point) {
-    static int initialized = 0;
-
-    if(unlikely(!initialized)) {
-        initialized = 1;
-
-        char *a = config_get("plugin:proc:/proc/diskstats", "exclude space metrics on paths", "/proc/ /sys/ /var/run/user/ /run/user/");
-        if(a && *a) {
-            char *s = a;
-
-            while(s && *s) {
-                // skip all spaces
-                while(isspace(*s)) s++;
-
-                // empty string
-                if(unlikely(!*s)) break;
-
-                // find the next space
-                char *c = s;
-                while(*c && !isspace(*c)) c++;
-
-                char *n;
-                if(likely(*c)) n = c + 1;
-                else n = NULL;
-
-                // terminate our string
-                *c = '\0';
-
-                // allocate the structure
-                struct excluded_mount_point *m = mallocz(sizeof(struct excluded_mount_point));
-                m->prefix = strdup(s);
-                m->len = strlen(m->prefix);
-                m->next = excluded_mount_points;
-                excluded_mount_points = m;
-
-                // prepare for next loop
-                s = n;
-                if(likely(n)) *c = ' ';
-            }
-        }
-    }
-
-    size_t len = strlen(mount_point);
-    struct excluded_mount_point *m;
-    for(m = excluded_mount_points; m ; m = m->next) {
-        if(m->len <= len) {
-            // fprintf(stderr, "SPACE: comparing '%s' with '%s'\n", mount_point, m->prefix);
-            if(unlikely(strncmp(m->prefix, mount_point, m->len) == 0)) {
-                // fprintf(stderr, "SPACE: excluded '%s'\n", mount_point);
-                return 1;
-            }
-        }
-    }
-
-    // fprintf(stderr, "SPACE: included '%s'\n", mount_point);
-    return 0;
-}
-
 // Data to be stored in DICTIONARY mount_points used by do_disk_space_stats().
 // This DICTIONARY is used to lookup the settings of the mount point on each iteration.
 struct mount_point_metadata {
@@ -133,10 +68,12 @@ static inline void do_disk_space_stats(struct mountinfo *mi, int update_every, u
     const char *disk = mi->persistent_id;
 
     static DICTIONARY *mount_points = NULL;
+    static NETDATA_SIMPLE_PATTERN *excluded_mountpoints = NULL;
     int do_space, do_inodes;
 
     if(unlikely(!mount_points)) {
         mount_points = dictionary_create(DICTIONARY_FLAG_SINGLE_THREADED);
+        excluded_mountpoints = netdata_simple_pattern_list_create(config_get("plugin:proc:/proc/diskstats", "exclude space metrics on paths", "/proc/ /sys/ /var/run/user/ /run/user/"), NETDATA_SIMPLE_PATTERN_MODE_PREFIX);
     }
 
     struct mount_point_metadata *m = dictionary_get(mount_points, mi->mount_point);
@@ -147,7 +84,7 @@ static inline void do_disk_space_stats(struct mountinfo *mi, int update_every, u
         int def_space = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "space usage for all disks", CONFIG_ONDEMAND_ONDEMAND);
         int def_inodes = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "inodes usage for all disks", CONFIG_ONDEMAND_ONDEMAND);
 
-        if(unlikely(is_mount_point_excluded(mi->mount_point))) {
+        if(unlikely(netdata_simple_pattern_list_matches(excluded_mountpoints, mi->mount_point))) {
             def_space = CONFIG_ONDEMAND_NO;
             def_inodes = CONFIG_ONDEMAND_NO;
         }
index 99c77cd1ba398b58cb261e0acd1e3860c89b00f5..e0242fcc4632f1dae22691e3781bfa7ec39b1838 100644 (file)
@@ -112,14 +112,13 @@ static struct netdev *get_netdev(const char *name) {
 int do_proc_net_dev(int update_every, usec_t dt) {
     (void)dt;
 
+    static NETDATA_SIMPLE_PATTERN *disabled_list = NULL;
     static procfile *ff = NULL;
-    static int enable_new_interfaces = -1, enable_ifb_interfaces = -1, enable_veth_interfaces = -1;
+    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;
 
     if(unlikely(enable_new_interfaces == -1)) {
         enable_new_interfaces = config_get_boolean_ondemand("plugin:proc:/proc/net/dev", "enable new interfaces detected at runtime", CONFIG_ONDEMAND_ONDEMAND);
-        enable_ifb_interfaces = config_get_boolean_ondemand("plugin:proc:/proc/net/dev", "enable ifb interfaces", CONFIG_ONDEMAND_NO);
-        enable_veth_interfaces = config_get_boolean_ondemand("plugin:proc:/proc/net/dev", "enable veth interfaces", enable_new_interfaces);
 
         do_bandwidth    = config_get_boolean_ondemand("plugin:proc:/proc/net/dev", "bandwidth for all interfaces", CONFIG_ONDEMAND_ONDEMAND);
         do_packets      = config_get_boolean_ondemand("plugin:proc:/proc/net/dev", "packets for all interfaces", CONFIG_ONDEMAND_ONDEMAND);
@@ -128,6 +127,8 @@ int do_proc_net_dev(int update_every, usec_t dt) {
         do_fifo         = config_get_boolean_ondemand("plugin:proc:/proc/net/dev", "fifo for all interfaces", CONFIG_ONDEMAND_ONDEMAND);
         do_compressed   = config_get_boolean_ondemand("plugin:proc:/proc/net/dev", "compressed packets for all interfaces", CONFIG_ONDEMAND_ONDEMAND);
         do_events       = config_get_boolean_ondemand("plugin:proc:/proc/net/dev", "frames, collisions, carrier counters for all interfaces", CONFIG_ONDEMAND_ONDEMAND);
+
+        disabled_list = netdata_simple_pattern_list_create(config_get("plugin:proc:/proc/net/dev", "disable by default interfaces matching", "lo fireqos* *-ifb"), NETDATA_SIMPLE_PATTERN_MODE_EXACT);
     }
 
     if(unlikely(!ff)) {
@@ -153,16 +154,10 @@ int do_proc_net_dev(int update_every, usec_t dt) {
             // remember we configured it
             d->configured = 1;
 
-            // start with the default enabled flag
             d->enabled = enable_new_interfaces;
-            if(d->enabled) {
-                if(unlikely(!strcmp(d->name, "lo")))
-                    d->enabled = CONFIG_ONDEMAND_NO;
-                else if(unlikely(!strncmp(d->name, "veth", 4)))
-                    d->enabled = enable_veth_interfaces;
-                else if(unlikely(d->len >= 4 && strcmp(&d->name[d->len - 4], "-ifb") == 0))
-                    d->enabled = enable_ifb_interfaces;
-            }
+
+            if(d->enabled)
+                d->enabled = !netdata_simple_pattern_list_matches(disabled_list, d->name);
 
             char var_name[512 + 1];
             snprintfz(var_name, 512, "plugin:proc:/proc/net/dev:%s", d->name);