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;