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
}