@cryptotaxi247 / netdata-1 / commits / f82bbd9d0

Add disk stats and do minor style cleanups

Vladimir Kobal committed Dec 9, 2016 at 23:25 UTC f82bbd9d06244f5ec770b2b0f5df64175a94f7e7
1 file changed +226 -22
src/freebsd_sysctl.c
+226 -22
@@ -2,6 +2,10 @@
2
3 // NEEDED BY: struct vmstat
4 #include <sys/vmmeter.h>
5 +// NEEDED BY: struct devstat
6 +#include <sys/devicestat.h>
7 +// NEEDED BY: do_disk_io
8 +#define RRD_TYPE_DISK "disk"
9
10 // FreeBSD calculates load averages once every 5 seconds
11 #define MIN_LOADAVG_UPDATE_EVERY 5
@@ -10,9 +14,9 @@ int do_freebsd_sysctl(int update_every, unsigned long long dt) {
14 (void)dt;
15
16 static int do_cpu = -1, do_cpu_cores = -1, do_interrupts = -1, do_context = -1, do_forks = -1, do_processes = -1,
13 - do_loadavg = -1, do_all_processes = -1;
17 + do_loadavg = -1, do_all_processes = -1, do_disk_io = -1;
18
15 - if(unlikely(do_cpu == -1)) {
19 + if (unlikely(do_cpu == -1)) {
20 do_cpu = config_get_boolean("plugin:freebsd:sysctl", "cpu utilization", 1);
21 do_cpu_cores = config_get_boolean("plugin:freebsd:sysctl", "per cpu core utilization", 1);
22 do_interrupts = config_get_boolean("plugin:freebsd:sysctl", "cpu interrupts", 1);
@@ -21,6 +25,8 @@ int do_freebsd_sysctl(int update_every, unsigned long long dt) {
25 do_processes = config_get_boolean("plugin:freebsd:sysctl", "processes running", 1);
26 do_loadavg = config_get_boolean("plugin:freebsd:sysctl", "enable load average", 1);
27 do_all_processes = config_get_boolean("plugin:freebsd:sysctl", "enable total processes", 1);
28 +
29 + do_disk_io = config_get_boolean("plugin:freebsd:sysctl", "stats for all disks", 1);
30 }
31
32 RRDSET *st;
@@ -51,17 +57,37 @@ int do_freebsd_sysctl(int update_every, unsigned long long dt) {
57 static unsigned long *intrcnt = NULL;
58 unsigned long long totalintr = 0;
59
60 +// NEEDED BY: do_disk_io
61 + #define BINTIME_SCALE 5.42101086242752217003726400434970855712890625e-17 // this is 1000/2^64
62 + int numdevs;
63 + static void *devstat_data = NULL;
64 + struct devstat *dstat;
65 + struct cur_dstat {
66 + collected_number duration_read_ms;
67 + collected_number duration_write_ms;
68 + collected_number busy_time_ms;
69 + } cur_dstat;
70 + struct prev_dstat {
71 + collected_number bytes_read;
72 + collected_number bytes_write;
73 + collected_number operations_read;
74 + collected_number operations_write;
75 + collected_number duration_read_ms;
76 + collected_number duration_write_ms;
77 + collected_number busy_time_ms;
78 + } prev_dstat;
79 +
80 // --------------------------------------------------------------------
81
56 - if(last_loadavg_usec <= dt) {
57 - if(likely(do_loadavg)) {
82 + if (last_loadavg_usec <= dt) {
83 + if (likely(do_loadavg)) {
84 if (unlikely(GETSYSCTL("vm.loadavg", sysload))) {
85 do_loadavg = 0;
86 error("DISABLED: system.load");
87 } else {
88
89 st = rrdset_find_bytype("system", "load");
64 - if(unlikely(!st)) {
90 + if (unlikely(!st)) {
91 st = rrdset_create("system", "load", NULL, "load", NULL, "System Load Average", "load", 100, (update_every < MIN_LOADAVG_UPDATE_EVERY) ? MIN_LOADAVG_UPDATE_EVERY : update_every, RRDSET_TYPE_LINE);
92 rrddim_add(st, "load1", NULL, 1, 1000, RRDDIM_ABSOLUTE);
93 rrddim_add(st, "load5", NULL, 1, 1000, RRDDIM_ABSOLUTE);
@@ -82,17 +108,17 @@ int do_freebsd_sysctl(int update_every, unsigned long long dt) {
108
109 // --------------------------------------------------------------------
110
85 - if(likely(do_all_processes | do_processes)) {
111 + if (likely(do_all_processes | do_processes)) {
112 if (unlikely(GETSYSCTL("vm.vmtotal", vmtotal_data))) {
113 do_all_processes = 0;
114 error("DISABLED: system.active_processes");
115 do_processes = 0;
116 error("DISABLED: system.processes");
117 } else {
92 - if(likely(do_processes)) {
118 + if (likely(do_processes)) {
119
120 st = rrdset_find_bytype("system", "active_processes");
95 - if(unlikely(!st)) {
121 + if (unlikely(!st)) {
122 st = rrdset_create("system", "active_processes", NULL, "processes", NULL, "System Active Processes", "processes", 750, update_every, RRDSET_TYPE_LINE);
123 rrddim_add(st, "active", NULL, 1, 1, RRDDIM_ABSOLUTE);
124 }
@@ -101,10 +127,10 @@ int do_freebsd_sysctl(int update_every, unsigned long long dt) {
127 rrddim_set(st, "active", (vmtotal_data.t_rq + vmtotal_data.t_dw + vmtotal_data.t_pw + vmtotal_data.t_sl + vmtotal_data.t_sw));
128 rrdset_done(st);
129 }
104 - if(likely(do_processes)) {
130 + if (likely(do_processes)) {
131
132 st = rrdset_find_bytype("system", "processes");
107 - if(unlikely(!st)) {
133 + if (unlikely(!st)) {
134 st = rrdset_create("system", "processes", NULL, "processes", NULL, "System Processes", "processes", 600, update_every, RRDSET_TYPE_LINE);
135
136 rrddim_add(st, "running", NULL, 1, 1, RRDDIM_ABSOLUTE);
@@ -122,10 +148,10 @@ int do_freebsd_sysctl(int update_every, unsigned long long dt) {
148
149 // --------------------------------------------------------------------
150
125 - if(likely(do_processes)) {
151 + if (likely(do_processes)) {
152
153 st = rrdset_find_bytype("system", "processes");
128 - if(unlikely(!st)) {
154 + if (unlikely(!st)) {
155 st = rrdset_create("system", "processes", NULL, "processes", NULL, "System Processes", "processes", 600, update_every, RRDSET_TYPE_LINE);
156
157 rrddim_add(st, "running", NULL, 1, 1, RRDDIM_ABSOLUTE);
@@ -140,7 +166,7 @@ int do_freebsd_sysctl(int update_every, unsigned long long dt) {
166
167 // --------------------------------------------------------------------
168
143 - if(likely(do_cpu)) {
169 + if (likely(do_cpu)) {
170 if (unlikely(CPUSTATES != 5)) {
171 error("FREEBSD: There are %d CPU states (5 was expected)", CPUSTATES);
172 do_cpu = 0;
@@ -152,7 +178,7 @@ int do_freebsd_sysctl(int update_every, unsigned long long dt) {
178 } else {
179
180 st = rrdset_find_bytype("system", "cpu");
155 - if(unlikely(!st)) {
181 + if (unlikely(!st)) {
182 st = rrdset_create("system", "cpu", NULL, "cpu", "system.cpu", "Total CPU utilization", "percentage", 100, update_every, RRDSET_TYPE_STACKED);
183
184 rrddim_add(st, "user", NULL, 1, 1, RRDDIM_PCENT_OVER_DIFF_TOTAL);
@@ -176,7 +202,7 @@ int do_freebsd_sysctl(int update_every, unsigned long long dt) {
202
203 // --------------------------------------------------------------------
204
179 - if(likely(do_cpu_cores)) {
205 + if (likely(do_cpu_cores)) {
206 if (unlikely(CPUSTATES != 5)) {
207 error("FREEBSD: There are %d CPU states (5 was expected)", CPUSTATES);
208 do_cpu_cores = 0;
@@ -203,7 +229,7 @@ int do_freebsd_sysctl(int update_every, unsigned long long dt) {
229 snprintfz(cpuid, 8, "cpu%d", i);
230
231 st = rrdset_find_bytype("cpu", cpuid);
206 - if(unlikely(!st)) {
232 + if (unlikely(!st)) {
233 st = rrdset_create("cpu", cpuid, NULL, "utilization", "cpu.cpu", "Core utilization", "percentage", 1000, update_every, RRDSET_TYPE_STACKED);
234
235 rrddim_add(st, "user", NULL, 1, 1, RRDDIM_PCENT_OVER_DIFF_TOTAL);
@@ -228,7 +254,7 @@ int do_freebsd_sysctl(int update_every, unsigned long long dt) {
254
255 // --------------------------------------------------------------------
256
231 - if(likely(do_interrupts)) {
257 + if (likely(do_interrupts)) {
258 if (unlikely(sysctlbyname("hw.intrcnt", NULL, &intrcnt_size, NULL, 0) == -1)) {
259 error("FREEBSD: sysctl(hw.intrcnt...) failed: %s", strerror(errno));
260 do_interrupts = 0;
@@ -244,7 +270,7 @@ int do_freebsd_sysctl(int update_every, unsigned long long dt) {
270 totalintr += intrcnt[i];
271
272 st = rrdset_find_bytype("system", "intr");
247 - if(unlikely(!st)) {
273 + if (unlikely(!st)) {
274 st = rrdset_create("system", "intr", NULL, "interrupts", NULL, "Total Device Interrupts", "interrupts/s", 900, update_every, RRDSET_TYPE_LINE);
275 st->isdetail = 1;
276
@@ -260,14 +286,14 @@ int do_freebsd_sysctl(int update_every, unsigned long long dt) {
286
287 // --------------------------------------------------------------------
288
263 - if(likely(do_context)) {
289 + if (likely(do_context)) {
290 if (unlikely(GETSYSCTL("vm.stats.sys.v_swtch", u_int_data))) {
291 do_context = 0;
292 error("DISABLED: system.ctxt");
293 } else {
294
295 st = rrdset_find_bytype("system", "ctxt");
270 - if(unlikely(!st)) {
296 + if (unlikely(!st)) {
297 st = rrdset_create("system", "ctxt", NULL, "processes", NULL, "CPU Context Switches", "context switches/s", 800, update_every, RRDSET_TYPE_LINE);
298
299 rrddim_add(st, "switches", NULL, 1, 1, RRDDIM_INCREMENTAL);
@@ -281,14 +307,14 @@ int do_freebsd_sysctl(int update_every, unsigned long long dt) {
307
308 // --------------------------------------------------------------------
309
284 - if(likely(do_forks)) {
310 + if (likely(do_forks)) {
311 if (unlikely(GETSYSCTL("vm.stats.vm.v_forks", u_int_data))) {
312 do_forks = 0;
313 error("DISABLED: system.forks");
314 } else {
315
316 st = rrdset_find_bytype("system", "forks");
291 - if(unlikely(!st)) {
317 + if (unlikely(!st)) {
318 st = rrdset_create("system", "forks", NULL, "processes", NULL, "Started Processes", "processes/s", 700, update_every, RRDSET_TYPE_LINE);
319 st->isdetail = 1;
320
@@ -301,5 +327,183 @@ int do_freebsd_sysctl(int update_every, unsigned long long dt) {
327 }
328 }
329
330 + // --------------------------------------------------------------------
331 +
332 + if (likely(do_disk_io)) {
333 + if (unlikely(GETSYSCTL("kern.devstat.numdevs", numdevs))) {
334 + do_disk_io = 0;
335 + error("DISABLED: disk.io");
336 + } else {
337 + devstat_data = reallocz(devstat_data, sizeof(long) + sizeof(struct devstat) * numdevs); // there is generation number before devstat structures
338 + if (unlikely(getsysctl("kern.devstat.all", devstat_data, sizeof(long) + sizeof(struct devstat) * numdevs))) {
339 + do_disk_io = 0;
340 + error("DISABLED: disk.io");
341 + } else {
342 + dstat = devstat_data +sizeof(long); // skip generation number
343 + collected_number total_disk_reads = 0;
344 + collected_number total_disk_writes = 0;
345 +
346 + for (i = 0; i < numdevs; i++) {
347 + if ((dstat[i].device_type == (DEVSTAT_TYPE_IF_SCSI | DEVSTAT_TYPE_DIRECT)) || (dstat[i].device_type == (DEVSTAT_TYPE_IF_IDE | DEVSTAT_TYPE_DIRECT))) {
348 +
349 + // --------------------------------------------------------------------
350 +
351 + st = rrdset_find_bytype(RRD_TYPE_DISK, dstat[i].device_name);
352 + if (unlikely(!st)) {
353 + st = rrdset_create(RRD_TYPE_DISK, dstat[i].device_name, NULL, dstat[i].device_name, "disk.io", "Disk I/O Bandwidth", "kilobytes/s", 2000, update_every, RRDSET_TYPE_AREA);
354 +
355 + rrddim_add(st, "reads", NULL, 1, 1024, RRDDIM_INCREMENTAL);
356 + rrddim_add(st, "writes", NULL, -1, 1024, RRDDIM_INCREMENTAL);
357 + }
358 + else rrdset_next(st);
359 +
360 + total_disk_reads += dstat[i].bytes[DEVSTAT_READ];
361 + total_disk_writes += dstat[i].bytes[DEVSTAT_WRITE];
362 + prev_dstat.bytes_read = rrddim_set(st, "reads", dstat[i].bytes[DEVSTAT_READ]);
363 + prev_dstat.bytes_write = rrddim_set(st, "writes", dstat[i].bytes[DEVSTAT_WRITE]);
364 + rrdset_done(st);
365 +
366 + // --------------------------------------------------------------------
367 +
368 + st = rrdset_find_bytype("disk_ops", dstat[i].device_name);
369 + if (unlikely(!st)) {
370 + st = rrdset_create("disk_ops", dstat[i].device_name, NULL, dstat[i].device_name, "disk.ops", "Disk Completed I/O Operations", "operations/s", 2001, update_every, RRDSET_TYPE_LINE);
371 + st->isdetail = 1;
372 +
373 + rrddim_add(st, "reads", NULL, 1, 1, RRDDIM_INCREMENTAL);
374 + rrddim_add(st, "writes", NULL, -1, 1, RRDDIM_INCREMENTAL);
375 + }
376 + else rrdset_next(st);
377 +
378 + prev_dstat.operations_read = rrddim_set(st, "reads", dstat[i].operations[DEVSTAT_READ]);
379 + prev_dstat.operations_write = rrddim_set(st, "writes", dstat[i].operations[DEVSTAT_WRITE]);
380 + rrdset_done(st);
381 +
382 + // --------------------------------------------------------------------
383 +
384 + st = rrdset_find_bytype("disk_qops", dstat[i].device_name);
385 + if (unlikely(!st)) {
386 + st = rrdset_create("disk_qops", dstat[i].device_name, NULL, dstat[i].device_name, "disk.qops", "Disk Current I/O Operations", "operations", 2002, update_every, RRDSET_TYPE_LINE);
387 + st->isdetail = 1;
388 +
389 + rrddim_add(st, "operations", NULL, 1, 1, RRDDIM_ABSOLUTE);
390 + }
391 + else rrdset_next(st);
392 +
393 + rrddim_set(st, "operations", dstat[i].start_count - dstat[i].end_count);
394 + rrdset_done(st);
395 +
396 + // --------------------------------------------------------------------
397 +
398 + st = rrdset_find_bytype("disk_util", dstat[i].device_name);
399 + if (unlikely(!st)) {
400 + st = rrdset_create("disk_util", dstat[i].device_name, NULL, dstat[i].device_name, "disk.util", "Disk Utilization Time", "% of time working", 2004, update_every, RRDSET_TYPE_AREA);
401 + st->isdetail = 1;
402 +
403 + rrddim_add(st, "utilization", NULL, 1, 10, RRDDIM_INCREMENTAL);
404 + }
405 + else rrdset_next(st);
406 +
407 + cur_dstat.busy_time_ms = dstat[i].busy_time.sec * 1000 + dstat[i].busy_time.frac * BINTIME_SCALE;
408 + prev_dstat.busy_time_ms = rrddim_set(st, "utilization", cur_dstat.busy_time_ms);
409 + rrdset_done(st);
410 +
411 + // --------------------------------------------------------------------
412 +
413 + st = rrdset_find_bytype("disk_iotime", dstat[i].device_name);
414 + if (unlikely(!st)) {
415 + st = rrdset_create("disk_iotime", dstat[i].device_name, NULL, dstat[i].device_name, "disk.iotime", "Disk Total I/O Time", "milliseconds/s", 2022, update_every, RRDSET_TYPE_LINE);
416 + st->isdetail = 1;
417 +
418 + rrddim_add(st, "reads", NULL, 1, 1, RRDDIM_INCREMENTAL);
419 + rrddim_add(st, "writes", NULL, -1, 1, RRDDIM_INCREMENTAL);
420 + }
421 + else rrdset_next(st);
422 +
423 + cur_dstat.duration_read_ms = dstat[i].duration[DEVSTAT_READ].sec * 1000 + dstat[i].duration[DEVSTAT_READ].frac * BINTIME_SCALE;
424 + cur_dstat.duration_write_ms = dstat[i].duration[DEVSTAT_WRITE].sec * 1000 + dstat[i].duration[DEVSTAT_READ].frac * BINTIME_SCALE;
425 + prev_dstat.duration_read_ms = rrddim_set(st, "reads", cur_dstat.duration_read_ms);
426 + prev_dstat.duration_write_ms = rrddim_set(st, "writes", cur_dstat.duration_write_ms);
427 + rrdset_done(st);
428 +
429 + // --------------------------------------------------------------------
430 + // calculate differential charts
431 + // only if this is not the first time we run
432 +
433 + if (likely(dt)) {
434 +
435 + // --------------------------------------------------------------------
436 +
437 + st = rrdset_find_bytype("disk_await", dstat[i].device_name);
438 + if (unlikely(!st)) {
439 + st = rrdset_create("disk_await", dstat[i].device_name, NULL, dstat[i].device_name, "disk.await", "Average Completed I/O Operation Time", "ms per operation", 2005, update_every, RRDSET_TYPE_LINE);
440 + st->isdetail = 1;
441 +
442 + rrddim_add(st, "reads", NULL, 1, 1, RRDDIM_ABSOLUTE);
443 + rrddim_add(st, "writes", NULL, -1, 1, RRDDIM_ABSOLUTE);
444 + }
445 + else rrdset_next(st);
446 +
447 + rrddim_set(st, "reads", (dstat[i].operations[DEVSTAT_READ] - prev_dstat.operations_read) ?
448 + (cur_dstat.duration_read_ms - prev_dstat.duration_read_ms) / (dstat[i].operations[DEVSTAT_READ] - prev_dstat.operations_read) : 0);
449 + rrddim_set(st, "writes", (dstat[i].operations[DEVSTAT_WRITE] - prev_dstat.operations_write) ?
450 + (cur_dstat.duration_write_ms - prev_dstat.duration_write_ms) / (dstat[i].operations[DEVSTAT_WRITE] - prev_dstat.operations_write) : 0);
451 + rrdset_done(st);
452 +
453 + // --------------------------------------------------------------------
454 +
455 + st = rrdset_find_bytype("disk_avgsz", dstat[i].device_name);
456 + if (unlikely(!st)) {
457 + st = rrdset_create("disk_avgsz", dstat[i].device_name, NULL, dstat[i].device_name, "disk.avgsz", "Average Completed I/O Operation Bandwidth", "kilobytes per operation", 2006, update_every, RRDSET_TYPE_AREA);
458 + st->isdetail = 1;
459 +
460 + rrddim_add(st, "reads", NULL, 1, 1024, RRDDIM_ABSOLUTE);
461 + rrddim_add(st, "writes", NULL, -1, 1024, RRDDIM_ABSOLUTE);
462 + }
463 + else rrdset_next(st);
464 +
465 + rrddim_set(st, "reads", (dstat[i].operations[DEVSTAT_READ] - prev_dstat.operations_read) ?
466 + (dstat[i].bytes[DEVSTAT_READ] - prev_dstat.bytes_read) / (dstat[i].operations[DEVSTAT_READ] - prev_dstat.operations_read) : 0);
467 + rrddim_set(st, "writes", (dstat[i].operations[DEVSTAT_WRITE] - prev_dstat.operations_write) ?
468 + (dstat[i].bytes[DEVSTAT_WRITE] - prev_dstat.bytes_write) / (dstat[i].operations[DEVSTAT_WRITE] - prev_dstat.operations_write) : 0);
469 + rrdset_done(st);
470 +
471 + // --------------------------------------------------------------------
472 +
473 + st = rrdset_find_bytype("disk_svctm", dstat[i].device_name);
474 + if (unlikely(!st)) {
475 + st = rrdset_create("disk_svctm", dstat[i].device_name, NULL, dstat[i].device_name, "disk.svctm", "Average Service Time", "ms per operation", 2007, update_every, RRDSET_TYPE_LINE);
476 + st->isdetail = 1;
477 +
478 + rrddim_add(st, "svctm", NULL, 1, 1, RRDDIM_ABSOLUTE);
479 + }
480 + else rrdset_next(st);
481 +
482 + rrddim_set(st, "svctm", ((dstat[i].operations[DEVSTAT_READ] - prev_dstat.operations_read) + (dstat[i].operations[DEVSTAT_WRITE] - prev_dstat.operations_write)) ?
483 + (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);
484 + rrdset_done(st);
485 +
486 + }
487 +
488 + }
489 +
490 + // --------------------------------------------------------------------
491 +
492 + st = rrdset_find_bytype("system", "io");
493 + if (unlikely(!st)) {
494 + st = rrdset_create("system", "io", NULL, "disk", NULL, "Disk I/O", "kilobytes/s", 150, update_every, RRDSET_TYPE_AREA);
495 + rrddim_add(st, "in", NULL, 1, 1024, RRDDIM_INCREMENTAL);
496 + rrddim_add(st, "out", NULL, -1, 1024, RRDDIM_INCREMENTAL);
497 + }
498 + else rrdset_next(st);
499 +
500 + rrddim_set(st, "in", total_disk_reads);
501 + rrddim_set(st, "out", total_disk_writes);
502 + rrdset_done(st);
503 + }
504 + }
505 + }
506 + }
507 +
508 return 0;
509 }