diff options
Diffstat (limited to 'src/proc_diskstats.c')
-rw-r--r-- | src/proc_diskstats.c | 312 |
1 files changed, 229 insertions, 83 deletions
diff --git a/src/proc_diskstats.c b/src/proc_diskstats.c index 4a32ec94..866e49c7 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; |