]> arthur.barton.de Git - netdata.git/commitdiff
allow certain paths to be excluded from disk space statistics; fixes #1206
authorCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Sat, 5 Nov 2016 01:42:00 +0000 (03:42 +0200)
committerCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Sat, 5 Nov 2016 01:42:00 +0000 (03:42 +0200)
src/proc_diskstats.c

index 1cd4f30d1b0bfd96c53794bebc7e4ff4333a53ed..3330a830c3219ed9ab6f9636a6e3e2ecdf30fbe3 100644 (file)
@@ -56,10 +56,88 @@ 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", "/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(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 {
+    int do_space;
+    int do_inodes;
+};
+
 static inline void do_disk_space_stats(struct disk *d, const char *mount_point, const char *mount_source, const char *disk, const char *family, int update_every, unsigned long long dt) {
+    static DICTIONARY *mount_points = NULL;
     int do_space, do_inodes;
 
-    if(d) {
+    if(unlikely(!mount_points)) {
+        mount_points = dictionary_create(DICTIONARY_FLAG_SINGLE_THREADED);
+    }
+
+    if(unlikely(d)) {
         // verify we collected the metrics for the right disk.
         // if not the mountpoint has changed.
 
@@ -80,19 +158,33 @@ static inline void do_disk_space_stats(struct disk *d, const char *mount_point,
         do_inodes = d->do_inodes;
     }
     else {
-        char var_name[4096 + 1];
-        snprintfz(var_name, 4096, "plugin:proc:/proc/diskstats:%s", mount_point);
+        struct mount_point_metadata *m = dictionary_get(mount_points, mount_point);
+        if(!m) {
+            char var_name[4096 + 1];
+            snprintfz(var_name, 4096, "plugin:proc:/proc/diskstats:%s", mount_point);
 
-        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);
+            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(strncmp(mount_point, "/run/user/", 10) == 0)) {
-            def_space = CONFIG_ONDEMAND_NO;
-            def_inodes = CONFIG_ONDEMAND_NO;
-        }
+            if(is_mount_point_excluded(mount_point)) {
+                def_space = CONFIG_ONDEMAND_NO;
+                def_inodes = CONFIG_ONDEMAND_NO;
+            }
 
-        do_space = config_get_boolean_ondemand(var_name, "space usage", def_space);
-        do_inodes = config_get_boolean_ondemand(var_name, "inodes usage", def_inodes);
+            do_space = config_get_boolean_ondemand(var_name, "space usage", def_space);
+            do_inodes = config_get_boolean_ondemand(var_name, "inodes usage", def_inodes);
+
+            struct mount_point_metadata mp = {
+                .do_space = do_space,
+                .do_inodes = do_inodes
+            };
+
+            dictionary_set(mount_points, mount_point, &mp, sizeof(struct mount_point_metadata));
+        }
+        else {
+            do_space = m->do_space;
+            do_inodes = m->do_inodes;
+        }
     }
 
     if(do_space == CONFIG_ONDEMAND_NO && do_inodes == CONFIG_ONDEMAND_NO)