@cryptotaxi247 / netdata-1 / commits / f198b9663

Separate kern.devstat module with simple patterns adopted

Vladimir Kobal committed Mar 16, 2017 at 22:02 UTC f198b96633b63e15894ddabd01234cdcdbe9b321
1 file changed +528 -143
src/freebsd_sysctl.c
+528 -143
@@ -2750,6 +2750,8 @@ int do_getmntinfo(int update_every, usec_t dt) {
2750
2751 size_t collected; // the number of times this has been collected
2752
2753 + // charts and dimensions
2754 +
2755 RRDSET *st_space;
2756 RRDDIM *rd_space_used;
2757 RRDDIM *rd_space_avail;
@@ -3057,6 +3059,8 @@ int do_getifaddrs(int update_every, usec_t dt) {
3059 int do_drops;
3060 int do_events;
3061
3062 + // charts and dimensions
3063 +
3064 RRDSET *st_bandwidth;
3065 RRDDIM *rd_bandwidth_in;
3066 RRDDIM *rd_bandwidth_out;
@@ -3326,137 +3330,398 @@ int do_getifaddrs(int update_every, usec_t dt) {
3330 // kern.devstat
3331
3332 int do_kern_devstat(int update_every, usec_t dt) {
3329 - static int do_disk_io = -1;
3333
3331 - if (unlikely(do_disk_io == -1)) {
3332 - do_disk_io = config_get_boolean("plugin:freebsd:kern.devstat", "stats for all disks", 1);
3334 +#define DELAULT_EXLUDED_DISKS ""
3335 +#define CONFIG_SECTION_KERN_DEVSTAT "plugin:freebsd:kern.devstat"
3336 +#define BINTIME_SCALE 5.42101086242752217003726400434970855712890625e-17 // this is 1000/2^64
3337 +
3338 + static int enable_pass_devices = -1, do_system_io = -1, do_io = -1, do_ops = -1, do_qops = -1, do_util = -1,
3339 + do_iotime = -1, do_await = -1, do_avagsz = -1, do_svctm = -1;
3340 +
3341 + if (unlikely(enable_pass_devices == -1)) {
3342 + enable_pass_devices = config_get_boolean_ondemand(CONFIG_SECTION_KERN_DEVSTAT,
3343 + "performance metrics for pass devices", CONFIG_BOOLEAN_AUTO);
3344 +
3345 + do_system_io = config_get_boolean_ondemand(CONFIG_SECTION_KERN_DEVSTAT, "total bandwidth for all disks",
3346 + CONFIG_BOOLEAN_YES);
3347 +
3348 + do_io = config_get_boolean_ondemand(CONFIG_SECTION_KERN_DEVSTAT, "bandwidth for all disks",
3349 + CONFIG_BOOLEAN_AUTO);
3350 + do_ops = config_get_boolean_ondemand(CONFIG_SECTION_KERN_DEVSTAT, "operations for all disks",
3351 + CONFIG_BOOLEAN_AUTO);
3352 + do_qops = config_get_boolean_ondemand(CONFIG_SECTION_KERN_DEVSTAT, "queued operations for all disks",
3353 + CONFIG_BOOLEAN_AUTO);
3354 + do_util = config_get_boolean_ondemand(CONFIG_SECTION_KERN_DEVSTAT, "utilization percentage for all disks",
3355 + CONFIG_BOOLEAN_AUTO);
3356 + do_iotime = config_get_boolean_ondemand(CONFIG_SECTION_KERN_DEVSTAT, "i/o time for all disks",
3357 + CONFIG_BOOLEAN_AUTO);
3358 + do_await = config_get_boolean_ondemand(CONFIG_SECTION_KERN_DEVSTAT, "average completed i/o time for all disks",
3359 + CONFIG_BOOLEAN_AUTO);
3360 + do_avagsz = config_get_boolean_ondemand(CONFIG_SECTION_KERN_DEVSTAT, "average completed i/o bandwidth for all disks",
3361 + CONFIG_BOOLEAN_AUTO);
3362 + do_svctm = config_get_boolean_ondemand(CONFIG_SECTION_KERN_DEVSTAT, "average service time for all disks",
3363 + CONFIG_BOOLEAN_AUTO);
3364 }
3365
3335 - RRDSET *st;
3336 -
3337 - int i;
3338 -
3339 - #define RRD_TYPE_DISK "disk"
3340 - #define BINTIME_SCALE 5.42101086242752217003726400434970855712890625e-17 // this is 1000/2^64
3341 - int numdevs;
3342 - static void *devstat_data = NULL;
3343 - struct devstat *dstat;
3344 - char disk[DEVSTAT_NAME_LEN + MAX_INT_DIGITS + 1];
3345 - struct cur_dstat {
3346 - collected_number duration_read_ms;
3347 - collected_number duration_write_ms;
3348 - collected_number busy_time_ms;
3349 - } cur_dstat;
3350 - struct prev_dstat {
3351 - collected_number bytes_read;
3352 - collected_number bytes_write;
3353 - collected_number operations_read;
3354 - collected_number operations_write;
3355 - collected_number duration_read_ms;
3356 - collected_number duration_write_ms;
3357 - collected_number busy_time_ms;
3358 - } prev_dstat;
3366 + if (likely(do_system_io || do_io || do_ops || do_qops || do_util || do_iotime || do_await || do_avagsz || do_svctm)) {
3367 + static int mib_numdevs[3] = {0, 0, 0};
3368 + int numdevs;
3369 + int common_error = 0;
3370
3360 - // --------------------------------------------------------------------
3361 -
3362 - if (likely(do_disk_io)) {
3363 - if (unlikely(GETSYSCTL_BY_NAME("kern.devstat.numdevs", numdevs))) {
3364 - do_disk_io = 0;
3365 - error("DISABLED: disk.io");
3371 + if (unlikely(GETSYSCTL_SIMPLE("kern.devstat.numdevs", mib_numdevs, numdevs))) {
3372 + common_error = 1;
3373 } else {
3374 + static int mib_devstat[3] = {0, 0, 0};
3375 + static void *devstat_data = NULL;
3376 +
3377 devstat_data = reallocz(devstat_data, sizeof(long) + sizeof(struct devstat) * numdevs); // there is generation number before devstat structures
3368 - if (unlikely(
3369 - getsysctl_by_name("kern.devstat.all", devstat_data, sizeof(long) + sizeof(struct devstat) * numdevs))) {
3370 - do_disk_io = 0;
3371 - error("DISABLED: disk.io");
3378 + if (unlikely(GETSYSCTL_WSIZE("kern.devstat.all", mib_devstat, devstat_data,
3379 + sizeof(long) + sizeof(struct devstat) * numdevs))) {
3380 + common_error = 1;
3381 } else {
3373 - dstat = devstat_data + sizeof(long); // skip generation number
3382 + struct devstat *dstat;
3383 + int i;
3384 collected_number total_disk_kbytes_read = 0;
3385 collected_number total_disk_kbytes_write = 0;
3386
3377 - for (i = 0; i < numdevs; i++) {
3378 - if (((dstat[i].device_type & DEVSTAT_TYPE_MASK) == DEVSTAT_TYPE_DIRECT) || ((dstat[i].device_type & DEVSTAT_TYPE_MASK) == DEVSTAT_TYPE_STORARRAY)) {
3379 - sprintf(disk, "%s%d", dstat[i].device_name, dstat[i].unit_number);
3387 + // Data to be stored in DICTIONARY disks.
3388 + // This DICTIONARY is used to lookup the settings of the disks on each iteration.
3389 + struct disks_metadata {
3390 + int do_io;
3391 + int do_ops;
3392 + int do_qops;
3393 + int do_util;
3394 + int do_iotime;
3395 + int do_await;
3396 + int do_avagsz;
3397 + int do_svctm;
3398
3381 - // --------------------------------------------------------------------
3399
3383 - st = rrdset_find_bytype_localhost(RRD_TYPE_DISK, disk);
3384 - if (unlikely(!st)) {
3385 - st = rrdset_create_localhost(RRD_TYPE_DISK, disk, NULL, disk, "disk.io", "Disk I/O Bandwidth", "kilobytes/s", 2000, update_every, RRDSET_TYPE_AREA);
3400 + // data for differential charts
3401
3387 - rrddim_add(st, "reads", NULL, 1, 1024, RRD_ALGORITHM_INCREMENTAL);
3388 - rrddim_add(st, "writes", NULL, -1, 1024, RRD_ALGORITHM_INCREMENTAL);
3389 - }
3390 - else rrdset_next(st);
3402 + struct prev_dstat {
3403 + collected_number bytes_read;
3404 + collected_number bytes_write;
3405 + collected_number operations_read;
3406 + collected_number operations_write;
3407 + collected_number duration_read_ms;
3408 + collected_number duration_write_ms;
3409 + collected_number busy_time_ms;
3410 + } prev_dstat;
3411
3392 - total_disk_kbytes_read += dstat[i].bytes[DEVSTAT_READ]/KILO_FACTOR;
3393 - total_disk_kbytes_write += dstat[i].bytes[DEVSTAT_WRITE]/KILO_FACTOR;
3394 - prev_dstat.bytes_read = rrddim_set(st, "reads", dstat[i].bytes[DEVSTAT_READ]);
3395 - prev_dstat.bytes_write = rrddim_set(st, "writes", dstat[i].bytes[DEVSTAT_WRITE]);
3396 - rrdset_done(st);
3412 + // charts and dimensions
3413
3398 - // --------------------------------------------------------------------
3414 + RRDSET *st_io;
3415 + RRDDIM *rd_io_in;
3416 + RRDDIM *rd_io_out;
3417 +
3418 + RRDSET *st_ops;
3419 + RRDDIM *rd_ops_in;
3420 + RRDDIM *rd_ops_out;
3421 +
3422 + RRDSET *st_qops;
3423 + RRDDIM *rd_qops;
3424
3400 - st = rrdset_find_bytype_localhost("disk_ops", disk);
3401 - if (unlikely(!st)) {
3402 - st = rrdset_create_localhost("disk_ops", disk, NULL, disk, "disk.ops", "Disk Completed I/O Operations", "operations/s", 2001, update_every, RRDSET_TYPE_LINE);
3403 - rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
3425 + RRDSET *st_util;
3426 + RRDDIM *rd_util;
3427
3405 - rrddim_add(st, "reads", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
3406 - rrddim_add(st, "writes", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
3428 + RRDSET *st_iotime;
3429 + RRDDIM *rd_iotime_in;
3430 + RRDDIM *rd_iotime_out;
3431 +
3432 + RRDSET *st_await;
3433 + RRDDIM *rd_await_in;
3434 + RRDDIM *rd_await_out;
3435 +
3436 + RRDSET *st_avagsz;
3437 + RRDDIM *rd_avagsz_in;
3438 + RRDDIM *rd_avagsz_out;
3439 +
3440 + RRDSET *st_svctm;
3441 + RRDDIM *rd_svctm;
3442 +
3443 + };
3444 + static DICTIONARY *disks = NULL;
3445 + static SIMPLE_PATTERN *excluded_disks = NULL;
3446 +
3447 + if(unlikely(!disks)) {
3448 +
3449 + excluded_disks = simple_pattern_create(
3450 + config_get(CONFIG_SECTION_KERN_DEVSTAT, "disable by default disks matching",
3451 + DELAULT_EXLUDED_DISKS)
3452 + , SIMPLE_PATTERN_EXACT
3453 + );
3454 +
3455 + disks = dictionary_create(DICTIONARY_FLAG_SINGLE_THREADED);
3456 + }
3457 +
3458 + dstat = devstat_data + sizeof(long); // skip generation number
3459 +
3460 + for (i = 0; i < numdevs; i++) {
3461 + if (unlikely(!do_system_io)) {
3462 + if (((dstat[i].device_type & DEVSTAT_TYPE_MASK) == DEVSTAT_TYPE_DIRECT) || ((dstat[i].device_type & DEVSTAT_TYPE_MASK) == DEVSTAT_TYPE_STORARRAY)) {
3463 + total_disk_kbytes_read += dstat[i].bytes[DEVSTAT_READ] / KILO_FACTOR;
3464 + total_disk_kbytes_write += dstat[i].bytes[DEVSTAT_WRITE] / KILO_FACTOR;
3465 }
3408 - else rrdset_next(st);
3466 + }
3467
3410 - prev_dstat.operations_read = rrddim_set(st, "reads", dstat[i].operations[DEVSTAT_READ]);
3411 - prev_dstat.operations_write = rrddim_set(st, "writes", dstat[i].operations[DEVSTAT_WRITE]);
3412 - rrdset_done(st);
3468 + if (unlikely(!enable_pass_devices))
3469 + if (dstat[i].device_type & DEVSTAT_TYPE_PASS == DEVSTAT_TYPE_PASS)
3470 + continue;
3471
3414 - // --------------------------------------------------------------------
3472 + if (((dstat[i].device_type & DEVSTAT_TYPE_MASK) == DEVSTAT_TYPE_DIRECT) || ((dstat[i].device_type & DEVSTAT_TYPE_MASK) == DEVSTAT_TYPE_STORARRAY)) {
3473 + char disk[DEVSTAT_NAME_LEN + MAX_INT_DIGITS + 1];
3474 + int def_io, def_ops, def_qops, def_util, def_iotime, def_await, def_avagsz, def_svctm,
3475 + iter_io, iter_ops, iter_qops, iter_util, iter_iotime, iter_await, iter_avagsz, iter_svctm;
3476 + struct cur_dstat {
3477 + collected_number duration_read_ms;
3478 + collected_number duration_write_ms;
3479 + collected_number busy_time_ms;
3480 + } cur_dstat;
3481 +
3482 + sprintf(disk, "%s%d", dstat[i].device_name, dstat[i].unit_number);
3483
3416 - st = rrdset_find_bytype_localhost("disk_qops", disk);
3417 - if (unlikely(!st)) {
3418 - st = rrdset_create_localhost("disk_qops", disk, NULL, disk, "disk.qops", "Disk Current I/O Operations", "operations", 2002, update_every, RRDSET_TYPE_LINE);
3419 - rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
3484 + struct disks_metadata *dm = dictionary_get(disks, disk);
3485 + if(unlikely(!dm)) {
3486 + char var_name[4096 + 1];
3487 + snprintfz(var_name, 4096, "%s:%s", CONFIG_SECTION_KERN_DEVSTAT, disk);
3488 +
3489 + def_io = do_io;
3490 + def_ops = do_ops;
3491 + def_qops = do_qops;
3492 + def_util = do_util;
3493 + def_iotime = do_iotime;
3494 + def_await = do_await;
3495 + def_avagsz = do_avagsz;
3496 + def_svctm = do_svctm;
3497 +
3498 + if(unlikely(simple_pattern_matches(excluded_disks, disk))) {
3499 + def_io = CONFIG_BOOLEAN_NO;
3500 + def_ops = CONFIG_BOOLEAN_NO;
3501 + def_qops = CONFIG_BOOLEAN_NO;
3502 + def_util = CONFIG_BOOLEAN_NO;
3503 + def_iotime = CONFIG_BOOLEAN_NO;
3504 + def_await = CONFIG_BOOLEAN_NO;
3505 + def_avagsz = CONFIG_BOOLEAN_NO;
3506 + def_svctm = CONFIG_BOOLEAN_NO;
3507 + }
3508
3421 - rrddim_add(st, "operations", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
3509 + iter_io = config_get_boolean_ondemand(var_name, "bandwidth", def_io);
3510 + iter_ops = config_get_boolean_ondemand(var_name, "operations", def_ops);
3511 + iter_qops = config_get_boolean_ondemand(var_name, "queued operations", def_qops);
3512 + iter_util = config_get_boolean_ondemand(var_name, "utilization percentage", def_util);
3513 + iter_iotime = config_get_boolean_ondemand(var_name, "i/o time", def_iotime);
3514 + iter_await = config_get_boolean_ondemand(var_name, "average completed i/o time", def_await);
3515 + iter_avagsz = config_get_boolean_ondemand(var_name, "average completed i/o bandwidth",
3516 + def_avagsz);
3517 + iter_svctm = config_get_boolean_ondemand(var_name, "average service time", def_svctm);
3518 +
3519 + struct disks_metadata dmp = {
3520 + .do_io = iter_io,
3521 + .do_ops = iter_ops,
3522 + .do_qops = iter_qops,
3523 + .do_util = iter_util,
3524 + .do_iotime = iter_iotime,
3525 + .do_await = iter_await,
3526 + .do_avagsz = iter_avagsz,
3527 + .do_svctm = iter_svctm,
3528 +
3529 + // initialise data for differential charts
3530 +
3531 + .prev_dstat.bytes_read = dstat[i].bytes[DEVSTAT_READ],
3532 + .prev_dstat.bytes_write = dstat[i].bytes[DEVSTAT_WRITE],
3533 + .prev_dstat.operations_read = dstat[i].operations[DEVSTAT_READ],
3534 + .prev_dstat.operations_write = dstat[i].operations[DEVSTAT_WRITE],
3535 + .prev_dstat.duration_read_ms = dstat[i].duration[DEVSTAT_READ].sec * 1000
3536 + + dstat[i].duration[DEVSTAT_READ].frac * BINTIME_SCALE,
3537 + .prev_dstat.duration_write_ms = dstat[i].duration[DEVSTAT_WRITE].sec * 1000
3538 + + dstat[i].duration[DEVSTAT_READ].frac * BINTIME_SCALE,
3539 + .prev_dstat.busy_time_ms = dstat[i].busy_time.sec * 1000
3540 + + dstat[i].busy_time.frac * BINTIME_SCALE,
3541 +
3542 + .st_io = NULL,
3543 + .rd_io_in = NULL,
3544 + .rd_io_out = NULL,
3545 +
3546 + .st_ops = NULL,
3547 + .rd_ops_in = NULL,
3548 + .rd_ops_out = NULL,
3549 +
3550 + .st_qops = NULL,
3551 + .rd_qops = NULL,
3552 +
3553 + .st_util = NULL,
3554 + .rd_util = NULL,
3555 +
3556 + .st_iotime = NULL,
3557 + .rd_iotime_in = NULL,
3558 + .rd_iotime_out = NULL,
3559 +
3560 + .st_await = NULL,
3561 + .rd_await_in = NULL,
3562 + .rd_await_out = NULL,
3563 +
3564 + .st_avagsz = NULL,
3565 + .rd_avagsz_in = NULL,
3566 + .rd_avagsz_out = NULL,
3567 +
3568 + .st_svctm = NULL,
3569 + .rd_svctm = NULL,
3570 + };
3571 +
3572 + dm = dictionary_set(disks, disk, &dmp, sizeof(struct disks_metadata));
3573 }
3423 - else rrdset_next(st);
3574
3425 - rrddim_set(st, "operations", dstat[i].start_count - dstat[i].end_count);
3426 - rrdset_done(st);
3575 + cur_dstat.duration_read_ms = dstat[i].duration[DEVSTAT_READ].sec * 1000
3576 + + dstat[i].duration[DEVSTAT_READ].frac * BINTIME_SCALE;
3577 + cur_dstat.duration_write_ms = dstat[i].duration[DEVSTAT_WRITE].sec * 1000
3578 + + dstat[i].duration[DEVSTAT_READ].frac * BINTIME_SCALE;
3579 + cur_dstat.busy_time_ms = dstat[i].busy_time.sec * 1000 + dstat[i].busy_time.frac * BINTIME_SCALE;
3580
3581 // --------------------------------------------------------------------
3582
3430 - st = rrdset_find_bytype_localhost("disk_util", disk);
3431 - if (unlikely(!st)) {
3432 - st = rrdset_create_localhost("disk_util", disk, NULL, disk, "disk.util", "Disk Utilization Time", "% of time working", 2004, update_every, RRDSET_TYPE_AREA);
3433 - rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
3583 + if(dm->do_io == CONFIG_BOOLEAN_YES || (dm->do_io == CONFIG_BOOLEAN_AUTO &&
3584 + (dstat[i].bytes[DEVSTAT_READ] || dstat[i].bytes[DEVSTAT_WRITE]))) {
3585 + if (unlikely(!dm->st_io)) {
3586 + dm->st_io = rrdset_create_localhost("disk",
3587 + disk,
3588 + NULL,
3589 + disk,
3590 + "disk.io",
3591 + "Disk I/O Bandwidth",
3592 + "kilobytes/s",
3593 + 2000,
3594 + update_every,
3595 + RRDSET_TYPE_AREA
3596 + );
3597 +
3598 + dm->rd_io_in = rrddim_add(dm->st_io, "reads", NULL, 1, KILO_FACTOR,
3599 + RRD_ALGORITHM_INCREMENTAL);
3600 + dm->rd_io_out = rrddim_add(dm->st_io, "writes", NULL, -1, KILO_FACTOR,
3601 + RRD_ALGORITHM_INCREMENTAL);
3602 + } else
3603 + rrdset_next(dm->st_io);
3604
3435 - rrddim_add(st, "utilization", NULL, 1, 10, RRD_ALGORITHM_INCREMENTAL);
3605 + rrddim_set_by_pointer(dm->st_io, dm->rd_io_in, dstat[i].bytes[DEVSTAT_READ]);
3606 + rrddim_set_by_pointer(dm->st_io, dm->rd_io_out, dstat[i].bytes[DEVSTAT_WRITE]);
3607 + rrdset_done(dm->st_io);
3608 }
3437 - else rrdset_next(st);
3609
3439 - cur_dstat.busy_time_ms = dstat[i].busy_time.sec * 1000 + dstat[i].busy_time.frac * BINTIME_SCALE;
3440 - prev_dstat.busy_time_ms = rrddim_set(st, "utilization", cur_dstat.busy_time_ms);
3441 - rrdset_done(st);
3610 + // --------------------------------------------------------------------
3611 +
3612 + if(dm->do_ops == CONFIG_BOOLEAN_YES || (dm->do_ops == CONFIG_BOOLEAN_AUTO &&
3613 + (dstat[i].operations[DEVSTAT_READ] || dstat[i].operations[DEVSTAT_WRITE]))) {
3614 + if (unlikely(!dm->st_ops)) {
3615 + dm->st_ops = rrdset_create_localhost("disk_ops",
3616 + disk,
3617 + NULL,
3618 + disk,
3619 + "disk.ops",
3620 + "Disk Completed I/O Operations",
3621 + "operations/s",
3622 + 2001,
3623 + update_every,
3624 + RRDSET_TYPE_LINE
3625 + );
3626 +
3627 + rrdset_flag_set(dm->st_ops, RRDSET_FLAG_DETAIL);
3628 +
3629 + dm->rd_ops_in = rrddim_add(dm->st_ops, "reads", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
3630 + dm->rd_ops_out = rrddim_add(dm->st_ops, "writes", NULL, -1, 1,
3631 + RRD_ALGORITHM_INCREMENTAL);
3632 + } else
3633 + rrdset_next(dm->st_ops);
3634 +
3635 + rrddim_set_by_pointer(dm->st_ops, dm->rd_ops_in, dstat[i].operations[DEVSTAT_READ]);
3636 + rrddim_set_by_pointer(dm->st_ops, dm->rd_ops_out, dstat[i].operations[DEVSTAT_WRITE]);
3637 + rrdset_done(dm->st_ops);
3638 + }
3639
3640 // --------------------------------------------------------------------
3641
3445 - st = rrdset_find_bytype_localhost("disk_iotime", disk);
3446 - if (unlikely(!st)) {
3447 - st = rrdset_create_localhost("disk_iotime", disk, NULL, disk, "disk.iotime", "Disk Total I/O Time", "milliseconds/s", 2022, update_every, RRDSET_TYPE_LINE);
3448 - rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
3642 + if(dm->do_qops == CONFIG_BOOLEAN_YES || (dm->do_qops == CONFIG_BOOLEAN_AUTO &&
3643 + (dstat[i].start_count || dstat[i].end_count))) {
3644 + if (unlikely(!dm->st_qops)) {
3645 + dm->st_qops = rrdset_create_localhost("disk_qops",
3646 + disk,
3647 + NULL,
3648 + disk,
3649 + "disk.qops",
3650 + "Disk Current I/O Operations",
3651 + "operations",
3652 + 2002,
3653 + update_every,
3654 + RRDSET_TYPE_LINE
3655 + );
3656 +
3657 + rrdset_flag_set(dm->st_qops, RRDSET_FLAG_DETAIL);
3658 +
3659 + dm->rd_qops = rrddim_add(dm->st_qops, "operations", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
3660 + } else
3661 + rrdset_next(dm->st_qops);
3662 +
3663 + rrddim_set_by_pointer(dm->st_qops, dm->rd_qops, dstat[i].start_count - dstat[i].end_count);
3664 + rrdset_done(dm->st_qops);
3665 + }
3666 +
3667 + // --------------------------------------------------------------------
3668 +
3669 + if(dm->do_util == CONFIG_BOOLEAN_YES || (dm->do_util == CONFIG_BOOLEAN_AUTO &&
3670 + cur_dstat.busy_time_ms)) {
3671 + if (unlikely(!dm->st_util)) {
3672 + dm->st_util = rrdset_create_localhost("disk_util",
3673 + disk,
3674 + NULL,
3675 + disk,
3676 + "disk.util",
3677 + "Disk Utilization Time",
3678 + "% of time working",
3679 + 2004,
3680 + update_every,
3681 + RRDSET_TYPE_AREA
3682 + );
3683 +
3684 + rrdset_flag_set(dm->st_util, RRDSET_FLAG_DETAIL);
3685 +
3686 + dm->rd_util = rrddim_add(dm->st_util, "utilization", NULL, 1, 10,
3687 + RRD_ALGORITHM_INCREMENTAL);
3688 + } else
3689 + rrdset_next(dm->st_util);
3690
3450 - rrddim_add(st, "reads", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
3451 - rrddim_add(st, "writes", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
3691 + rrddim_set_by_pointer(dm->st_util, dm->rd_util, cur_dstat.busy_time_ms);
3692 + rrdset_done(dm->st_util);
3693 }
3453 - else rrdset_next(st);
3694
3455 - cur_dstat.duration_read_ms = dstat[i].duration[DEVSTAT_READ].sec * 1000 + dstat[i].duration[DEVSTAT_READ].frac * BINTIME_SCALE;
3456 - cur_dstat.duration_write_ms = dstat[i].duration[DEVSTAT_WRITE].sec * 1000 + dstat[i].duration[DEVSTAT_READ].frac * BINTIME_SCALE;
3457 - prev_dstat.duration_read_ms = rrddim_set(st, "reads", cur_dstat.duration_read_ms);
3458 - prev_dstat.duration_write_ms = rrddim_set(st, "writes", cur_dstat.duration_write_ms);
3459 - rrdset_done(st);
3695 + // --------------------------------------------------------------------
3696 +
3697 + if(dm->do_iotime == CONFIG_BOOLEAN_YES || (dm->do_iotime == CONFIG_BOOLEAN_AUTO &&
3698 + (cur_dstat.duration_read_ms || cur_dstat.duration_write_ms))) {
3699 + if (unlikely(!dm->st_iotime)) {
3700 + dm->st_iotime = rrdset_create_localhost("disk_iotime",
3701 + disk,
3702 + NULL,
3703 + disk,
3704 + "disk.iotime",
3705 + "Disk Total I/O Time",
3706 + "milliseconds/s",
3707 + 2022,
3708 + update_every,
3709 + RRDSET_TYPE_LINE
3710 + );
3711 +
3712 + rrdset_flag_set(dm->st_iotime, RRDSET_FLAG_DETAIL);
3713 +
3714 + dm->rd_iotime_in = rrddim_add(dm->st_iotime, "reads", NULL, 1, 1,
3715 + RRD_ALGORITHM_INCREMENTAL);
3716 + dm->rd_iotime_out = rrddim_add(dm->st_iotime, "writes", NULL, -1, 1,
3717 + RRD_ALGORITHM_INCREMENTAL);
3718 + } else
3719 + rrdset_next(dm->st_iotime);
3720 +
3721 + rrddim_set_by_pointer(dm->st_iotime, dm->rd_iotime_in, cur_dstat.duration_read_ms);
3722 + rrddim_set_by_pointer(dm->st_iotime, dm->rd_iotime_out, cur_dstat.duration_write_ms);
3723 + rrdset_done(dm->st_iotime);
3724 + }
3725
3726 // --------------------------------------------------------------------
3727 // calculate differential charts
@@ -3466,73 +3731,193 @@ int do_kern_devstat(int update_every, usec_t dt) {
3731
3732 // --------------------------------------------------------------------
3733
3469 - st = rrdset_find_bytype_localhost("disk_await", disk);
3470 - if (unlikely(!st)) {
3471 - st = rrdset_create_localhost("disk_await", disk, NULL, disk, "disk.await", "Average Completed I/O Operation Time", "ms per operation", 2005, update_every, RRDSET_TYPE_LINE);
3472 - rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
3473 -
3474 - rrddim_add(st, "reads", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
3475 - rrddim_add(st, "writes", NULL, -1, 1, RRD_ALGORITHM_ABSOLUTE);
3734 + if(dm->do_await == CONFIG_BOOLEAN_YES || (dm->do_await == CONFIG_BOOLEAN_AUTO &&
3735 + (dstat[i].operations[DEVSTAT_READ] || dstat[i].operations[DEVSTAT_WRITE]))) {
3736 + if (unlikely(!dm->st_await)) {
3737 + dm->st_await = rrdset_create_localhost("disk_await",
3738 + disk,
3739 + NULL,
3740 + disk,
3741 + "disk.await",
3742 + "Average Completed I/O Operation Time",
3743 + "ms per operation",
3744 + 2005,
3745 + update_every,
3746 + RRDSET_TYPE_LINE
3747 + );
3748 +
3749 + rrdset_flag_set(dm->st_await, RRDSET_FLAG_DETAIL);
3750 +
3751 + dm->rd_await_in = rrddim_add(dm->st_await, "reads", NULL, 1, 1,
3752 + RRD_ALGORITHM_ABSOLUTE);
3753 + dm->rd_await_out = rrddim_add(dm->st_await, "writes", NULL, -1, 1,
3754 + RRD_ALGORITHM_ABSOLUTE);
3755 + } else
3756 + rrdset_next(dm->st_await);
3757 +
3758 + rrddim_set_by_pointer(dm->st_await, dm->rd_await_in,
3759 + (dstat[i].operations[DEVSTAT_READ] -
3760 + dm->prev_dstat.operations_read) ?
3761 + (cur_dstat.duration_read_ms - dm->prev_dstat.duration_read_ms) /
3762 + (dstat[i].operations[DEVSTAT_READ] -
3763 + dm->prev_dstat.operations_read) :
3764 + 0);
3765 + rrddim_set_by_pointer(dm->st_await, dm->rd_await_out,
3766 + (dstat[i].operations[DEVSTAT_WRITE] -
3767 + dm->prev_dstat.operations_write) ?
3768 + (cur_dstat.duration_write_ms - dm->prev_dstat.duration_write_ms) /
3769 + (dstat[i].operations[DEVSTAT_WRITE] -
3770 + dm->prev_dstat.operations_write) :
3771 + 0);
3772 + rrdset_done(dm->st_await);
3773 }
3477 - else rrdset_next(st);
3478 -
3479 - rrddim_set(st, "reads", (dstat[i].operations[DEVSTAT_READ] - prev_dstat.operations_read) ?
3480 - (cur_dstat.duration_read_ms - prev_dstat.duration_read_ms) / (dstat[i].operations[DEVSTAT_READ] - prev_dstat.operations_read) : 0);
3481 - rrddim_set(st, "writes", (dstat[i].operations[DEVSTAT_WRITE] - prev_dstat.operations_write) ?
3482 - (cur_dstat.duration_write_ms - prev_dstat.duration_write_ms) / (dstat[i].operations[DEVSTAT_WRITE] - prev_dstat.operations_write) : 0);
3483 - rrdset_done(st);
3774
3775 // --------------------------------------------------------------------
3776
3487 - st = rrdset_find_bytype_localhost("disk_avgsz", disk);
3488 - if (unlikely(!st)) {
3489 - st = rrdset_create_localhost("disk_avgsz", disk, NULL, disk, "disk.avgsz", "Average Completed I/O Operation Bandwidth", "kilobytes per operation", 2006, update_every, RRDSET_TYPE_AREA);
3490 - rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
3491 -
3492 - rrddim_add(st, "reads", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
3493 - rrddim_add(st, "writes", NULL, -1, 1024, RRD_ALGORITHM_ABSOLUTE);
3777 + if(dm->do_avagsz == CONFIG_BOOLEAN_YES || (dm->do_avagsz == CONFIG_BOOLEAN_AUTO &&
3778 + (dstat[i].operations[DEVSTAT_READ] || dstat[i].operations[DEVSTAT_WRITE]))) {
3779 + if (unlikely(!dm->st_avagsz)) {
3780 + dm->st_avagsz = rrdset_create_localhost("disk_avgsz",
3781 + disk,
3782 + NULL,
3783 + disk,
3784 + "disk.avgsz",
3785 + "Average Completed I/O Operation Bandwidth",
3786 + "kilobytes per operation",
3787 + 2006,
3788 + update_every,
3789 + RRDSET_TYPE_AREA
3790 + );
3791 +
3792 + rrdset_flag_set(dm->st_avagsz, RRDSET_FLAG_DETAIL);
3793 +
3794 + dm->rd_avagsz_in = rrddim_add(dm->st_avagsz, "reads", NULL, 1, KILO_FACTOR,
3795 + RRD_ALGORITHM_ABSOLUTE);
3796 + dm->rd_avagsz_out = rrddim_add(dm->st_avagsz, "writes", NULL, -1, KILO_FACTOR,
3797 + RRD_ALGORITHM_ABSOLUTE);
3798 + } else
3799 + rrdset_next(dm->st_avagsz);
3800 +
3801 + rrddim_set_by_pointer(dm->st_avagsz, dm->rd_avagsz_in,
3802 + (dstat[i].operations[DEVSTAT_READ] -
3803 + dm->prev_dstat.operations_read) ?
3804 + (dstat[i].bytes[DEVSTAT_READ] - dm->prev_dstat.bytes_read) /
3805 + (dstat[i].operations[DEVSTAT_READ] -
3806 + dm->prev_dstat.operations_read) :
3807 + 0);
3808 + rrddim_set_by_pointer(dm->st_avagsz, dm->rd_avagsz_out,
3809 + (dstat[i].operations[DEVSTAT_WRITE] -
3810 + dm->prev_dstat.operations_write) ?
3811 + (dstat[i].bytes[DEVSTAT_WRITE] - dm->prev_dstat.bytes_write) /
3812 + (dstat[i].operations[DEVSTAT_WRITE] -
3813 + dm->prev_dstat.operations_write) :
3814 + 0);
3815 + rrdset_done(dm->st_avagsz);
3816 }
3495 - else rrdset_next(st);
3496 -
3497 - rrddim_set(st, "reads", (dstat[i].operations[DEVSTAT_READ] - prev_dstat.operations_read) ?
3498 - (dstat[i].bytes[DEVSTAT_READ] - prev_dstat.bytes_read) / (dstat[i].operations[DEVSTAT_READ] - prev_dstat.operations_read) : 0);
3499 - rrddim_set(st, "writes", (dstat[i].operations[DEVSTAT_WRITE] - prev_dstat.operations_write) ?
3500 - (dstat[i].bytes[DEVSTAT_WRITE] - prev_dstat.bytes_write) / (dstat[i].operations[DEVSTAT_WRITE] - prev_dstat.operations_write) : 0);
3501 - rrdset_done(st);
3817
3818 // --------------------------------------------------------------------
3819
3505 - st = rrdset_find_bytype_localhost("disk_svctm", disk);
3506 - if (unlikely(!st)) {
3507 - st = rrdset_create_localhost("disk_svctm", disk, NULL, disk, "disk.svctm", "Average Service Time", "ms per operation", 2007, update_every, RRDSET_TYPE_LINE);
3508 - rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
3509 -
3510 - rrddim_add(st, "svctm", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
3820 + if(dm->do_svctm == CONFIG_BOOLEAN_YES || (dm->do_svctm == CONFIG_BOOLEAN_AUTO &&
3821 + (dstat[i].operations[DEVSTAT_READ] || dstat[i].operations[DEVSTAT_WRITE]))) {
3822 + if (unlikely(!dm->st_svctm)) {
3823 + dm->st_svctm = rrdset_create_localhost("disk_svctm",
3824 + disk,
3825 + NULL,
3826 + disk,
3827 + "disk.svctm",
3828 + "Average Service Time",
3829 + "ms per operation",
3830 + 2007,
3831 + update_every,
3832 + RRDSET_TYPE_LINE
3833 + );
3834 +
3835 + rrdset_flag_set(dm->st_svctm, RRDSET_FLAG_DETAIL);
3836 +
3837 + dm->rd_svctm = rrddim_add(dm->st_svctm, "svctm", NULL, 1, 1,
3838 + RRD_ALGORITHM_ABSOLUTE);
3839 + } else
3840 + rrdset_next(dm->st_svctm);
3841 +
3842 + rrddim_set_by_pointer(dm->st_svctm, dm->rd_svctm,
3843 + ((dstat[i].operations[DEVSTAT_READ] - dm->prev_dstat.operations_read) +
3844 + (dstat[i].operations[DEVSTAT_WRITE] - dm->prev_dstat.operations_write)) ?
3845 + (cur_dstat.busy_time_ms - dm->prev_dstat.busy_time_ms) /
3846 + ((dstat[i].operations[DEVSTAT_READ] - dm->prev_dstat.operations_read) +
3847 + (dstat[i].operations[DEVSTAT_WRITE] - dm->prev_dstat.operations_write)) :
3848 + 0);
3849 + rrdset_done(dm->st_svctm);
3850 }
3512 - else rrdset_next(st);
3851
3514 - rrddim_set(st, "svctm", ((dstat[i].operations[DEVSTAT_READ] - prev_dstat.operations_read) + (dstat[i].operations[DEVSTAT_WRITE] - prev_dstat.operations_write)) ?
3515 - (cur_dstat.busy_time_ms - prev_dstat.busy_time_ms) / ((dstat[i].operations[DEVSTAT_READ] - prev_dstat.operations_read) + (dstat[i].operations[DEVSTAT_WRITE] - prev_dstat.operations_write)) : 0);
3516 - rrdset_done(st);
3852 + // --------------------------------------------------------------------
3853 +
3854 + dm->prev_dstat.bytes_read = dstat[i].bytes[DEVSTAT_READ];
3855 + dm->prev_dstat.bytes_write = dstat[i].bytes[DEVSTAT_WRITE];
3856 + dm->prev_dstat.operations_read = dstat[i].operations[DEVSTAT_READ];
3857 + dm->prev_dstat.operations_write = dstat[i].operations[DEVSTAT_WRITE];
3858 + dm->prev_dstat.duration_read_ms = cur_dstat.duration_read_ms;
3859 + dm->prev_dstat.duration_write_ms = cur_dstat.duration_write_ms;
3860 + dm->prev_dstat.busy_time_ms = cur_dstat.busy_time_ms;
3861 }
3862 }
3863 }
3864
3865 // --------------------------------------------------------------------
3866
3523 - st = rrdset_find_bytype_localhost("system", "io");
3524 - if (unlikely(!st)) {
3525 - st = rrdset_create_localhost("system", "io", NULL, "disk", NULL, "Disk I/O", "kilobytes/s", 150, update_every, RRDSET_TYPE_AREA);
3526 - rrddim_add(st, "in", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
3527 - rrddim_add(st, "out", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
3528 - }
3529 - else rrdset_next(st);
3867 + if (unlikely(!do_system_io)) {
3868 + static RRDSET *st = NULL;
3869 + static RRDDIM *rd_in = NULL, *rd_out = NULL;
3870 +
3871 + st = rrdset_find_bytype_localhost("system", "io");
3872 + if (unlikely(!st)) {
3873 + st = rrdset_create_localhost("system",
3874 + "io",
3875 + NULL,
3876 + "disk",
3877 + NULL,
3878 + "Disk I/O",
3879 + "kilobytes/s",
3880 + 150,
3881 + update_every,
3882 + RRDSET_TYPE_AREA
3883 + );
3884
3531 - rrddim_set(st, "in", total_disk_kbytes_read);
3532 - rrddim_set(st, "out", total_disk_kbytes_write);
3533 - rrdset_done(st);
3885 + rd_in = rrddim_add(st, "in", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
3886 + rd_out = rrddim_add(st, "out", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
3887 + } else
3888 + rrdset_next(st);
3889 +
3890 + rrddim_set_by_pointer(st, rd_in, total_disk_kbytes_read);
3891 + rrddim_set_by_pointer(st, rd_out, total_disk_kbytes_write);
3892 + rrdset_done(st);
3893 + }
3894 }
3895 }
3896 + if (unlikely(common_error)) {
3897 + do_system_io = 0;
3898 + error("DISABLED: system.io chart");
3899 + do_io = 0;
3900 + error("DISABLED: disk.* charts");
3901 + do_ops = 0;
3902 + error("DISABLED: disk_ops.* charts");
3903 + do_qops = 0;
3904 + error("DISABLED: disk_qops.* charts");
3905 + do_util = 0;
3906 + error("DISABLED: disk_util.* charts");
3907 + do_iotime = 0;
3908 + error("DISABLED: disk_iotime.* charts");
3909 + do_await = 0;
3910 + error("DISABLED: disk_await.* charts");
3911 + do_avagsz = 0;
3912 + error("DISABLED: disk_avgsz.* charts");
3913 + do_svctm = 0;
3914 + error("DISABLED: disk_svctm.* charts");
3915 + error("DISABLED: kern.devstat module");
3916 + return 1;
3917 + }
3918 + } else {
3919 + error("DISABLED: kern.devstat module");
3920 + return 1;
3921 }
3922
3923 return 0;