Skip to content

Commit

Permalink
Add disk I/O chart to macOS plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
vlvkobal committed Dec 28, 2016
1 parent 8d78be8 commit 78d53e2
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 1 deletion.
1 change: 1 addition & 0 deletions configure.ac
Expand Up @@ -46,6 +46,7 @@ freebsd*)
;;
darwin*)
build_target=macos
LDFLAGS="${LDFLAGS} -framework CoreFoundation -framework IOKit"
;;
*)
;;
Expand Down
1 change: 1 addition & 0 deletions src/Makefile.am
Expand Up @@ -72,6 +72,7 @@ netdata_SOURCES += \
plugin_macos.c plugin_macos.h \
macos_sysctl.c \
macos_mach_smi.c \
macos_fw.c \
$(NULL)
else
netdata_SOURCES += \
Expand Down
97 changes: 97 additions & 0 deletions src/macos_fw.c
@@ -0,0 +1,97 @@
#include "common.h"
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/storage/IOBlockStorageDriver.h>

int do_macos_iokit(int update_every, usec_t dt) {
(void)dt;

static int do_io = -1;

if (unlikely(do_io == -1)) {
do_io = config_get_boolean("plugin:macos:iokit", "disk i/o", 1);
}

RRDSET *st;

mach_port_t master_port;
io_registry_entry_t drive;
io_iterator_t drive_list;
CFNumberRef number;
CFDictionaryRef properties, statistics;
UInt64 value;
collected_number total_disk_reads = 0;
collected_number total_disk_writes = 0;

/* Get ports and services for drive statistics. */
if (IOMasterPort(bootstrap_port, &master_port)) {
error("MACOS: IOMasterPort() failed");
do_io = 0;
error("DISABLED: system.io");
/* Get the list of all drive objects. */
} else if (IOServiceGetMatchingServices(master_port, IOServiceMatching("IOBlockStorageDriver"), &drive_list)) {
error("MACOS: IOServiceGetMatchingServices() failed");
do_io = 0;
error("DISABLED: system.io");
} else {
while ((drive = IOIteratorNext(drive_list)) != 0) {
number = 0;
properties = 0;
statistics = 0;
value = 0;

/* Obtain the properties for this drive object. */
if (IORegistryEntryCreateCFProperties(drive, (CFMutableDictionaryRef *)&properties, kCFAllocatorDefault, 0)) {
error("MACOS: IORegistryEntryCreateCFProperties() failed");
do_io = 0;
error("DISABLED: system.io");
break;
} else if (properties != 0) {
/* Obtain the statistics from the drive properties. */
statistics = (CFDictionaryRef)CFDictionaryGetValue(properties, CFSTR(kIOBlockStorageDriverStatisticsKey));

if (statistics != 0) {
/* Get bytes read. */
number = (CFNumberRef)CFDictionaryGetValue(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesReadKey));
if (number != 0) {
CFNumberGetValue(number, kCFNumberSInt64Type, &value);
total_disk_reads += value;
}

/* Get bytes written. */
number = (CFNumberRef)CFDictionaryGetValue(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesWrittenKey));
if (number != 0) {
CFNumberGetValue(number, kCFNumberSInt64Type, &value);
total_disk_writes += value;
}
}

/* Release. */
CFRelease(properties);
}

/* Release. */
IOObjectRelease(drive);
}
IOIteratorReset(drive_list);

/* Release. */
IOObjectRelease(drive_list);
}

if (do_io) {
st = rrdset_find_bytype("system", "io");
if (unlikely(!st)) {
st = rrdset_create("system", "io", NULL, "disk", NULL, "Disk I/O", "kilobytes/s", 150, update_every, RRDSET_TYPE_AREA);
rrddim_add(st, "in", NULL, 1, 1024, RRDDIM_INCREMENTAL);
rrddim_add(st, "out", NULL, -1, 1024, RRDDIM_INCREMENTAL);
}
else rrdset_next(st);

rrddim_set(st, "in", total_disk_reads);
rrddim_set(st, "out", total_disk_writes);
rrdset_done(st);
}

return 0;
}
2 changes: 1 addition & 1 deletion src/macos_mach_smi.c
Expand Up @@ -36,7 +36,7 @@ int do_macos_mach_smi(int update_every, usec_t dt) {

if (likely(do_cpu)) {
if (unlikely(HOST_CPU_LOAD_INFO_COUNT != 4)) {
error("FREEBSD: There are %d CPU states (4 was expected)", HOST_CPU_LOAD_INFO_COUNT);
error("MACOS: There are %d CPU states (4 was expected)", HOST_CPU_LOAD_INFO_COUNT);
do_cpu = 0;
error("DISABLED: system.cpu");
} else {
Expand Down
10 changes: 10 additions & 0 deletions src/plugin_macos.c
Expand Up @@ -22,10 +22,12 @@ void *macos_main(void *ptr)
int vdo_cpu_netdata = !config_get_boolean("plugin:macos", "netdata server resources", 1);
int vdo_macos_sysctl = !config_get_boolean("plugin:macos", "sysctl", 1);
int vdo_macos_mach_smi = !config_get_boolean("plugin:macos", "mach system management interface", 1);
int vdo_macos_iokit = !config_get_boolean("plugin:macos", "iokit", 1);

// keep track of the time each module was called
unsigned long long sutime_macos_sysctl = 0ULL;
unsigned long long sutime_macos_mach_smi = 0ULL;
unsigned long long sutime_macos_iokit = 0ULL;

usec_t step = rrd_update_every * USEC_PER_SEC;
for(;;) {
Expand Down Expand Up @@ -57,6 +59,14 @@ void *macos_main(void *ptr)
}
if(unlikely(netdata_exit)) break;

if(!vdo_macos_iokit) {
debug(D_PROCNETDEV_LOOP, "MACOS: calling do_macos_iokit().");
now = now_realtime_usec();
vdo_macos_iokit = do_macos_iokit(rrd_update_every, (sutime_macos_iokit > 0)?now - sutime_macos_iokit:0ULL);
sutime_macos_iokit = now;
}
if(unlikely(netdata_exit)) break;

// END -- the job is done

// --------------------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions src/plugin_macos.h
Expand Up @@ -5,5 +5,6 @@ void *macos_main(void *ptr);

extern int do_macos_sysctl(int update_every, usec_t dt);
extern int do_macos_mach_smi(int update_every, usec_t dt);
extern int do_macos_iokit(int update_every, usec_t dt);

#endif /* NETDATA_PLUGIN_MACOS_H */

0 comments on commit 78d53e2

Please sign in to comment.