]> arthur.barton.de Git - netdata.git/commitdiff
Add disk I/O chart to macOS plugin
authorVladimir Kobal <vlad@prokk.net>
Wed, 28 Dec 2016 20:40:33 +0000 (15:40 -0500)
committerVladimir Kobal <vlad@prokk.net>
Wed, 28 Dec 2016 20:58:36 +0000 (15:58 -0500)
configure.ac
src/Makefile.am
src/macos_fw.c [new file with mode: 0644]
src/macos_mach_smi.c
src/plugin_macos.c
src/plugin_macos.h

index 1b03d0bfcb4014b3a133bf5bf1df028967eeab27..d2745f62fc48319e123508ed188dc04cd5ba3436 100644 (file)
@@ -46,6 +46,7 @@ freebsd*)
        ;;
 darwin*)
        build_target=macos
+       LDFLAGS="${LDFLAGS} -framework CoreFoundation -framework IOKit"
        ;;
 *)
        ;;
index 8df6b61fcfb3e05956ef025bba460d1edcf522ff..e1f87b5e4dfbc65a8f32281803cb479f6c276251 100644 (file)
@@ -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 += \
diff --git a/src/macos_fw.c b/src/macos_fw.c
new file mode 100644 (file)
index 0000000..47d70ed
--- /dev/null
@@ -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;
+}
index 58510688888d8c5b9b43c78072651dd4fe72005a..d86a032205bf798ed9d1048b6598087c0ae64cfb 100644 (file)
@@ -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 {
index 2f3a9cf453ab195eb343fee8eab314bddc05d758..9f88d1e2e6ca8ada0d44c645b100ee5bcffc7d90 100644 (file)
@@ -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(;;) {
@@ -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
 
         // --------------------------------------------------------------------
index b903ff5ba7f28901986d411c2835d7c0a49580ae..a6f966a87e0e7271b526ffd44bfffbc6618a83f6 100644 (file)
@@ -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 */