Add disk I/O chart to macOS plugin
Vladimir Kobal committed
Dec 28, 2016 at 15:40 UTC
78d53e2d121dfa6ddb94cc5ae0f94ddfcdb4e51a
6 files changed
+111
-1
configure.ac
+1
@@ -46,6 +46,7 @@ freebsd*)
46
;;
47
darwin*)
48
build_target=macos
49
+ LDFLAGS="${LDFLAGS} -framework CoreFoundation -framework IOKit"
50
;;
51
*)
52
;;
src/Makefile.am
+1
@@ -72,6 +72,7 @@ netdata_SOURCES += \
72
plugin_macos.c plugin_macos.h \
73
macos_sysctl.c \
74
macos_mach_smi.c \
75
+ macos_fw.c \
76
$(NULL)
77
else
78
netdata_SOURCES += \
src/macos_fw.c
new
+97
@@ -0,0 +1,97 @@
1
+#include "common.h"
2
+#include <CoreFoundation/CoreFoundation.h>
3
+#include <IOKit/IOKitLib.h>
4
+#include <IOKit/storage/IOBlockStorageDriver.h>
5
+
6
+int do_macos_iokit(int update_every, usec_t dt) {
7
+ (void)dt;
8
+
9
+ static int do_io = -1;
10
+
11
+ if (unlikely(do_io == -1)) {
12
+ do_io = config_get_boolean("plugin:macos:iokit", "disk i/o", 1);
13
+ }
14
+
15
+ RRDSET *st;
16
+
17
+ mach_port_t master_port;
18
+ io_registry_entry_t drive;
19
+ io_iterator_t drive_list;
20
+ CFNumberRef number;
21
+ CFDictionaryRef properties, statistics;
22
+ UInt64 value;
23
+ collected_number total_disk_reads = 0;
24
+ collected_number total_disk_writes = 0;
25
+
26
+ /* Get ports and services for drive statistics. */
27
+ if (IOMasterPort(bootstrap_port, &master_port)) {
28
+ error("MACOS: IOMasterPort() failed");
29
+ do_io = 0;
30
+ error("DISABLED: system.io");
31
+ /* Get the list of all drive objects. */
32
+ } else if (IOServiceGetMatchingServices(master_port, IOServiceMatching("IOBlockStorageDriver"), &drive_list)) {
33
+ error("MACOS: IOServiceGetMatchingServices() failed");
34
+ do_io = 0;
35
+ error("DISABLED: system.io");
36
+ } else {
37
+ while ((drive = IOIteratorNext(drive_list)) != 0) {
38
+ number = 0;
39
+ properties = 0;
40
+ statistics = 0;
41
+ value = 0;
42
+
43
+ /* Obtain the properties for this drive object. */
44
+ if (IORegistryEntryCreateCFProperties(drive, (CFMutableDictionaryRef *)&properties, kCFAllocatorDefault, 0)) {
45
+ error("MACOS: IORegistryEntryCreateCFProperties() failed");
46
+ do_io = 0;
47
+ error("DISABLED: system.io");
48
+ break;
49
+ } else if (properties != 0) {
50
+ /* Obtain the statistics from the drive properties. */
51
+ statistics = (CFDictionaryRef)CFDictionaryGetValue(properties, CFSTR(kIOBlockStorageDriverStatisticsKey));
52
+
53
+ if (statistics != 0) {
54
+ /* Get bytes read. */
55
+ number = (CFNumberRef)CFDictionaryGetValue(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesReadKey));
56
+ if (number != 0) {
57
+ CFNumberGetValue(number, kCFNumberSInt64Type, &value);
58
+ total_disk_reads += value;
59
+ }
60
+
61
+ /* Get bytes written. */
62
+ number = (CFNumberRef)CFDictionaryGetValue(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesWrittenKey));
63
+ if (number != 0) {
64
+ CFNumberGetValue(number, kCFNumberSInt64Type, &value);
65
+ total_disk_writes += value;
66
+ }
67
+ }
68
+
69
+ /* Release. */
70
+ CFRelease(properties);
71
+ }
72
+
73
+ /* Release. */
74
+ IOObjectRelease(drive);
75
+ }
76
+ IOIteratorReset(drive_list);
77
+
78
+ /* Release. */
79
+ IOObjectRelease(drive_list);
80
+ }
81
+
82
+ if (do_io) {
83
+ st = rrdset_find_bytype("system", "io");
84
+ if (unlikely(!st)) {
85
+ st = rrdset_create("system", "io", NULL, "disk", NULL, "Disk I/O", "kilobytes/s", 150, update_every, RRDSET_TYPE_AREA);
86
+ rrddim_add(st, "in", NULL, 1, 1024, RRDDIM_INCREMENTAL);
87
+ rrddim_add(st, "out", NULL, -1, 1024, RRDDIM_INCREMENTAL);
88
+ }
89
+ else rrdset_next(st);
90
+
91
+ rrddim_set(st, "in", total_disk_reads);
92
+ rrddim_set(st, "out", total_disk_writes);
93
+ rrdset_done(st);
94
+ }
95
+
96
+ return 0;
97
+}
src/macos_mach_smi.c
+1
-1
@@ -36,7 +36,7 @@ int do_macos_mach_smi(int update_every, usec_t dt) {
36
37
if (likely(do_cpu)) {
38
if (unlikely(HOST_CPU_LOAD_INFO_COUNT != 4)) {
39
- error("FREEBSD: There are %d CPU states (4 was expected)", HOST_CPU_LOAD_INFO_COUNT);
39
+ error("MACOS: There are %d CPU states (4 was expected)", HOST_CPU_LOAD_INFO_COUNT);
40
do_cpu = 0;
41
error("DISABLED: system.cpu");
42
} else {
src/plugin_macos.c
+10
@@ -22,10 +22,12 @@ void *macos_main(void *ptr)
22
int vdo_cpu_netdata = !config_get_boolean("plugin:macos", "netdata server resources", 1);
23
int vdo_macos_sysctl = !config_get_boolean("plugin:macos", "sysctl", 1);
24
int vdo_macos_mach_smi = !config_get_boolean("plugin:macos", "mach system management interface", 1);
25
+ int vdo_macos_iokit = !config_get_boolean("plugin:macos", "iokit", 1);
26
27
// keep track of the time each module was called
28
unsigned long long sutime_macos_sysctl = 0ULL;
29
unsigned long long sutime_macos_mach_smi = 0ULL;
30
+ unsigned long long sutime_macos_iokit = 0ULL;
31
32
usec_t step = rrd_update_every * USEC_PER_SEC;
33
for(;;) {
@@ -57,6 +59,14 @@ void *macos_main(void *ptr)
59
}
60
if(unlikely(netdata_exit)) break;
61
62
+ if(!vdo_macos_iokit) {
63
+ debug(D_PROCNETDEV_LOOP, "MACOS: calling do_macos_iokit().");
64
+ now = now_realtime_usec();
65
+ vdo_macos_iokit = do_macos_iokit(rrd_update_every, (sutime_macos_iokit > 0)?now - sutime_macos_iokit:0ULL);
66
+ sutime_macos_iokit = now;
67
+ }
68
+ if(unlikely(netdata_exit)) break;
69
+
70
// END -- the job is done
71
72
// --------------------------------------------------------------------
src/plugin_macos.h
+1
@@ -5,5 +5,6 @@ void *macos_main(void *ptr);
5
6
extern int do_macos_sysctl(int update_every, usec_t dt);
7
extern int do_macos_mach_smi(int update_every, usec_t dt);
8
+extern int do_macos_iokit(int update_every, usec_t dt);
9
10
#endif /* NETDATA_PLUGIN_MACOS_H */