]> arthur.barton.de Git - netdata.git/commitdiff
disk performance metrics optimization and cleanup of removed disks
authorCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Sun, 5 Mar 2017 20:13:56 +0000 (22:13 +0200)
committerCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Sun, 5 Mar 2017 20:13:56 +0000 (22:13 +0200)
src/proc_diskstats.c

index 134e7a1a8d69aba290cc092e521b3a5110709305..7d118be0f3c61ffde7342a2b298f2e9ff7a1cf03 100644 (file)
@@ -25,9 +25,24 @@ static struct disk {
     int do_util;
     int do_backlog;
 
+    int updated;
+
+    RRDSET *st_avgsz;
+    RRDSET *st_await;
+    RRDSET *st_backlog;
+    RRDSET *st_io;
+    RRDSET *st_iotime;
+    RRDSET *st_mops;
+    RRDSET *st_ops;
+    RRDSET *st_qops;
+    RRDSET *st_svctm;
+    RRDSET *st_util;
+
     struct disk *next;
 } *disk_root = NULL;
 
+#define rrdset_obsolete_and_pointer_null(st) do { if(st) { rrdset_flag_set(st, RRDSET_FLAG_OBSOLETE); st = NULL; } } while(st)
+
 static struct disk *get_disk(unsigned long major, unsigned long minor, char *disk) {
     static char path_to_get_hw_sector_size[FILENAME_MAX + 1] = "";
     static char path_to_get_hw_sector_size_partitions[FILENAME_MAX + 1] = "";
@@ -316,7 +331,7 @@ int do_proc_diskstats(int update_every, usec_t dt) {
         // get a disk structure for the disk
 
         struct disk *d = get_disk(major, minor, disk);
-
+        d->updated = 1;
 
         // --------------------------------------------------------------------------
         // Set its family based on mount point
@@ -409,27 +424,34 @@ int do_proc_diskstats(int update_every, usec_t dt) {
             d->configured = 1;
         }
 
-        RRDSET *st;
-
         // --------------------------------------------------------------------------
         // Do performance metrics
 
         if(d->do_io == CONFIG_BOOLEAN_YES || (d->do_io == CONFIG_BOOLEAN_AUTO && (readsectors || writesectors))) {
             d->do_io = CONFIG_BOOLEAN_YES;
 
-            st = rrdset_find_bytype_localhost(RRD_TYPE_DISK, disk);
-            if(unlikely(!st)) {
-                st = rrdset_create_localhost(RRD_TYPE_DISK, disk, NULL, family, "disk.io", "Disk I/O Bandwidth"
-                                             , "kilobytes/s", 2000, update_every, RRDSET_TYPE_AREA);
-
-                rrddim_add(st, "reads", NULL, d->sector_size, 1024, RRD_ALGORITHM_INCREMENTAL);
-                rrddim_add(st, "writes", NULL, d->sector_size * -1, 1024, RRD_ALGORITHM_INCREMENTAL);
+            if(unlikely(!d->st_io)) {
+                d->st_io = rrdset_create_localhost(
+                        RRD_TYPE_DISK
+                        , disk
+                        , NULL
+                        , family
+                        , "disk.io"
+                        , "Disk I/O Bandwidth"
+                        , "kilobytes/s"
+                        , 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);
             }
-            else rrdset_next(st);
+            else rrdset_next(d->st_io);
 
-            last_readsectors  = rrddim_set(st, "reads", readsectors);
-            last_writesectors = rrddim_set(st, "writes", writesectors);
-            rrdset_done(st);
+            last_readsectors  = rrddim_set(d->st_io, "reads", readsectors);
+            last_writesectors = rrddim_set(d->st_io, "writes", writesectors);
+            rrdset_done(d->st_io);
         }
 
         // --------------------------------------------------------------------
@@ -437,20 +459,30 @@ int do_proc_diskstats(int update_every, usec_t dt) {
         if(d->do_ops == CONFIG_BOOLEAN_YES || (d->do_ops == CONFIG_BOOLEAN_AUTO && (reads || writes))) {
             d->do_ops = CONFIG_BOOLEAN_YES;
 
-            st = rrdset_find_bytype_localhost("disk_ops", disk);
-            if(unlikely(!st)) {
-                st = rrdset_create_localhost("disk_ops", disk, NULL, family, "disk.ops", "Disk Completed I/O Operations"
-                                             , "operations/s", 2001, update_every, RRDSET_TYPE_LINE);
-                rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
-
-                rrddim_add(st, "reads", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
-                rrddim_add(st, "writes", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+            if(unlikely(!d->st_ops)) {
+                d->st_ops = rrdset_create_localhost(
+                        "disk_ops"
+                        , disk
+                        , NULL
+                        , family
+                        , "disk.ops"
+                        , "Disk Completed I/O Operations"
+                        , "operations/s"
+                        , 2001
+                        , update_every
+                        , RRDSET_TYPE_LINE
+                );
+
+                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);
             }
-            else rrdset_next(st);
+            else rrdset_next(d->st_ops);
 
-            last_reads  = rrddim_set(st, "reads", reads);
-            last_writes = rrddim_set(st, "writes", writes);
-            rrdset_done(st);
+            last_reads  = rrddim_set(d->st_ops, "reads", reads);
+            last_writes = rrddim_set(d->st_ops, "writes", writes);
+            rrdset_done(d->st_ops);
         }
 
         // --------------------------------------------------------------------
@@ -458,18 +490,28 @@ int do_proc_diskstats(int update_every, usec_t dt) {
         if(d->do_qops == CONFIG_BOOLEAN_YES || (d->do_qops == CONFIG_BOOLEAN_AUTO && queued_ios)) {
             d->do_qops = CONFIG_BOOLEAN_YES;
 
-            st = rrdset_find_bytype_localhost("disk_qops", disk);
-            if(unlikely(!st)) {
-                st = rrdset_create_localhost("disk_qops", disk, NULL, family, "disk.qops", "Disk Current I/O Operations"
-                                             , "operations", 2002, update_every, RRDSET_TYPE_LINE);
-                rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
-
-                rrddim_add(st, "operations", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+            if(unlikely(!d->st_qops)) {
+                d->st_qops = rrdset_create_localhost(
+                        "disk_qops"
+                        , disk
+                        , NULL
+                        , family
+                        , "disk.qops"
+                        , "Disk Current I/O Operations"
+                        , "operations"
+                        , 2002
+                        , update_every
+                        , RRDSET_TYPE_LINE
+                );
+
+                rrdset_flag_set(d->st_qops, RRDSET_FLAG_DETAIL);
+
+                rrddim_add(d->st_qops, "operations", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
             }
-            else rrdset_next(st);
+            else rrdset_next(d->st_qops);
 
-            rrddim_set(st, "operations", queued_ios);
-            rrdset_done(st);
+            rrddim_set(d->st_qops, "operations", queued_ios);
+            rrdset_done(d->st_qops);
         }
 
         // --------------------------------------------------------------------
@@ -477,18 +519,28 @@ int do_proc_diskstats(int update_every, usec_t dt) {
         if(d->do_backlog == CONFIG_BOOLEAN_YES || (d->do_backlog == CONFIG_BOOLEAN_AUTO && backlog_ms)) {
             d->do_backlog = CONFIG_BOOLEAN_YES;
 
-            st = rrdset_find_bytype_localhost("disk_backlog", disk);
-            if(unlikely(!st)) {
-                st = rrdset_create_localhost("disk_backlog", disk, NULL, family, "disk.backlog", "Disk Backlog"
-                                             , "backlog (ms)", 2003, update_every, RRDSET_TYPE_AREA);
-                rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
-
-                rrddim_add(st, "backlog", NULL, 1, 10, RRD_ALGORITHM_INCREMENTAL);
+            if(unlikely(!d->st_backlog)) {
+                d->st_backlog = rrdset_create_localhost(
+                        "disk_backlog"
+                        , disk
+                        , NULL
+                        , family
+                        , "disk.backlog"
+                        , "Disk Backlog"
+                        , "backlog (ms)"
+                        , 2003
+                        , update_every
+                        , RRDSET_TYPE_AREA
+                );
+
+                rrdset_flag_set(d->st_backlog, RRDSET_FLAG_DETAIL);
+
+                rrddim_add(d->st_backlog, "backlog", NULL, 1, 10, RRD_ALGORITHM_INCREMENTAL);
             }
-            else rrdset_next(st);
+            else rrdset_next(d->st_backlog);
 
-            rrddim_set(st, "backlog", backlog_ms);
-            rrdset_done(st);
+            rrddim_set(d->st_backlog, "backlog", backlog_ms);
+            rrdset_done(d->st_backlog);
         }
 
         // --------------------------------------------------------------------
@@ -496,18 +548,28 @@ int do_proc_diskstats(int update_every, usec_t dt) {
         if(d->do_util == CONFIG_BOOLEAN_YES || (d->do_util == CONFIG_BOOLEAN_AUTO && busy_ms)) {
             d->do_util = CONFIG_BOOLEAN_YES;
 
-            st = rrdset_find_bytype_localhost("disk_util", disk);
-            if(unlikely(!st)) {
-                st = rrdset_create_localhost("disk_util", disk, NULL, family, "disk.util", "Disk Utilization Time"
-                                             , "% of time working", 2004, update_every, RRDSET_TYPE_AREA);
-                rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
-
-                rrddim_add(st, "utilization", NULL, 1, 10, RRD_ALGORITHM_INCREMENTAL);
+            if(unlikely(!d->st_util)) {
+                d->st_util = rrdset_create_localhost(
+                        "disk_util"
+                        , disk
+                        , NULL
+                        , family
+                        , "disk.util"
+                        , "Disk Utilization Time"
+                        , "% of time working"
+                        , 2004
+                        , update_every
+                        , RRDSET_TYPE_AREA
+                );
+
+                rrdset_flag_set(d->st_util, RRDSET_FLAG_DETAIL);
+
+                rrddim_add(d->st_util, "utilization", NULL, 1, 10, RRD_ALGORITHM_INCREMENTAL);
             }
-            else rrdset_next(st);
+            else rrdset_next(d->st_util);
 
-            last_busy_ms = rrddim_set(st, "utilization", busy_ms);
-            rrdset_done(st);
+            last_busy_ms = rrddim_set(d->st_util, "utilization", busy_ms);
+            rrdset_done(d->st_util);
         }
 
         // --------------------------------------------------------------------
@@ -515,20 +577,30 @@ int do_proc_diskstats(int update_every, usec_t dt) {
         if(d->do_mops == CONFIG_BOOLEAN_YES || (d->do_mops == CONFIG_BOOLEAN_AUTO && (mreads || mwrites))) {
             d->do_mops = CONFIG_BOOLEAN_YES;
 
-            st = rrdset_find_bytype_localhost("disk_mops", disk);
-            if(unlikely(!st)) {
-                st = rrdset_create_localhost("disk_mops", disk, NULL, family, "disk.mops", "Disk Merged Operations"
-                                             , "merged operations/s", 2021, update_every, RRDSET_TYPE_LINE);
-                rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
-
-                rrddim_add(st, "reads", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
-                rrddim_add(st, "writes", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+            if(unlikely(!d->st_mops)) {
+                d->st_mops = rrdset_create_localhost(
+                        "disk_mops"
+                        , disk
+                        , NULL
+                        , family
+                        , "disk.mops"
+                        , "Disk Merged Operations"
+                        , "merged operations/s"
+                        , 2021
+                        , update_every
+                        , RRDSET_TYPE_LINE
+                );
+
+                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);
             }
-            else rrdset_next(st);
+            else rrdset_next(d->st_mops);
 
-            rrddim_set(st, "reads", mreads);
-            rrddim_set(st, "writes", mwrites);
-            rrdset_done(st);
+            rrddim_set(d->st_mops, "reads", mreads);
+            rrddim_set(d->st_mops, "writes", mwrites);
+            rrdset_done(d->st_mops);
         }
 
         // --------------------------------------------------------------------
@@ -536,20 +608,30 @@ int do_proc_diskstats(int update_every, usec_t dt) {
         if(d->do_iotime == CONFIG_BOOLEAN_YES || (d->do_iotime == CONFIG_BOOLEAN_AUTO && (readms || writems))) {
             d->do_iotime = CONFIG_BOOLEAN_YES;
 
-            st = rrdset_find_bytype_localhost("disk_iotime", disk);
-            if(unlikely(!st)) {
-                st = rrdset_create_localhost("disk_iotime", disk, NULL, family, "disk.iotime", "Disk Total I/O Time"
-                                             , "milliseconds/s", 2022, update_every, RRDSET_TYPE_LINE);
-                rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
-
-                rrddim_add(st, "reads", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
-                rrddim_add(st, "writes", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+            if(unlikely(!d->st_iotime)) {
+                d->st_iotime = rrdset_create_localhost(
+                        "disk_iotime"
+                        , disk
+                        , NULL
+                        , family
+                        , "disk.iotime"
+                        , "Disk Total I/O Time"
+                        , "milliseconds/s"
+                        , 2022
+                        , update_every
+                        , RRDSET_TYPE_LINE
+                );
+
+                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);
             }
-            else rrdset_next(st);
+            else rrdset_next(d->st_iotime);
 
-            last_readms  = rrddim_set(st, "reads", readms);
-            last_writems = rrddim_set(st, "writes", writems);
-            rrdset_done(st);
+            last_readms  = rrddim_set(d->st_iotime, "reads", readms);
+            last_writems = rrddim_set(d->st_iotime, "writes", writems);
+            rrdset_done(d->st_iotime);
         }
 
         // --------------------------------------------------------------------
@@ -559,57 +641,125 @@ int do_proc_diskstats(int update_every, usec_t dt) {
         if(likely(dt)) {
             if( (d->do_iotime == CONFIG_BOOLEAN_YES || (d->do_iotime == CONFIG_BOOLEAN_AUTO && (readms || writems))) &&
                 (d->do_ops    == CONFIG_BOOLEAN_YES || (d->do_ops    == CONFIG_BOOLEAN_AUTO && (reads || writes)))) {
-                st = rrdset_find_bytype_localhost("disk_await", disk);
-                if(unlikely(!st)) {
-                    st = rrdset_create_localhost("disk_await", disk, NULL, family, "disk.await"
-                                                 , "Average Completed I/O Operation Time", "ms per operation", 2005
-                                                 , update_every, RRDSET_TYPE_LINE);
-                    rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
-
-                    rrddim_add(st, "reads", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
-                    rrddim_add(st, "writes", NULL, -1, 1, RRD_ALGORITHM_ABSOLUTE);
+
+                if(unlikely(!d->st_await)) {
+                    d->st_await = rrdset_create_localhost(
+                            "disk_await"
+                            , disk
+                            , NULL
+                            , family
+                            , "disk.await"
+                            , "Average Completed I/O Operation Time"
+                            , "ms per operation"
+                            , 2005
+                            , update_every
+                            , RRDSET_TYPE_LINE
+                    );
+
+                    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);
                 }
-                else rrdset_next(st);
+                else rrdset_next(d->st_await);
 
-                rrddim_set(st, "reads", (reads - last_reads) ? (readms - last_readms) / (reads - last_reads) : 0);
-                rrddim_set(st, "writes", (writes - last_writes) ? (writems - last_writems) / (writes - last_writes) : 0);
-                rrdset_done(st);
+                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);
+                rrdset_done(d->st_await);
             }
 
             if( (d->do_io  == CONFIG_BOOLEAN_YES || (d->do_io  == CONFIG_BOOLEAN_AUTO && (readsectors || writesectors))) &&
                 (d->do_ops == CONFIG_BOOLEAN_YES || (d->do_ops == CONFIG_BOOLEAN_AUTO && (reads || writes)))) {
-                st = rrdset_find_bytype_localhost("disk_avgsz", disk);
-                if(unlikely(!st)) {
-                    st = rrdset_create_localhost("disk_avgsz", disk, NULL, family, "disk.avgsz"
-                                                 , "Average Completed I/O Operation Bandwidth"
-                                                 , "kilobytes per operation", 2006, update_every, RRDSET_TYPE_AREA);
-                    rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
-
-                    rrddim_add(st, "reads", NULL, d->sector_size, 1024, RRD_ALGORITHM_ABSOLUTE);
-                    rrddim_add(st, "writes", NULL, d->sector_size * -1, 1024, RRD_ALGORITHM_ABSOLUTE);
+
+                if(unlikely(!d->st_avgsz)) {
+                    d->st_avgsz = rrdset_create_localhost(
+                            "disk_avgsz"
+                            , disk
+                            , NULL
+                            , family
+                            , "disk.avgsz"
+                            , "Average Completed I/O Operation Bandwidth"
+                            , "kilobytes per operation"
+                            , 2006
+                            , update_every
+                            , RRDSET_TYPE_AREA
+                    );
+
+                    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);
                 }
-                else rrdset_next(st);
+                else rrdset_next(d->st_avgsz);
 
-                rrddim_set(st, "reads", (reads - last_reads) ? (readsectors - last_readsectors) / (reads - last_reads) : 0);
-                rrddim_set(st, "writes", (writes - last_writes) ? (writesectors - last_writesectors) / (writes - last_writes) : 0);
-                rrdset_done(st);
+                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);
+                rrdset_done(d->st_avgsz);
             }
 
             if( (d->do_util == CONFIG_BOOLEAN_YES || (d->do_util == CONFIG_BOOLEAN_AUTO && busy_ms)) &&
                 (d->do_ops  == CONFIG_BOOLEAN_YES || (d->do_ops  == CONFIG_BOOLEAN_AUTO && (reads || writes)))) {
-                st = rrdset_find_bytype_localhost("disk_svctm", disk);
-                if(unlikely(!st)) {
-                    st = rrdset_create_localhost("disk_svctm", disk, NULL, family, "disk.svctm", "Average Service Time"
-                                                 , "ms per operation", 2007, update_every, RRDSET_TYPE_LINE);
-                    rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
 
-                    rrddim_add(st, "svctm", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+                if(unlikely(!d->st_svctm)) {
+                    d->st_svctm = rrdset_create_localhost(
+                            "disk_svctm"
+                            , disk
+                            , NULL
+                            , family
+                            , "disk.svctm"
+                            , "Average Service Time"
+                            , "ms per operation"
+                            , 2007
+                            , update_every
+                            , RRDSET_TYPE_LINE
+                    );
+
+                    rrdset_flag_set(d->st_svctm, RRDSET_FLAG_DETAIL);
+
+                    rrddim_add(d->st_svctm, "svctm", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
                 }
-                else rrdset_next(st);
+                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);
+                rrdset_done(d->st_svctm);
+            }
+        }
+    }
 
-                rrddim_set(st, "svctm", ((reads - last_reads) + (writes - last_writes)) ? (busy_ms - last_busy_ms) / ((reads - last_reads) + (writes - last_writes)) : 0);
-                rrdset_done(st);
+    // cleanup removed disks
+
+    struct disk *d = disk_root, *last = NULL;
+    while(d) {
+        if(unlikely(!d->updated)) {
+            struct disk *t = d;
+
+            rrdset_obsolete_and_pointer_null(d->st_avgsz);
+            rrdset_obsolete_and_pointer_null(d->st_await);
+            rrdset_obsolete_and_pointer_null(d->st_backlog);
+            rrdset_obsolete_and_pointer_null(d->st_io);
+            rrdset_obsolete_and_pointer_null(d->st_iotime);
+            rrdset_obsolete_and_pointer_null(d->st_mops);
+            rrdset_obsolete_and_pointer_null(d->st_ops);
+            rrdset_obsolete_and_pointer_null(d->st_qops);
+            rrdset_obsolete_and_pointer_null(d->st_svctm);
+            rrdset_obsolete_and_pointer_null(d->st_util);
+
+            if(d == disk_root) {
+                disk_root = d = d->next;
+                last = NULL;
+            }
+            else if(last) {
+                last->next = d = d->next;
             }
+
+            freez(t->disk);
+            freez(t->mount_point);
+            freez(t);
+        }
+        else {
+            d->updated = 0;
+            last = d;
+            d = d->next;
         }
     }