@cryptotaxi247 / netdata-1 / commits / f80d57aca

diskstats: enhance options

Simon Nagl committed May 18, 2016 at 20:57 UTC f80d57acaec0a48638faf366c8a2ae075efd0909
1 file changed +241 -460
src/proc_diskstats.c
+241 -460
@@ -136,21 +136,28 @@ struct disk *get_disk(unsigned long major, unsigned long minor) {
136 int do_proc_diskstats(int update_every, unsigned long long dt) {
137 static procfile *ff = NULL;
138 static char path_to_get_hw_sector_size[FILENAME_MAX + 1] = "";
139 - static int enable_new_disks = -1;
140 - 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;
139 + static int enable_autodetection;
140 + static int enable_physical_disks, enable_virtual_disks, enable_partitions, enable_mountpoints, enable_space_metrics;
141 + static int do_io, do_ops, do_mops, do_iotime, do_qops, do_util, do_backlog, do_space;
142 static struct statvfs buff_statvfs;
143 static struct stat buff_stat;
144
144 - 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);
145 + enable_autodetection = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "enable new disks detected at runtime", CONFIG_ONDEMAND_ONDEMAND);
146
146 - if(do_io == -1) do_io = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "bandwidth for all disks", CONFIG_ONDEMAND_ONDEMAND);
147 - if(do_ops == -1) do_ops = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "operations for all disks", CONFIG_ONDEMAND_ONDEMAND);
148 - if(do_mops == -1) do_mops = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "merged operations for all disks", CONFIG_ONDEMAND_ONDEMAND);
149 - if(do_iotime == -1) do_iotime = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "i/o time for all disks", CONFIG_ONDEMAND_ONDEMAND);
150 - if(do_qops == -1) do_qops = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "queued operations for all disks", CONFIG_ONDEMAND_ONDEMAND);
151 - if(do_util == -1) do_util = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "utilization percentage for all disks", CONFIG_ONDEMAND_ONDEMAND);
152 - if(do_backlog == -1)do_backlog = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "backlog for all disks", CONFIG_ONDEMAND_ONDEMAND);
153 - if(do_space == -1) do_space = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "space usage for all disks", CONFIG_ONDEMAND_ONDEMAND);
147 + enable_physical_disks = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "performance metrics for physical disks", CONFIG_ONDEMAND_ONDEMAND);
148 + enable_virtual_disks = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "performance metrics for virtual disks", CONFIG_ONDEMAND_NO);
149 + enable_partitions = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "performance metrics for partitions", CONFIG_ONDEMAND_NO);
150 + enable_mountpoints = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "performance metrics for mounted filesystems", CONFIG_ONDEMAND_NO);
151 + enable_space_metrics = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "space metrics for mounted filesystems", CONFIG_ONDEMAND_ONDEMAND);
152 +
153 + do_io = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "bandwidth for all disks", CONFIG_ONDEMAND_ONDEMAND);
154 + do_ops = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "operations for all disks", CONFIG_ONDEMAND_ONDEMAND);
155 + do_mops = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "merged operations for all disks", CONFIG_ONDEMAND_ONDEMAND);
156 + do_iotime = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "i/o time for all disks", CONFIG_ONDEMAND_ONDEMAND);
157 + do_qops = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "queued operations for all disks", CONFIG_ONDEMAND_ONDEMAND);
158 + do_util = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "utilization percentage for all disks", CONFIG_ONDEMAND_ONDEMAND);
159 + do_backlog = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "backlog for all disks", CONFIG_ONDEMAND_ONDEMAND);
160 + do_space = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "space usage for all disks", CONFIG_ONDEMAND_ONDEMAND);
161
162 if(!ff) {
163 char filename[FILENAME_MAX + 1];
@@ -172,6 +179,8 @@ int do_proc_diskstats(int update_every, unsigned long long dt) {
179 uint32_t words;
180
181 for(l = 0; l < lines ;l++) {
182 + // --------------------------------------------------------------------------
183 + // Read parameters
184 char *disk;
185 unsigned long long major = 0, minor = 0,
186 reads = 0, mreads = 0, readsectors = 0, readms = 0,
@@ -230,271 +239,49 @@ int do_proc_diskstats(int update_every, unsigned long long dt) {
239 // I/O completion time and the backlog that may be accumulating.
240 backlog_ms = strtoull(procfile_lineword(ff, l, 13), NULL, 10); // rq_ticks
241
233 - int def_enabled = 0;
234 -
242 + // --------------------------------------------------------------------------
243 // remove slashes from disk names
244 char *s;
245 for(s = disk; *s ;s++) if(*s == '/') *s = '_';
238 -
246 struct disk *d = get_disk(major, minor);
240 -
241 - // Enable statistics for physical disks and mount points by default.
242 - if( (d->type == DISK_TYPE_PHYSICAL) || (d->mount_point != NULL) ) {
243 - def_enabled = enable_new_disks;
244 - }
245 -
246 - /*
247 - // Enable physical disks by default.
248 - // To fine out if it is a harddrive we use
249 - // Linux Assigned Names and Numbers Authority (http://www.lanana.org/)
250 - // We can't do that because proprietary disk drivers do not stick to
251 - // the standard. To detect re
252 - switch(major) {
253 - case 8: // SCSI disk devices (0-15)
254 - if(!(minor % 16)) {
255 - def_enabled = enable_new_disks;
256 - }
257 - break;
258 - case 21: // Acorn MFM hard drive interface
259 - if(!(minor % 64)) {
260 - def_enabled = enable_new_disks;
261 - }
262 - break;
263 - case 28: // ACSI disk (68k/Atari)
264 - if(!(minor % 16)) {
265 - def_enabled = enable_new_disks;
266 - }
267 - break;
268 - case 36: // MCA ESDI hard disk
269 - if(!(minor % 64)) {
270 - def_enabled = enable_new_disks;
271 - }
272 - break;
273 - case 48: // Mylex DAC960 PCI RAID controller; first controller
274 - if(!(minor % 8)) {
275 - def_enabled = enable_new_disks;
276 - }
277 - break;
278 - case 49: // Mylex DAC960 PCI RAID controller; second controller
279 - if(!(minor % 8)) {
280 - def_enabled = enable_new_disks;
281 - }
282 - break;
283 - case 50: // Mylex DAC960 PCI RAID controller; third controller
284 - if(!(minor % 8)) {
285 - def_enabled = enable_new_disks;
286 - }
287 - break;
288 - case 51: // Mylex DAC960 PCI RAID controller; fourth controller
289 - if(!(minor % 8)) {
290 - def_enabled = enable_new_disks;
291 - }
292 - break;
293 - case 52: // Mylex DAC960 PCI RAID controller; fifth controller
294 - if(!(minor % 8)) {
295 - def_enabled = enable_new_disks;
296 - }
297 - break;
298 - case 53: // Mylex DAC960 PCI RAID controller; sixth controller
299 - if(!(minor % 8)) {
300 - def_enabled = enable_new_disks;
301 - }
302 - break;
303 - case 54: // Mylex DAC960 PCI RAID controller; seventh controller
304 - if(!(minor % 8)) {
305 - def_enabled = enable_new_disks;
306 - }
307 - break;
308 - case 55: // Mylex DAC960 PCI RAID controller; eigth controller
309 - if(!(minor % 8)) {
310 - def_enabled = enable_new_disks;
311 - }
312 - break;
313 - case 65: // SCSI disk devices (16-31)
314 - if(!(minor % 16)) {
315 - def_enabled = enable_new_disks;
316 - }
317 - break;
318 - case 66: // SCSI disk devices (32-47)
319 - if(!(minor % 16)) {
320 - def_enabled = enable_new_disks;
321 - }
322 - break;
323 - case 67: // SCSI disk devices (48-63)
324 - if(!(minor % 16)) {
325 - def_enabled = enable_new_disks;
326 - }
327 - break;
328 - case 68: // SCSI disk devices (64-79)
329 - if(!(minor % 16)) {
330 - def_enabled = enable_new_disks;
331 - }
332 - break;
333 - case 69: // SCSI disk devices (80-95)
334 - if(!(minor % 16)) {
335 - def_enabled = enable_new_disks;
336 - }
337 - break;
338 - case 70: // SCSI disk devices (96-111)
339 - if(!(minor % 16)) {
340 - def_enabled = enable_new_disks;
341 - }
342 - break;
343 - case 71: // SCSI disk devices (112-127)
344 - if(!(minor % 16)) {
345 - def_enabled = enable_new_disks;
346 - }
347 - break;
348 - case 80: // I2O hard disk
349 - if(!(minor % 16)) {
350 - def_enabled = enable_new_disks;
351 - }
352 - break;
353 - case 81: // I2O hard disk
354 - if(!(minor % 16)) {
355 - def_enabled = enable_new_disks;
356 - }
357 - break;
358 - case 82: // I2O hard disk
359 - if(!(minor % 16)) {
360 - def_enabled = enable_new_disks;
361 - }
362 - break;
363 - case 83: // I2O hard disk
364 - if(!(minor % 16)) {
365 - def_enabled = enable_new_disks;
366 - }
367 - break;
368 - case 84: // I2O hard disk
369 - if(!(minor % 16)) {
370 - def_enabled = enable_new_disks;
371 - }
372 - break;
373 - case 85: // I2O hard disk
374 - if(!(minor % 16)) {
375 - def_enabled = enable_new_disks;
376 - }
377 - break;
378 - case 86: // I2O hard disk
379 - if(!(minor % 16)) {
380 - def_enabled = enable_new_disks;
381 - }
382 - break;
383 - case 87: // I2O hard disk
384 - if(!(minor % 16)) {
385 - def_enabled = enable_new_disks;
386 - }
387 - break;
388 - case 128: // SCSI disk devices (128-143)
389 - if(!(minor % 16)) {
390 - def_enabled = enable_new_disks;
391 - }
392 - break;
393 - case 129: // SCSI disk devices (144-159)
394 - if(!(minor % 16)) {
395 - def_enabled = enable_new_disks;
396 - }
397 - break;
398 - case 130: // SCSI disk devices (160-175)
399 - if(!(minor % 16)) {
400 - def_enabled = enable_new_disks;
401 - }
402 - break;
403 - case 131: // SCSI disk devices (176-191)
404 - if(!(minor % 16)) {
405 - def_enabled = enable_new_disks;
406 - }
407 - break;
408 - case 132: // SCSI disk devices (192-207)
409 - if(!(minor % 16)) {
410 - def_enabled = enable_new_disks;
411 - }
412 - break;
413 - case 133: // SCSI disk devices (208-223)
414 - if(!(minor % 16)) {
415 - def_enabled = enable_new_disks;
416 - }
417 - break;
418 - case 134: // SCSI disk devices (224-239)
419 - if(!(minor % 16)) {
420 - def_enabled = enable_new_disks;
421 - }
422 - break;
423 - case 135: // SCSI disk devices (240-255)
424 - if(!(minor % 16)) {
425 - def_enabled = enable_new_disks;
426 - }
427 - break;
428 - case 136: // Mylex DAC960 PCI RAID controller; nineth controller
429 - if(!(minor % 8)) {
430 - def_enabled = enable_new_disks;
431 - }
432 - break;
433 - case 137: // Mylex DAC960 PCI RAID controller; tenth controller
434 - if(!(minor % 8)) {
435 - def_enabled = enable_new_disks;
436 - }
437 - break;
438 - case 138: // Mylex DAC960 PCI RAID controller; eleventh controller
439 - if(!(minor % 8)) {
440 - def_enabled = enable_new_disks;
441 - }
442 - break;
443 - case 139: // Mylex DAC960 PCI RAID controller; twelfth controller
444 - if(!(minor % 8)) {
445 - def_enabled = enable_new_disks;
446 - }
447 - break;
448 - case 140: // Mylex DAC960 PCI RAID controller; thirteenth controller
449 - if(!(minor % 8)) {
450 - def_enabled = enable_new_disks;
451 - }
452 - break;
453 - case 141: // Mylex DAC960 PCI RAID controller; fourteenth controller
454 - if(!(minor % 8)) {
455 - def_enabled = enable_new_disks;
456 - }
457 - break;
458 - case 142: // Mylex DAC960 PCI RAID controller; fifteenth controller
459 - if(!(minor % 8)) {
460 - def_enabled = enable_new_disks;
461 - }
462 - break;
463 - case 143: // Mylex DAC960 PCI RAID controller; sixteenth controller
464 - if(!(minor % 8)) {
465 - def_enabled = enable_new_disks;
466 - }
467 - break;
468 - case 160: // Carmel 8-port SATA Disks on First Controller
469 - if(!(minor % 32)) {
470 - def_enabled = enable_new_disks;
471 - }
472 - break;
473 - case 161: // Carmel 8-port SATA Disks on Second Controller
474 - if(!(minor % 32)) {
475 - def_enabled = enable_new_disks;
476 - }
477 - break;
478 - default:
479 - def_enabled = 0;
480 - break;
481 - }
482 - */
483 -
247 + // Find mount point and family
248 char *mount_point = d->mount_point;
249 char *family = d->mount_point;
250 if(!family) family = disk;
251
488 - 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;
252 + // --------------------------------------------------------------------------
253 + // Check if device is enabled by autodetection or config
254 + int def_enable = -1;
255 + char var_name[4096 + 1];
256 + snprintfz(var_name, 4096, "plugin:proc:/proc/diskstats:%s", disk);
257 +
258 + if(def_enable == -1) def_enable = config_get_boolean_ondemand(var_name, "enable", CONFIG_ONDEMAND_ONDEMAND);
259 + if(def_enable == CONFIG_ONDEMAND_NO) continue;
260 +
261 + int def_performance = CONFIG_ONDEMAND_NO, def_space = CONFIG_ONDEMAND_NO;
262 + if(enable_autodetection) {
263 + if(enable_physical_disks && (d->type == DISK_TYPE_PHYSICAL)) {
264 + def_performance = enable_physical_disks;
265 + } else if(enable_virtual_disks && (d->type == DISK_TYPE_CONTAINER)) {
266 + def_performance = enable_virtual_disks;
267 + } else if(enable_partitions && (d->type == DISK_TYPE_PARTITION)) {
268 + def_performance = enable_partitions;
269 + } else if(enable_mountpoints && (d->mount_point != NULL)) {
270 + def_performance = enable_mountpoints;
271 + }
272 +
273 + if(enable_space_metrics && (d->mount_point != NULL)) {
274 + def_space = enable_space_metrics;
275 + }
276 + }
277
490 - // check which charts are enabled for this disk
491 - {
492 - char var_name[4096 + 1];
493 - snprintfz(var_name, 4096, "plugin:proc:/proc/diskstats:%s", disk);
494 - def_enabled = config_get_boolean_ondemand(var_name, "enabled", def_enabled);
495 - if(def_enabled == CONFIG_ONDEMAND_NO) continue;
496 - if(def_enabled == CONFIG_ONDEMAND_ONDEMAND && !reads && !writes) continue;
278 + RRDSET *st;
279
280 + // --------------------------------------------------------------------------
281 + // Do performance metrics
282 + def_performance = config_get_boolean_ondemand(var_name, "enable performance metrics", def_performance);
283 + if( (def_performance == CONFIG_ONDEMAND_YES) || (def_performance == CONFIG_ONDEMAND_ONDEMAND && reads && writes) ) {
284 + 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;
285
286 ddo_io = config_get_boolean_ondemand(var_name, "bandwidth", ddo_io);
287 ddo_ops = config_get_boolean_ondemand(var_name, "operations", ddo_ops);
@@ -503,7 +290,6 @@ int do_proc_diskstats(int update_every, unsigned long long dt) {
290 ddo_qops = config_get_boolean_ondemand(var_name, "queued operations", ddo_qops);
291 ddo_util = config_get_boolean_ondemand(var_name, "utilization percentage", ddo_util);
292 ddo_backlog = config_get_boolean_ondemand(var_name, "backlog", ddo_backlog);
506 - ddo_space = config_get_boolean_ondemand(var_name, "space", ddo_space);
293
294 // by default, do not add charts that do not have values
295 if(ddo_io == CONFIG_ONDEMAND_ONDEMAND && !reads && !writes) ddo_io = 0;
@@ -516,246 +302,241 @@ int do_proc_diskstats(int update_every, unsigned long long dt) {
302 // for absolute values, we need to switch the setting to 'yes'
303 // to allow it refresh from now on
304 if(ddo_qops == CONFIG_ONDEMAND_ONDEMAND) config_set(var_name, "queued operations", "yes");
519 - }
520 -
521 - RRDSET *st;
522 -
523 - // --------------------------------------------------------------------
305
525 - int sector_size = 512;
526 - if(ddo_io) {
527 - st = rrdset_find_bytype(RRD_TYPE_DISK, disk);
528 - if(!st) {
529 - char tf[FILENAME_MAX + 1], *t;
530 - char ssfilename[FILENAME_MAX + 1];
531 -
532 - strncpyz(tf, disk, FILENAME_MAX);
533 -
534 - // replace all / with !
535 - while((t = strchr(tf, '/'))) *t = '!';
536 -
537 - snprintfz(ssfilename, FILENAME_MAX, path_to_get_hw_sector_size, tf);
538 - FILE *fpss = fopen(ssfilename, "r");
539 - if(fpss) {
540 - char ssbuffer[1025];
541 - char *tmp = fgets(ssbuffer, 1024, fpss);
542 -
543 - if(tmp) {
544 - sector_size = atoi(tmp);
545 - if(sector_size <= 0) {
546 - error("Invalid sector size %d for device %s in %s. Assuming 512.", sector_size, disk, ssfilename);
547 - sector_size = 512;
306 + // --------------------------------------------------------------------
307 + int sector_size = 512;
308 + if(ddo_io) {
309 + st = rrdset_find_bytype(RRD_TYPE_DISK, disk);
310 + if(!st) {
311 + char tf[FILENAME_MAX + 1], *t;
312 + char ssfilename[FILENAME_MAX + 1];
313 +
314 + strncpyz(tf, disk, FILENAME_MAX);
315 +
316 + // replace all / with !
317 + while((t = strchr(tf, '/'))) *t = '!';
318 +
319 + snprintfz(ssfilename, FILENAME_MAX, path_to_get_hw_sector_size, tf);
320 + FILE *fpss = fopen(ssfilename, "r");
321 + if(fpss) {
322 + char ssbuffer[1025];
323 + char *tmp = fgets(ssbuffer, 1024, fpss);
324 +
325 + if(tmp) {
326 + sector_size = atoi(tmp);
327 + if(sector_size <= 0) {
328 + error("Invalid sector size %d for device %s in %s. Assuming 512.", sector_size, disk, ssfilename);
329 + sector_size = 512;
330 + }
331 }
549 - }
550 - else error("Cannot read data for sector size for device %s from %s. Assuming 512.", disk, ssfilename);
551 -
552 - fclose(fpss);
553 - }
554 - else error("Cannot read sector size for device %s from %s. Assuming 512.", disk, ssfilename);
555 -
556 - st = rrdset_create(RRD_TYPE_DISK, disk, NULL, family, "disk.io", "Disk I/O Bandwidth", "kilobytes/s", 2000, update_every, RRDSET_TYPE_AREA);
557 -
558 - rrddim_add(st, "reads", NULL, sector_size, 1024, RRDDIM_INCREMENTAL);
559 - rrddim_add(st, "writes", NULL, sector_size * -1, 1024, RRDDIM_INCREMENTAL);
560 - }
561 - else rrdset_next_usec(st, dt);
562 -
563 - last_readsectors = rrddim_set(st, "reads", readsectors);
564 - last_writesectors = rrddim_set(st, "writes", writesectors);
565 - rrdset_done(st);
566 - }
567 -
568 - // --------------------------------------------------------------------
569 -
570 - if(ddo_ops) {
571 - st = rrdset_find_bytype("disk_ops", disk);
572 - if(!st) {
573 - st = rrdset_create("disk_ops", disk, NULL, family, "disk.ops", "Disk Completed I/O Operations", "operations/s", 2001, update_every, RRDSET_TYPE_LINE);
574 - st->isdetail = 1;
575 -
576 - rrddim_add(st, "reads", NULL, 1, 1, RRDDIM_INCREMENTAL);
577 - rrddim_add(st, "writes", NULL, -1, 1, RRDDIM_INCREMENTAL);
578 - }
579 - else rrdset_next_usec(st, dt);
580 -
581 - last_reads = rrddim_set(st, "reads", reads);
582 - last_writes = rrddim_set(st, "writes", writes);
583 - rrdset_done(st);
584 - }
585 -
586 - // --------------------------------------------------------------------
587 -
588 - if(ddo_qops) {
589 - st = rrdset_find_bytype("disk_qops", disk);
590 - if(!st) {
591 - st = rrdset_create("disk_qops", disk, NULL, family, "disk.qops", "Disk Current I/O Operations", "operations", 2002, update_every, RRDSET_TYPE_LINE);
592 - st->isdetail = 1;
593 -
594 - rrddim_add(st, "operations", NULL, 1, 1, RRDDIM_ABSOLUTE);
595 - }
596 - else rrdset_next_usec(st, dt);
597 -
598 - rrddim_set(st, "operations", queued_ios);
599 - rrdset_done(st);
600 - }
601 -
602 - // --------------------------------------------------------------------
603 -
604 - if(ddo_backlog) {
605 - st = rrdset_find_bytype("disk_backlog", disk);
606 - if(!st) {
607 - st = rrdset_create("disk_backlog", disk, NULL, family, "disk.backlog", "Disk Backlog", "backlog (ms)", 2003, update_every, RRDSET_TYPE_AREA);
608 - st->isdetail = 1;
332 + else error("Cannot read data for sector size for device %s from %s. Assuming 512.", disk, ssfilename);
333
610 - rrddim_add(st, "backlog", NULL, 1, 10, RRDDIM_INCREMENTAL);
611 - }
612 - else rrdset_next_usec(st, dt);
613 -
614 - rrddim_set(st, "backlog", backlog_ms);
615 - rrdset_done(st);
616 - }
334 + fclose(fpss);
335 + }
336 + else error("Cannot read sector size for device %s from %s. Assuming 512.", disk, ssfilename);
337
618 - // --------------------------------------------------------------------
338 + st = rrdset_create(RRD_TYPE_DISK, disk, NULL, family, "disk.io", "Disk I/O Bandwidth", "kilobytes/s", 2000, update_every, RRDSET_TYPE_AREA);
339
620 - if(ddo_util) {
621 - st = rrdset_find_bytype("disk_util", disk);
622 - if(!st) {
623 - st = rrdset_create("disk_util", disk, NULL, family, "disk.util", "Disk Utilization Time", "% of time working", 2004, update_every, RRDSET_TYPE_AREA);
624 - st->isdetail = 1;
340 + rrddim_add(st, "reads", NULL, sector_size, 1024, RRDDIM_INCREMENTAL);
341 + rrddim_add(st, "writes", NULL, sector_size * -1, 1024, RRDDIM_INCREMENTAL);
342 + }
343 + else rrdset_next_usec(st, dt);
344
626 - rrddim_add(st, "utilization", NULL, 1, 10, RRDDIM_INCREMENTAL);
345 + last_readsectors = rrddim_set(st, "reads", readsectors);
346 + last_writesectors = rrddim_set(st, "writes", writesectors);
347 + rrdset_done(st);
348 }
628 - else rrdset_next_usec(st, dt);
629 -
630 - last_busy_ms = rrddim_set(st, "utilization", busy_ms);
631 - rrdset_done(st);
632 - }
349
634 - // --------------------------------------------------------------------
350 + // --------------------------------------------------------------------
351 + if(ddo_ops) {
352 + st = rrdset_find_bytype("disk_ops", disk);
353 + if(!st) {
354 + st = rrdset_create("disk_ops", disk, NULL, family, "disk.ops", "Disk Completed I/O Operations", "operations/s", 2001, update_every, RRDSET_TYPE_LINE);
355 + st->isdetail = 1;
356
636 - if(ddo_mops) {
637 - st = rrdset_find_bytype("disk_mops", disk);
638 - if(!st) {
639 - st = rrdset_create("disk_mops", disk, NULL, family, "disk.mops", "Disk Merged Operations", "merged operations/s", 2021, update_every, RRDSET_TYPE_LINE);
640 - st->isdetail = 1;
357 + rrddim_add(st, "reads", NULL, 1, 1, RRDDIM_INCREMENTAL);
358 + rrddim_add(st, "writes", NULL, -1, 1, RRDDIM_INCREMENTAL);
359 + }
360 + else rrdset_next_usec(st, dt);
361
642 - rrddim_add(st, "reads", NULL, 1, 1, RRDDIM_INCREMENTAL);
643 - rrddim_add(st, "writes", NULL, -1, 1, RRDDIM_INCREMENTAL);
362 + last_reads = rrddim_set(st, "reads", reads);
363 + last_writes = rrddim_set(st, "writes", writes);
364 + rrdset_done(st);
365 }
645 - else rrdset_next_usec(st, dt);
646 -
647 - rrddim_set(st, "reads", mreads);
648 - rrddim_set(st, "writes", mwrites);
649 - rrdset_done(st);
650 - }
366
652 - // --------------------------------------------------------------------
367 + // --------------------------------------------------------------------
368 + if(ddo_qops) {
369 + st = rrdset_find_bytype("disk_qops", disk);
370 + if(!st) {
371 + st = rrdset_create("disk_qops", disk, NULL, family, "disk.qops", "Disk Current I/O Operations", "operations", 2002, update_every, RRDSET_TYPE_LINE);
372 + st->isdetail = 1;
373
654 - if(ddo_iotime) {
655 - st = rrdset_find_bytype("disk_iotime", disk);
656 - if(!st) {
657 - st = rrdset_create("disk_iotime", disk, NULL, family, "disk.iotime", "Disk Total I/O Time", "milliseconds/s", 2022, update_every, RRDSET_TYPE_LINE);
658 - st->isdetail = 1;
374 + rrddim_add(st, "operations", NULL, 1, 1, RRDDIM_ABSOLUTE);
375 + }
376 + else rrdset_next_usec(st, dt);
377
660 - rrddim_add(st, "reads", NULL, 1, 1, RRDDIM_INCREMENTAL);
661 - rrddim_add(st, "writes", NULL, -1, 1, RRDDIM_INCREMENTAL);
378 + rrddim_set(st, "operations", queued_ios);
379 + rrdset_done(st);
380 }
663 - else rrdset_next_usec(st, dt);
381
665 - last_readms = rrddim_set(st, "reads", readms);
666 - last_writems = rrddim_set(st, "writes", writems);
667 - rrdset_done(st);
668 - }
669 -
670 - // --------------------------------------------------------------------
671 -
672 - if(ddo_space && mount_point) {
673 - // collect space metrics using statvfs
674 - if (statvfs(mount_point, &buff_statvfs) < 0) {
675 - error("Failed checking disk space usage of %s", family);
676 - } else {
677 - // verify we collected the metrics for the right disk.
678 - // if not the mountpoint has changed.
679 - if(stat(mount_point, &buff_stat) == -1) {
680 - } else {
681 - if(major(buff_stat.st_dev) == major && minor(buff_stat.st_dev) == minor)
682 - {
683 - space_avail = buff_statvfs.f_bavail * buff_statvfs.f_bsize;
684 - space_avail_root = (buff_statvfs.f_bfree - buff_statvfs.f_bavail) * buff_statvfs.f_bsize;
685 - space_used = (buff_statvfs.f_blocks - buff_statvfs.f_bfree) * buff_statvfs.f_bsize;
686 -
687 - st = rrdset_find_bytype("disk_space", disk);
688 - if(!st) {
689 - st = rrdset_create("disk_space", disk, NULL, family, "disk.space", "Disk Space Usage", "GB", 2023, update_every, RRDSET_TYPE_STACKED);
690 - st->isdetail = 1;
691 -
692 - rrddim_add(st, "avail", NULL, 1, 1000*1000*1000, RRDDIM_ABSOLUTE);
693 - rrddim_add(st, "reserved_for_root", "reserved for root", 1, 1000*1000*1000, RRDDIM_ABSOLUTE);
694 - rrddim_add(st, "used" , NULL, 1, 1000*1000*1000, RRDDIM_ABSOLUTE);
695 - }
696 - else rrdset_next_usec(st, dt);
382 + // --------------------------------------------------------------------
383 + if(ddo_backlog) {
384 + st = rrdset_find_bytype("disk_backlog", disk);
385 + if(!st) {
386 + st = rrdset_create("disk_backlog", disk, NULL, family, "disk.backlog", "Disk Backlog", "backlog (ms)", 2003, update_every, RRDSET_TYPE_AREA);
387 + st->isdetail = 1;
388
698 - rrddim_set(st, "avail", space_avail);
699 - rrddim_set(st, "reserved_for_root", space_avail_root);
700 - rrddim_set(st, "used", space_used);
701 - rrdset_done(st);
702 - }
389 + rrddim_add(st, "backlog", NULL, 1, 10, RRDDIM_INCREMENTAL);
390 }
704 - }
705 - }
391 + else rrdset_next_usec(st, dt);
392
707 - // --------------------------------------------------------------------
708 - // calculate differential charts
709 - // only if this is not the first time we run
393 + rrddim_set(st, "backlog", backlog_ms);
394 + rrdset_done(st);
395 + }
396
711 - if(dt) {
712 - if(ddo_iotime && ddo_ops) {
713 - st = rrdset_find_bytype("disk_await", disk);
397 + // --------------------------------------------------------------------
398 + if(ddo_util) {
399 + st = rrdset_find_bytype("disk_util", disk);
400 if(!st) {
715 - st = rrdset_create("disk_await", disk, NULL, family, "disk.await", "Average Completed I/O Operation Time", "ms per operation", 2005, update_every, RRDSET_TYPE_LINE);
401 + st = rrdset_create("disk_util", disk, NULL, family, "disk.util", "Disk Utilization Time", "% of time working", 2004, update_every, RRDSET_TYPE_AREA);
402 st->isdetail = 1;
403
718 - rrddim_add(st, "reads", NULL, 1, 1, RRDDIM_ABSOLUTE);
719 - rrddim_add(st, "writes", NULL, -1, 1, RRDDIM_ABSOLUTE);
404 + rrddim_add(st, "utilization", NULL, 1, 10, RRDDIM_INCREMENTAL);
405 }
406 else rrdset_next_usec(st, dt);
407
723 - rrddim_set(st, "reads", (reads - last_reads) ? (readms - last_readms) / (reads - last_reads) : 0);
724 - rrddim_set(st, "writes", (writes - last_writes) ? (writems - last_writems) / (writes - last_writes) : 0);
408 + last_busy_ms = rrddim_set(st, "utilization", busy_ms);
409 rrdset_done(st);
410 }
411
728 - if(ddo_io && ddo_ops) {
729 - st = rrdset_find_bytype("disk_avgsz", disk);
412 + // --------------------------------------------------------------------
413 + if(ddo_mops) {
414 + st = rrdset_find_bytype("disk_mops", disk);
415 if(!st) {
731 - st = rrdset_create("disk_avgsz", disk, NULL, family, "disk.avgsz", "Average Completed I/O Operation Bandwidth", "kilobytes per operation", 2006, update_every, RRDSET_TYPE_AREA);
416 + st = rrdset_create("disk_mops", disk, NULL, family, "disk.mops", "Disk Merged Operations", "merged operations/s", 2021, update_every, RRDSET_TYPE_LINE);
417 st->isdetail = 1;
418
734 - rrddim_add(st, "reads", NULL, sector_size, 1024, RRDDIM_ABSOLUTE);
735 - rrddim_add(st, "writes", NULL, -sector_size, 1024, RRDDIM_ABSOLUTE);
419 + rrddim_add(st, "reads", NULL, 1, 1, RRDDIM_INCREMENTAL);
420 + rrddim_add(st, "writes", NULL, -1, 1, RRDDIM_INCREMENTAL);
421 }
422 else rrdset_next_usec(st, dt);
423
739 - rrddim_set(st, "reads", (reads - last_reads) ? (readsectors - last_readsectors) / (reads - last_reads) : 0);
740 - rrddim_set(st, "writes", (writes - last_writes) ? (writesectors - last_writesectors) / (writes - last_writes) : 0);
424 + rrddim_set(st, "reads", mreads);
425 + rrddim_set(st, "writes", mwrites);
426 rrdset_done(st);
427 }
428
744 - if(ddo_util && ddo_ops) {
745 - st = rrdset_find_bytype("disk_svctm", disk);
429 + // --------------------------------------------------------------------
430 + if(ddo_iotime) {
431 + st = rrdset_find_bytype("disk_iotime", disk);
432 if(!st) {
747 - st = rrdset_create("disk_svctm", disk, NULL, family, "disk.svctm", "Average Service Time", "ms per operation", 2007, update_every, RRDSET_TYPE_LINE);
433 + st = rrdset_create("disk_iotime", disk, NULL, family, "disk.iotime", "Disk Total I/O Time", "milliseconds/s", 2022, update_every, RRDSET_TYPE_LINE);
434 st->isdetail = 1;
435
750 - rrddim_add(st, "svctm", NULL, 1, 1, RRDDIM_ABSOLUTE);
436 + rrddim_add(st, "reads", NULL, 1, 1, RRDDIM_INCREMENTAL);
437 + rrddim_add(st, "writes", NULL, -1, 1, RRDDIM_INCREMENTAL);
438 }
439 else rrdset_next_usec(st, dt);
440
754 - rrddim_set(st, "svctm", ((reads - last_reads) + (writes - last_writes)) ? (busy_ms - last_busy_ms) / ((reads - last_reads) + (writes - last_writes)) : 0);
441 + last_readms = rrddim_set(st, "reads", readms);
442 + last_writems = rrddim_set(st, "writes", writems);
443 rrdset_done(st);
444 }
445 +
446 + // --------------------------------------------------------------------
447 + // calculate differential charts
448 + // only if this is not the first time we run
449 + if(dt) {
450 + if(ddo_iotime && ddo_ops) {
451 + st = rrdset_find_bytype("disk_await", disk);
452 + if(!st) {
453 + st = rrdset_create("disk_await", disk, NULL, family, "disk.await", "Average Completed I/O Operation Time", "ms per operation", 2005, update_every, RRDSET_TYPE_LINE);
454 + st->isdetail = 1;
455 +
456 + rrddim_add(st, "reads", NULL, 1, 1, RRDDIM_ABSOLUTE);
457 + rrddim_add(st, "writes", NULL, -1, 1, RRDDIM_ABSOLUTE);
458 + }
459 + else rrdset_next_usec(st, dt);
460 +
461 + rrddim_set(st, "reads", (reads - last_reads) ? (readms - last_readms) / (reads - last_reads) : 0);
462 + rrddim_set(st, "writes", (writes - last_writes) ? (writems - last_writems) / (writes - last_writes) : 0);
463 + rrdset_done(st);
464 + }
465 +
466 + if(ddo_io && ddo_ops) {
467 + st = rrdset_find_bytype("disk_avgsz", disk);
468 + if(!st) {
469 + st = rrdset_create("disk_avgsz", disk, NULL, family, "disk.avgsz", "Average Completed I/O Operation Bandwidth", "kilobytes per operation", 2006, update_every, RRDSET_TYPE_AREA);
470 + st->isdetail = 1;
471 +
472 + rrddim_add(st, "reads", NULL, sector_size, 1024, RRDDIM_ABSOLUTE);
473 + rrddim_add(st, "writes", NULL, -sector_size, 1024, RRDDIM_ABSOLUTE);
474 + }
475 + else rrdset_next_usec(st, dt);
476 +
477 + rrddim_set(st, "reads", (reads - last_reads) ? (readsectors - last_readsectors) / (reads - last_reads) : 0);
478 + rrddim_set(st, "writes", (writes - last_writes) ? (writesectors - last_writesectors) / (writes - last_writes) : 0);
479 + rrdset_done(st);
480 + }
481 +
482 + if(ddo_util && ddo_ops) {
483 + st = rrdset_find_bytype("disk_svctm", disk);
484 + if(!st) {
485 + st = rrdset_create("disk_svctm", disk, NULL, family, "disk.svctm", "Average Service Time", "ms per operation", 2007, update_every, RRDSET_TYPE_LINE);
486 + st->isdetail = 1;
487 +
488 + rrddim_add(st, "svctm", NULL, 1, 1, RRDDIM_ABSOLUTE);
489 + }
490 + else rrdset_next_usec(st, dt);
491 +
492 + rrddim_set(st, "svctm", ((reads - last_reads) + (writes - last_writes)) ? (busy_ms - last_busy_ms) / ((reads - last_reads) + (writes - last_writes)) : 0);
493 + rrdset_done(st);
494 + }
495 + }
496 }
758 - }
497
498 + // --------------------------------------------------------------------------
499 + // Do space metrics
500 + def_space = config_get_boolean_ondemand(var_name, "enable space metrics", def_space);
501 + if(def_space != CONFIG_ONDEMAND_NO) {
502 + int ddo_space = do_space;
503 +
504 + ddo_space = config_get_boolean_ondemand(var_name, "space", ddo_space);
505 + if(ddo_space && mount_point) {
506 + // collect space metrics using statvfs
507 + if (statvfs(mount_point, &buff_statvfs) < 0) {
508 + error("Failed checking disk space usage of %s", family);
509 + } else {
510 + // verify we collected the metrics for the right disk.
511 + // if not the mountpoint has changed.
512 + if(stat(mount_point, &buff_stat) == -1) {
513 + } else {
514 + if(major(buff_stat.st_dev) == major && minor(buff_stat.st_dev) == minor)
515 + {
516 + space_avail = buff_statvfs.f_bavail * buff_statvfs.f_bsize;
517 + space_avail_root = (buff_statvfs.f_bfree - buff_statvfs.f_bavail) * buff_statvfs.f_bsize;
518 + space_used = (buff_statvfs.f_blocks - buff_statvfs.f_bfree) * buff_statvfs.f_bsize;
519 +
520 + st = rrdset_find_bytype("disk_space", disk);
521 + if(!st) {
522 + st = rrdset_create("disk_space", disk, NULL, family, "disk.space", "Disk Space Usage", "GB", 2023, update_every, RRDSET_TYPE_STACKED);
523 + st->isdetail = 1;
524 +
525 + rrddim_add(st, "avail", NULL, 1, 1000*1000*1000, RRDDIM_ABSOLUTE);
526 + rrddim_add(st, "reserved_for_root", "reserved for root", 1, 1000*1000*1000, RRDDIM_ABSOLUTE);
527 + rrddim_add(st, "used" , NULL, 1, 1000*1000*1000, RRDDIM_ABSOLUTE);
528 + }
529 + else rrdset_next_usec(st, dt);
530 +
531 + rrddim_set(st, "avail", space_avail);
532 + rrddim_set(st, "reserved_for_root", space_avail_root);
533 + rrddim_set(st, "used", space_used);
534 + rrdset_done(st);
535 + }
536 + }
537 + }
538 + }
539 + }
540 + }
541 return 0;
542 }