@cryptotaxi247 / netdata-1 / commits / 569ec1386

diskstats: monitor disk space usage.

This fixes #249 and #74

Simon Nagl committed Apr 29, 2016 at 15:40 UTC 569ec138680595cf2ccb4b76e3d2d15bc5ee4f6a
1 file changed +55 -6
src/proc_diskstats.c
+55 -6
@@ -6,6 +6,7 @@
6 #include <string.h>
7 #include <sys/types.h>
8 #include <sys/stat.h>
9 +#include <sys/statvfs.h>
10 #include <fcntl.h>
11
12 #include "common.h"
@@ -23,6 +24,7 @@ struct disk {
24 unsigned long major;
25 unsigned long minor;
26 int partition_id; // -1 = this is not a partition
27 + char *mount_point;
28 char *family;
29 struct disk *next;
30 } *disk_root = NULL;
@@ -102,10 +104,10 @@ struct disk *get_disk(unsigned long major, unsigned long minor) {
104 }
105
106 if(mi)
105 - d->family = strdup(mi->mount_point);
107 + d->mount_point = strdup(mi->mount_point);
108 // no need to check for NULL
109 else
108 - d->family = NULL;
110 + d->mount_point = NULL;
111
112 return d;
113 }
@@ -114,7 +116,7 @@ int do_proc_diskstats(int update_every, unsigned long long dt) {
116 static procfile *ff = NULL;
117 static char path_to_get_hw_sector_size[FILENAME_MAX + 1] = "";
118 static int enable_new_disks = -1;
117 - static int do_io = -1, do_ops = -1, do_mops = -1, do_iotime = -1, do_qops = -1, do_util = -1, do_backlog = -1;
119 + static int do_io = -1, do_ops = -1, do_mops = -1, do_iotime = -1, do_qops = -1, do_util = -1, do_backlog = -1, do_space = -1;
120
121 if(enable_new_disks == -1) enable_new_disks = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "enable new disks detected at runtime", CONFIG_ONDEMAND_ONDEMAND);
122
@@ -125,6 +127,7 @@ int do_proc_diskstats(int update_every, unsigned long long dt) {
127 if(do_qops == -1) do_qops = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "queued operations for all disks", CONFIG_ONDEMAND_ONDEMAND);
128 if(do_util == -1) do_util = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "utilization percentage for all disks", CONFIG_ONDEMAND_ONDEMAND);
129 if(do_backlog == -1)do_backlog = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "backlog for all disks", CONFIG_ONDEMAND_ONDEMAND);
130 + if(do_space == -1) do_space = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "space usage for all disks", CONFIG_ONDEMAND_ONDEMAND);
131
132 if(!ff) {
133 char filename[FILENAME_MAX + 1];
@@ -142,6 +145,12 @@ int do_proc_diskstats(int update_every, unsigned long long dt) {
145 ff = procfile_readall(ff);
146 if(!ff) return 0; // we return 0, so that we will retry to open it next time
147
148 + struct statvfs * buff_statvfs;
149 + if ( !(buff_statvfs = (struct statvfs *)
150 + malloc(sizeof(struct statvfs)))) {
151 + error("Failed to allocate memory to buffer.");
152 + }
153 +
154 uint32_t lines = procfile_lines(ff), l;
155 uint32_t words;
156
@@ -150,7 +159,8 @@ int do_proc_diskstats(int update_every, unsigned long long dt) {
159 unsigned long long major = 0, minor = 0,
160 reads = 0, mreads = 0, readsectors = 0, readms = 0,
161 writes = 0, mwrites = 0, writesectors = 0, writems = 0,
153 - queued_ios = 0, busy_ms = 0, backlog_ms = 0;
162 + queued_ios = 0, busy_ms = 0, backlog_ms = 0,
163 + space_avail = 0, space_avail_root = 0, space_used = 0;
164
165 unsigned long long last_reads = 0, last_readsectors = 0, last_readms = 0,
166 last_writes = 0, last_writesectors = 0, last_writems = 0,
@@ -215,7 +225,8 @@ int do_proc_diskstats(int update_every, unsigned long long dt) {
225 else
226 def_enabled = 0;
227
218 - char *family = d->family;
228 + char *mount_point = d->mount_point;
229 + char *family = d->mount_point;
230 if(!family) family = disk;
231
232 /*
@@ -340,7 +351,7 @@ int do_proc_diskstats(int update_every, unsigned long long dt) {
351 }
352 */
353
343 - int ddo_io = do_io, ddo_ops = do_ops, ddo_mops = do_mops, ddo_iotime = do_iotime, ddo_qops = do_qops, ddo_util = do_util, ddo_backlog = do_backlog;
354 + int ddo_io = do_io, ddo_ops = do_ops, ddo_mops = do_mops, ddo_iotime = do_iotime, ddo_qops = do_qops, ddo_util = do_util, ddo_backlog = do_backlog, ddo_space = do_space;
355
356 // check which charts are enabled for this disk
357 {
@@ -358,6 +369,7 @@ int do_proc_diskstats(int update_every, unsigned long long dt) {
369 ddo_qops = config_get_boolean_ondemand(var_name, "queued operations", ddo_qops);
370 ddo_util = config_get_boolean_ondemand(var_name, "utilization percentage", ddo_util);
371 ddo_backlog = config_get_boolean_ondemand(var_name, "backlog", ddo_backlog);
372 + ddo_space = config_get_boolean_ondemand(var_name, "space", ddo_space);
373
374 // by default, do not add charts that do not have values
375 if(ddo_io == CONFIG_ONDEMAND_ONDEMAND && !reads && !writes) ddo_io = 0;
@@ -521,6 +533,42 @@ int do_proc_diskstats(int update_every, unsigned long long dt) {
533 rrdset_done(st);
534 }
535
536 + // --------------------------------------------------------------------
537 +
538 + if(ddo_space) {
539 + if(mount_point) {
540 + st = rrdset_find_bytype("disk_space", disk);
541 + if(!st) {
542 + st = rrdset_create("disk_space", disk, NULL, family, "disk.space", "Disk Space Usage", "Megabyte", 2023, update_every, RRDSET_TYPE_AREA);
543 + st->isdetail = 1;
544 +
545 + rrddim_add(st, "avail", NULL, 1, 1048576, RRDDIM_ABSOLUTE);
546 + rrddim_add(st, "reserved for root", NULL, 1, 1048576, RRDDIM_ABSOLUTE);
547 + rrddim_add(st, "used" , NULL, 1, 1045576, RRDDIM_ABSOLUTE);
548 + }
549 + else rrdset_next_usec(st, dt);
550 +
551 +
552 +
553 + if (statvfs(family, buff_statvfs) < 0) {
554 + error("Faild checking disk space usage of %s", family);
555 + } else {
556 + space_avail = buff_statvfs->f_bavail * buff_statvfs->f_bsize;
557 + space_avail_root = (buff_statvfs->f_bfree - buff_statvfs->f_bavail) * buff_statvfs->f_bsize;
558 + space_used = (buff_statvfs->f_blocks - buff_statvfs->f_bfree) * buff_statvfs->f_bsize;
559 + }
560 +
561 + rrddim_set(st, "avail", space_avail);
562 + rrddim_set(st, "reserved for root", space_avail_root);
563 + rrddim_set(st, "used", space_used);
564 + rrdset_done(st);
565 + } else {
566 + if(ddo_space != CONFIG_ONDEMAND_ONDEMAND) {
567 + error("Cannot find space usage for disk %s. It does not have a mount point.", family);
568 + }
569 + }
570 + }
571 +
572 // --------------------------------------------------------------------
573 // calculate differential charts
574 // only if this is not the first time we run
@@ -573,6 +621,7 @@ int do_proc_diskstats(int update_every, unsigned long long dt) {
621 }
622 }
623 }
624 + free(buff_statvfs);
625
626 return 0;
627 }