summaryrefslogtreecommitdiffstats
path: root/src/proc_diskstats.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/proc_diskstats.c')
-rw-r--r--src/proc_diskstats.c312
1 files changed, 229 insertions, 83 deletions
diff --git a/src/proc_diskstats.c b/src/proc_diskstats.c
index 4a32ec949..866e49c77 100644
--- a/src/proc_diskstats.c
+++ b/src/proc_diskstats.c
@@ -2,12 +2,13 @@
#define RRD_TYPE_DISK "disk"
+#define DISK_TYPE_UNKNOWN 0
#define DISK_TYPE_PHYSICAL 1
#define DISK_TYPE_PARTITION 2
-#define DISK_TYPE_CONTAINER 3
+#define DISK_TYPE_VIRTUAL 3
#define CONFIG_SECTION_DISKSTATS "plugin:proc:/proc/diskstats"
-#define DELAULT_EXLUDED_DISKS "loop* ram*"
+#define DEFAULT_EXCLUDED_DISKS "loop* ram*"
static struct disk {
char *disk; // the name of the disk (sda, sdb, etc, after being looked up)
@@ -31,16 +32,41 @@ static struct disk {
int updated;
- RRDSET *st_avgsz;
- RRDSET *st_await;
- RRDSET *st_backlog;
RRDSET *st_io;
- RRDSET *st_iotime;
- RRDSET *st_mops;
+ RRDDIM *rd_io_reads;
+ RRDDIM *rd_io_writes;
+
RRDSET *st_ops;
+ RRDDIM *rd_ops_reads;
+ RRDDIM *rd_ops_writes;
+
RRDSET *st_qops;
- RRDSET *st_svctm;
+ RRDDIM *rd_qops_operations;
+
+ RRDSET *st_backlog;
+ RRDDIM *rd_backlog_backlog;
+
RRDSET *st_util;
+ RRDDIM *rd_util_utilization;
+
+ RRDSET *st_mops;
+ RRDDIM *rd_mops_reads;
+ RRDDIM *rd_mops_writes;
+
+ RRDSET *st_iotime;
+ RRDDIM *rd_iotime_reads;
+ RRDDIM *rd_iotime_writes;
+
+ RRDSET *st_await;
+ RRDDIM *rd_await_reads;
+ RRDDIM *rd_await_writes;
+
+ RRDSET *st_avgsz;
+ RRDDIM *rd_avgsz_reads;
+ RRDDIM *rd_avgsz_writes;
+
+ RRDSET *st_svctm;
+ RRDDIM *rd_svctm_svctm;
struct disk *next;
} *disk_root = NULL;
@@ -49,21 +75,23 @@ static struct disk {
static char *path_to_get_hw_sector_size = NULL;
static char *path_to_get_hw_sector_size_partitions = NULL;
-static char *path_to_find_block_device = NULL;
+static char *path_to_sys_dev_block_major_minor_string = NULL;
+static char *path_to_sys_block_device = NULL;
+static char *path_to_sys_devices_virtual_block_device = NULL;
static char *path_to_device_mapper = NULL;
+static char *path_to_device_label = NULL;
+static char *path_to_device_id = NULL;
+static int name_disks_by_id = CONFIG_BOOLEAN_NO;
-static inline char *get_disk_name(unsigned long major, unsigned long minor, char *disk) {
- static int enabled = 1;
-
- if(!enabled) goto cleanup;
-
+static inline int get_disk_name_from_path(const char *path, char *result, size_t result_size, unsigned long major, unsigned long minor, char *disk) {
char filename[FILENAME_MAX + 1];
- char link[FILENAME_MAX + 1];
+ int found = 0;
- DIR *dir = opendir(path_to_device_mapper);
+ result_size--;
+
+ DIR *dir = opendir(path);
if (!dir) {
- error("DEVICE-MAPPER ('%s', %lu:%lu): Cannot open directory '%s'. Disabling device-mapper support.", disk, major, minor, path_to_device_mapper);
- enabled = 0;
+ error("DEVICE-MAPPER ('%s', %lu:%lu): Cannot open directory '%s'. Disabling device-mapper support.", disk, major, minor, path);
goto cleanup;
}
@@ -71,18 +99,18 @@ static inline char *get_disk_name(unsigned long major, unsigned long minor, char
while ((de = readdir(dir))) {
if(de->d_type != DT_LNK) continue;
- snprintfz(filename, FILENAME_MAX, "%s/%s", path_to_device_mapper, de->d_name);
- ssize_t len = readlink(filename, link, FILENAME_MAX);
+ snprintfz(filename, FILENAME_MAX, "%s/%s", path, de->d_name);
+ ssize_t len = readlink(filename, result, result_size);
if(len <= 0) {
error("DEVICE-MAPPER ('%s', %lu:%lu): Cannot read link '%s'.", disk, major, minor, filename);
continue;
}
- link[len] = '\0';
- if(link[0] != '/')
- snprintfz(filename, FILENAME_MAX, "%s/%s", path_to_device_mapper, link);
+ result[len] = '\0';
+ if(result[0] != '/')
+ snprintfz(filename, FILENAME_MAX, "%s/%s", path, result);
else
- strncpyz(filename, link, FILENAME_MAX);
+ strncpyz(filename, result, FILENAME_MAX);
struct stat sb;
if(stat(filename, &sb) == -1) {
@@ -102,17 +130,37 @@ static inline char *get_disk_name(unsigned long major, unsigned long minor, char
// info("DEVICE-MAPPER ('%s', %lu:%lu): filename '%s' matches.", disk, major, minor, filename);
- strncpy(link, de->d_name, FILENAME_MAX);
- netdata_fix_chart_name(link);
- disk = link;
+ strncpy(result, de->d_name, result_size);
+ found = 1;
break;
}
closedir(dir);
+
cleanup:
- return strdupz(disk);
+
+ if(!found)
+ result[0] = '\0';
+
+ return found;
}
+static inline char *get_disk_name(unsigned long major, unsigned long minor, char *disk) {
+ char result[FILENAME_MAX + 1] = "";
+
+ if(!path_to_device_mapper || !*path_to_device_mapper || !get_disk_name_from_path(path_to_device_mapper, result, FILENAME_MAX + 1, major, minor, disk))
+ if(!path_to_device_label || !*path_to_device_label || !get_disk_name_from_path(path_to_device_label, result, FILENAME_MAX + 1, major, minor, disk))
+ if(name_disks_by_id != CONFIG_BOOLEAN_YES || !path_to_device_id || !*path_to_device_id || !get_disk_name_from_path(path_to_device_id, result, FILENAME_MAX + 1, major, minor, disk))
+ strncpy(result, disk, FILENAME_MAX);
+
+ if(!result[0])
+ strncpy(result, disk, FILENAME_MAX);
+
+ netdata_fix_chart_name(result);
+ return strdup(result);
+}
+
+
static struct disk *get_disk(unsigned long major, unsigned long minor, char *disk) {
static struct mountinfo *disk_mountinfo_root = NULL;
@@ -134,7 +182,7 @@ static struct disk *get_disk(unsigned long major, unsigned long minor, char *dis
d->device = strdupz(disk);
d->major = major;
d->minor = minor;
- d->type = DISK_TYPE_PHYSICAL; // Default type. Changed later if not correct.
+ d->type = DISK_TYPE_UNKNOWN; // Default type. Changed later if not correct.
d->configured = 0;
d->sector_size = 512; // the default, will be changed below
d->next = NULL;
@@ -148,33 +196,50 @@ static struct disk *get_disk(unsigned long major, unsigned long minor, char *dis
last->next = d;
}
+ char buffer[FILENAME_MAX + 1];
+
+ // find if it is a physical disk
+ // by checking if /sys/block/DISK is readable.
+ snprintfz(buffer, FILENAME_MAX, path_to_sys_block_device, disk);
+ if(likely(access(buffer, R_OK) == 0)) {
+ // assign it here, but it will be overwritten if it is not a physical disk
+ d->type = DISK_TYPE_PHYSICAL;
+ }
+
// find if it is a partition
// by checking if /sys/dev/block/MAJOR:MINOR/partition is readable.
- char buffer[FILENAME_MAX + 1];
- snprintfz(buffer, FILENAME_MAX, path_to_find_block_device, major, minor, "partition");
+ snprintfz(buffer, FILENAME_MAX, path_to_sys_dev_block_major_minor_string, major, minor, "partition");
if(likely(access(buffer, R_OK) == 0)) {
d->type = DISK_TYPE_PARTITION;
}
else {
- // find if it is a container
- // by checking if /sys/dev/block/MAJOR:MINOR/slaves has entries
- snprintfz(buffer, FILENAME_MAX, path_to_find_block_device, major, minor, "slaves/");
- DIR *dirp = opendir(buffer);
- if(likely(dirp != NULL)) {
- struct dirent *dp;
- while( (dp = readdir(dirp)) ) {
- // . and .. are also files in empty folders.
- if(unlikely(strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0)) {
- continue;
+ // find if it is a virtual disk
+ // by checking if /sys/devices/virtual/block/DISK is readable.
+ snprintfz(buffer, FILENAME_MAX, path_to_sys_devices_virtual_block_device, disk);
+ if(likely(access(buffer, R_OK) == 0)) {
+ d->type = DISK_TYPE_VIRTUAL;
+ }
+ else {
+ // find if it is a virtual device
+ // by checking if /sys/dev/block/MAJOR:MINOR/slaves has entries
+ snprintfz(buffer, FILENAME_MAX, path_to_sys_dev_block_major_minor_string, major, minor, "slaves/");
+ DIR *dirp = opendir(buffer);
+ if (likely(dirp != NULL)) {
+ struct dirent *dp;
+ while ((dp = readdir(dirp))) {
+ // . and .. are also files in empty folders.
+ if (unlikely(strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0)) {
+ continue;
+ }
+
+ d->type = DISK_TYPE_VIRTUAL;
+
+ // Stop the loop after we found one file.
+ break;
}
-
- d->type = DISK_TYPE_CONTAINER;
-
- // Stop the loop after we found one file.
- break;
+ if (unlikely(closedir(dirp) == -1))
+ error("Unable to close dir %s", buffer);
}
- if(unlikely(closedir(dirp) == -1))
- error("Unable to close dir %s", buffer);
}
}
@@ -296,8 +361,14 @@ int do_proc_diskstats(int update_every, usec_t dt) {
char buffer[FILENAME_MAX + 1];
+ snprintfz(buffer, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/sys/block/%s");
+ path_to_sys_block_device = config_get(CONFIG_SECTION_DISKSTATS, "path to get block device", buffer);
+
+ snprintfz(buffer, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/sys/devices/virtual/block/%s");
+ path_to_sys_devices_virtual_block_device = config_get(CONFIG_SECTION_DISKSTATS, "path to get virtual block device", buffer);
+
snprintfz(buffer, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/sys/dev/block/%lu:%lu/%s");
- path_to_find_block_device = config_get(CONFIG_SECTION_DISKSTATS, "path to get block device infos", buffer);
+ path_to_sys_dev_block_major_minor_string = config_get(CONFIG_SECTION_DISKSTATS, "path to get block device infos", buffer);
snprintfz(buffer, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/sys/block/%s/queue/hw_sector_size");
path_to_get_hw_sector_size = config_get(CONFIG_SECTION_DISKSTATS, "path to get h/w sector size", buffer);
@@ -307,6 +378,14 @@ int do_proc_diskstats(int update_every, usec_t dt) {
snprintfz(buffer, FILENAME_MAX, "%s/dev/mapper", netdata_configured_host_prefix);
path_to_device_mapper = config_get(CONFIG_SECTION_DISKSTATS, "path to device mapper", buffer);
+
+ snprintfz(buffer, FILENAME_MAX, "%s/dev/disk/by-label", netdata_configured_host_prefix);
+ path_to_device_label = config_get(CONFIG_SECTION_DISKSTATS, "path to /dev/disk/by-label", buffer);
+
+ snprintfz(buffer, FILENAME_MAX, "%s/dev/disk/by-id", netdata_configured_host_prefix);
+ path_to_device_id = config_get(CONFIG_SECTION_DISKSTATS, "path to /dev/disk/by-id", buffer);
+
+ name_disks_by_id = config_get_boolean(CONFIG_SECTION_DISKSTATS, "name disks by id", name_disks_by_id);
}
// --------------------------------------------------------------------------
@@ -323,6 +402,8 @@ int do_proc_diskstats(int update_every, usec_t dt) {
size_t lines = procfile_lines(ff), l;
+ collected_number system_read_kb = 0, system_write_kb = 0;
+
for(l = 0; l < lines ;l++) {
// --------------------------------------------------------------------------
// Read parameters
@@ -398,6 +479,11 @@ int do_proc_diskstats(int update_every, usec_t dt) {
struct disk *d = get_disk(major, minor, disk);
d->updated = 1;
+ if(unlikely(d->type == DISK_TYPE_PHYSICAL)) {
+ system_read_kb += readsectors * d->sector_size / 1024;
+ system_write_kb += writesectors * d->sector_size / 1024;
+ }
+
// --------------------------------------------------------------------------
// Set its family based on mount point
@@ -415,7 +501,7 @@ int do_proc_diskstats(int update_every, usec_t dt) {
if(unlikely(!excluded_disks)) {
excluded_disks = simple_pattern_create(
- config_get(CONFIG_SECTION_DISKSTATS, "exclude disks", DELAULT_EXLUDED_DISKS),
+ config_get(CONFIG_SECTION_DISKSTATS, "exclude disks", DEFAULT_EXCLUDED_DISKS),
SIMPLE_PATTERN_EXACT
);
}
@@ -449,6 +535,10 @@ int do_proc_diskstats(int update_every, usec_t dt) {
// based on the type of disk
switch(d->type) {
+ default:
+ case DISK_TYPE_UNKNOWN:
+ break;
+
case DISK_TYPE_PHYSICAL:
def_performance = global_enable_performance_for_physical_disks;
break;
@@ -457,7 +547,7 @@ int do_proc_diskstats(int update_every, usec_t dt) {
def_performance = global_enable_performance_for_partitions;
break;
- case DISK_TYPE_CONTAINER:
+ case DISK_TYPE_VIRTUAL:
def_performance = global_enable_performance_for_virtual_disks;
break;
}
@@ -518,18 +608,20 @@ int do_proc_diskstats(int update_every, usec_t dt) {
, "disk.io"
, "Disk I/O Bandwidth"
, "kilobytes/s"
+ , "proc"
+ , "diskstats"
, 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);
+ d->rd_io_reads = rrddim_add(d->st_io, "reads", NULL, d->sector_size, 1024, RRD_ALGORITHM_INCREMENTAL);
+ d->rd_io_writes = rrddim_add(d->st_io, "writes", NULL, d->sector_size * -1, 1024, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(d->st_io);
- last_readsectors = rrddim_set(d->st_io, "reads", readsectors);
- last_writesectors = rrddim_set(d->st_io, "writes", writesectors);
+ last_readsectors = rrddim_set_by_pointer(d->st_io, d->rd_io_reads, readsectors);
+ last_writesectors = rrddim_set_by_pointer(d->st_io, d->rd_io_writes, writesectors);
rrdset_done(d->st_io);
}
@@ -547,6 +639,8 @@ int do_proc_diskstats(int update_every, usec_t dt) {
, "disk.ops"
, "Disk Completed I/O Operations"
, "operations/s"
+ , "proc"
+ , "diskstats"
, 2001
, update_every
, RRDSET_TYPE_LINE
@@ -554,13 +648,13 @@ int do_proc_diskstats(int update_every, usec_t dt) {
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);
+ d->rd_ops_reads = rrddim_add(d->st_ops, "reads", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ d->rd_ops_writes = rrddim_add(d->st_ops, "writes", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(d->st_ops);
- last_reads = rrddim_set(d->st_ops, "reads", reads);
- last_writes = rrddim_set(d->st_ops, "writes", writes);
+ last_reads = rrddim_set_by_pointer(d->st_ops, d->rd_ops_reads, reads);
+ last_writes = rrddim_set_by_pointer(d->st_ops, d->rd_ops_writes, writes);
rrdset_done(d->st_ops);
}
@@ -578,6 +672,8 @@ int do_proc_diskstats(int update_every, usec_t dt) {
, "disk.qops"
, "Disk Current I/O Operations"
, "operations"
+ , "proc"
+ , "diskstats"
, 2002
, update_every
, RRDSET_TYPE_LINE
@@ -585,11 +681,11 @@ int do_proc_diskstats(int update_every, usec_t dt) {
rrdset_flag_set(d->st_qops, RRDSET_FLAG_DETAIL);
- rrddim_add(d->st_qops, "operations", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+ d->rd_qops_operations = rrddim_add(d->st_qops, "operations", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
}
else rrdset_next(d->st_qops);
- rrddim_set(d->st_qops, "operations", queued_ios);
+ rrddim_set_by_pointer(d->st_qops, d->rd_qops_operations, queued_ios);
rrdset_done(d->st_qops);
}
@@ -607,6 +703,8 @@ int do_proc_diskstats(int update_every, usec_t dt) {
, "disk.backlog"
, "Disk Backlog"
, "backlog (ms)"
+ , "proc"
+ , "diskstats"
, 2003
, update_every
, RRDSET_TYPE_AREA
@@ -614,11 +712,11 @@ int do_proc_diskstats(int update_every, usec_t dt) {
rrdset_flag_set(d->st_backlog, RRDSET_FLAG_DETAIL);
- rrddim_add(d->st_backlog, "backlog", NULL, 1, 10, RRD_ALGORITHM_INCREMENTAL);
+ d->rd_backlog_backlog = rrddim_add(d->st_backlog, "backlog", NULL, 1, 10, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(d->st_backlog);
- rrddim_set(d->st_backlog, "backlog", backlog_ms);
+ rrddim_set_by_pointer(d->st_backlog, d->rd_backlog_backlog, backlog_ms);
rrdset_done(d->st_backlog);
}
@@ -636,6 +734,8 @@ int do_proc_diskstats(int update_every, usec_t dt) {
, "disk.util"
, "Disk Utilization Time"
, "% of time working"
+ , "proc"
+ , "diskstats"
, 2004
, update_every
, RRDSET_TYPE_AREA
@@ -643,11 +743,11 @@ int do_proc_diskstats(int update_every, usec_t dt) {
rrdset_flag_set(d->st_util, RRDSET_FLAG_DETAIL);
- rrddim_add(d->st_util, "utilization", NULL, 1, 10, RRD_ALGORITHM_INCREMENTAL);
+ d->rd_util_utilization = rrddim_add(d->st_util, "utilization", NULL, 1, 10, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(d->st_util);
- last_busy_ms = rrddim_set(d->st_util, "utilization", busy_ms);
+ last_busy_ms = rrddim_set_by_pointer(d->st_util, d->rd_util_utilization, busy_ms);
rrdset_done(d->st_util);
}
@@ -665,6 +765,8 @@ int do_proc_diskstats(int update_every, usec_t dt) {
, "disk.mops"
, "Disk Merged Operations"
, "merged operations/s"
+ , "proc"
+ , "diskstats"
, 2021
, update_every
, RRDSET_TYPE_LINE
@@ -672,13 +774,13 @@ int do_proc_diskstats(int update_every, usec_t dt) {
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);
+ d->rd_mops_reads = rrddim_add(d->st_mops, "reads", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ d->rd_mops_writes = rrddim_add(d->st_mops, "writes", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(d->st_mops);
- rrddim_set(d->st_mops, "reads", mreads);
- rrddim_set(d->st_mops, "writes", mwrites);
+ rrddim_set_by_pointer(d->st_mops, d->rd_mops_reads, mreads);
+ rrddim_set_by_pointer(d->st_mops, d->rd_mops_writes, mwrites);
rrdset_done(d->st_mops);
}
@@ -696,6 +798,8 @@ int do_proc_diskstats(int update_every, usec_t dt) {
, "disk.iotime"
, "Disk Total I/O Time"
, "milliseconds/s"
+ , "proc"
+ , "diskstats"
, 2022
, update_every
, RRDSET_TYPE_LINE
@@ -703,13 +807,13 @@ int do_proc_diskstats(int update_every, usec_t dt) {
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);
+ d->rd_iotime_reads = rrddim_add(d->st_iotime, "reads", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ d->rd_iotime_writes = rrddim_add(d->st_iotime, "writes", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(d->st_iotime);
- last_readms = rrddim_set(d->st_iotime, "reads", readms);
- last_writems = rrddim_set(d->st_iotime, "writes", writems);
+ last_readms = rrddim_set_by_pointer(d->st_iotime, d->rd_iotime_reads, readms);
+ last_writems = rrddim_set_by_pointer(d->st_iotime, d->rd_iotime_writes, writems);
rrdset_done(d->st_iotime);
}
@@ -730,6 +834,8 @@ int do_proc_diskstats(int update_every, usec_t dt) {
, "disk.await"
, "Average Completed I/O Operation Time"
, "ms per operation"
+ , "proc"
+ , "diskstats"
, 2005
, update_every
, RRDSET_TYPE_LINE
@@ -737,13 +843,13 @@ int do_proc_diskstats(int update_every, usec_t dt) {
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);
+ d->rd_await_reads = rrddim_add(d->st_await, "reads", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+ d->rd_await_writes = rrddim_add(d->st_await, "writes", NULL, -1, 1, RRD_ALGORITHM_ABSOLUTE);
}
else rrdset_next(d->st_await);
- 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);
+ rrddim_set_by_pointer(d->st_await, d->rd_await_reads, (reads - last_reads) ? (readms - last_readms) / (reads - last_reads) : 0);
+ rrddim_set_by_pointer(d->st_await, d->rd_await_writes, (writes - last_writes) ? (writems - last_writems) / (writes - last_writes) : 0);
rrdset_done(d->st_await);
}
@@ -759,6 +865,8 @@ int do_proc_diskstats(int update_every, usec_t dt) {
, "disk.avgsz"
, "Average Completed I/O Operation Bandwidth"
, "kilobytes per operation"
+ , "proc"
+ , "diskstats"
, 2006
, update_every
, RRDSET_TYPE_AREA
@@ -766,13 +874,13 @@ int do_proc_diskstats(int update_every, usec_t dt) {
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);
+ d->rd_avgsz_reads = rrddim_add(d->st_avgsz, "reads", NULL, d->sector_size, 1024, RRD_ALGORITHM_ABSOLUTE);
+ d->rd_avgsz_writes = rrddim_add(d->st_avgsz, "writes", NULL, d->sector_size * -1, 1024, RRD_ALGORITHM_ABSOLUTE);
}
else rrdset_next(d->st_avgsz);
- 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);
+ rrddim_set_by_pointer(d->st_avgsz, d->rd_avgsz_reads, (reads - last_reads) ? (readsectors - last_readsectors) / (reads - last_reads) : 0);
+ rrddim_set_by_pointer(d->st_avgsz, d->rd_avgsz_writes, (writes - last_writes) ? (writesectors - last_writesectors) / (writes - last_writes) : 0);
rrdset_done(d->st_avgsz);
}
@@ -788,6 +896,8 @@ int do_proc_diskstats(int update_every, usec_t dt) {
, "disk.svctm"
, "Average Service Time"
, "ms per operation"
+ , "proc"
+ , "diskstats"
, 2007
, update_every
, RRDSET_TYPE_LINE
@@ -795,16 +905,52 @@ int do_proc_diskstats(int update_every, usec_t dt) {
rrdset_flag_set(d->st_svctm, RRDSET_FLAG_DETAIL);
- rrddim_add(d->st_svctm, "svctm", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+ d->rd_svctm_svctm = rrddim_add(d->st_svctm, "svctm", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
}
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);
+ rrddim_set_by_pointer(d->st_svctm, d->rd_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);
}
}
}
+
+ // ------------------------------------------------------------------------
+ // update the system total I/O
+
+ if(global_do_io == CONFIG_BOOLEAN_YES || (global_do_io == CONFIG_BOOLEAN_AUTO && (system_read_kb || system_write_kb))) {
+ static RRDSET *st_io = NULL;
+ static RRDDIM *rd_in = NULL, *rd_out = NULL;
+
+ if(unlikely(!st_io)) {
+ st_io = rrdset_create_localhost(
+ "system"
+ , "io"
+ , NULL
+ , "disk"
+ , NULL
+ , "Disk I/O"
+ , "kilobytes/s"
+ , "proc"
+ , "diskstats"
+ , 150
+ , update_every
+ , RRDSET_TYPE_AREA
+ );
+
+ rd_in = rrddim_add(st_io, "in", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rd_out = rrddim_add(st_io, "out", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ }
+ else rrdset_next(st_io);
+
+ rrddim_set_by_pointer(st_io, rd_in, system_read_kb);
+ rrddim_set_by_pointer(st_io, rd_out, system_write_kb);
+ rrdset_done(st_io);
+ }
+
+
+ // ------------------------------------------------------------------------
// cleanup removed disks
struct disk *d = disk_root, *last = NULL;