]> arthur.barton.de Git - netdata.git/commitdiff
Separate macOS plugin
authorVladimir Kobal <vlad@prokk.net>
Mon, 26 Dec 2016 17:34:23 +0000 (19:34 +0200)
committerVladimir Kobal <vlad@prokk.net>
Mon, 26 Dec 2016 17:44:14 +0000 (19:44 +0200)
configure.ac
src/Makefile.am
src/common.h
src/freebsd_sysctl.c
src/macos_mach_smi.c [new file with mode: 0644]
src/macos_sysctl.c [new file with mode: 0644]
src/main.c
src/plugin_macos.c [new file with mode: 0644]
src/plugin_macos.h [new file with mode: 0644]

index ed8f8212b635a6be0d3e3735eb4e80e152b28af9..1b03d0bfcb4014b3a133bf5bf1df028967eeab27 100644 (file)
@@ -45,13 +45,14 @@ freebsd*)
        build_target=freebsd
        ;;
 darwin*)
-       build_target=freebsd
+       build_target=macos
        ;;
 *)
        ;;
 esac
 
 AM_CONDITIONAL([FREEBSD], [test x$build_target = xfreebsd])
+AM_CONDITIONAL([MACOS], [test x$build_target = xmacos])
 
 AC_ARG_ENABLE(
        [plugin-nfacct],
index c2918744a215fcdb8a3863f41a6b722fc85c009a..8df6b61fcfb3e05956ef025bba460d1edcf522ff 100644 (file)
@@ -67,6 +67,13 @@ netdata_SOURCES += \
        freebsd_sysctl.c \
        $(NULL)
 else
+if MACOS
+netdata_SOURCES += \
+       plugin_macos.c plugin_macos.h \
+       macos_sysctl.c \
+       macos_mach_smi.c \
+       $(NULL)
+else
 netdata_SOURCES += \
        plugin_proc.c plugin_proc.h \
        proc_diskstats.c \
@@ -91,6 +98,7 @@ netdata_SOURCES += \
        sys_kernel_mm_ksm.c \
        $(NULL)
 endif
+endif
 
 netdata_LDADD = \
        $(OPTIONAL_MATH_LIBS) \
index d0084f6c0045754f09d517e69c5b1a1f8da27fce..baa95dcb07e92a7505d11f9e1204a87cc519f13d 100644 (file)
 #include "plugin_checks.h"
 #include "plugin_idlejitter.h"
 #include "plugin_nfacct.h"
-#if !(defined(__FreeBSD__) || defined(__APPLE__))
-#include "plugin_proc.h"
-#else
+#if defined(__FreeBSD__)
 #include "plugin_freebsd.h"
-#endif /* __FreeBSD__ || __APPLE__*/
+#elif defined(__APPLE__)
+#include "plugin_macos.h"
+#else
+#include "plugin_proc.h"
+#endif /* __FreeBSD__, __APPLE__*/
 #include "plugin_tc.h"
 #include "plugins_d.h"
 
index 30768ffa72243f981872bce2711abf7cce29ca07..da85b838331a862aaca5a4ffbb614d9b796e6940 100644 (file)
@@ -1,6 +1,5 @@
 #include "common.h"
 
-#ifndef __APPLE__
 // NEEDED BY: struct vmtotal, struct vmmeter
 #include <sys/vmmeter.h>
 // NEEDED BY: struct devstat
@@ -19,7 +18,6 @@
 #define _IFI_OQDROPS // It is for FreeNAS only. Most probably in future releases of FreeNAS it will be removed
 #include <net/if.h>
 #include <ifaddrs.h>
-#endif /* __APPLE__ */
 // NEEDED BY: do_disk_io
 #define RRD_TYPE_DISK "disk"
 
@@ -73,7 +71,6 @@ int do_freebsd_sysctl(int update_every, usec_t dt) {
     static usec_t last_loadavg_usec = 0;
     struct loadavg sysload;
 
-#ifndef __APPLE__
     // NEEDED BY: do_cpu, do_cpu_cores
     long cp_time[CPUSTATES];
 
@@ -180,7 +177,6 @@ int do_freebsd_sysctl(int update_every, usec_t dt) {
 
     // --------------------------------------------------------------------
 
-#endif /* __APPLE__ */
     if (last_loadavg_usec <= dt) {
         if (likely(do_loadavg)) {
             if (unlikely(GETSYSCTL("vm.loadavg", sysload))) {
@@ -207,7 +203,6 @@ int do_freebsd_sysctl(int update_every, usec_t dt) {
         last_loadavg_usec = st->update_every * USEC_PER_SEC;
     }
     else last_loadavg_usec -= dt;
-#ifndef __APPLE__
 
     // --------------------------------------------------------------------
 
@@ -1193,7 +1188,6 @@ int do_freebsd_sysctl(int update_every, usec_t dt) {
             freeifaddrs(ifap);
         }
     }
-#endif /* __APPLE__ */
 
     return 0;
 }
diff --git a/src/macos_mach_smi.c b/src/macos_mach_smi.c
new file mode 100644 (file)
index 0000000..a10e5ad
--- /dev/null
@@ -0,0 +1,48 @@
+#include "common.h"
+
+int do_macos_mach_smi(int update_every, usec_t dt) {
+    (void)dt;
+
+    static int do_cpu = -1;
+
+    if (unlikely(do_cpu == -1)) {
+        do_cpu                  = config_get_boolean("plugin:macos:mach_smi", "cpu utilization", 1);
+    }
+
+    RRDSET *st;
+
+    // NEEDED BY: do_cpu, do_cpu_cores
+    long cp_time[5];
+
+    // --------------------------------------------------------------------
+
+    if (likely(do_cpu)) {
+        if (unlikely(1)) {
+            do_cpu = 0;
+            error("DISABLED: system.cpu");
+        } else {
+
+            st = rrdset_find_bytype("system", "cpu");
+            if (unlikely(!st)) {
+                st = rrdset_create("system", "cpu", NULL, "cpu", "system.cpu", "Total CPU utilization", "percentage", 100, update_every, RRDSET_TYPE_STACKED);
+
+                rrddim_add(st, "user", NULL, 1, 1, RRDDIM_PCENT_OVER_DIFF_TOTAL);
+                rrddim_add(st, "nice", NULL, 1, 1, RRDDIM_PCENT_OVER_DIFF_TOTAL);
+                rrddim_add(st, "system", NULL, 1, 1, RRDDIM_PCENT_OVER_DIFF_TOTAL);
+                rrddim_add(st, "interrupt", NULL, 1, 1, RRDDIM_PCENT_OVER_DIFF_TOTAL);
+                rrddim_add(st, "idle", NULL, 1, 1, RRDDIM_PCENT_OVER_DIFF_TOTAL);
+                rrddim_hide(st, "idle");
+            }
+            else rrdset_next(st);
+
+            rrddim_set(st, "user", cp_time[0]);
+            rrddim_set(st, "nice", cp_time[1]);
+            rrddim_set(st, "system", cp_time[2]);
+            rrddim_set(st, "interrupt", cp_time[3]);
+            rrddim_set(st, "idle", cp_time[4]);
+            rrdset_done(st);
+        }
+     }
+
+    return 0;
+}
diff --git a/src/macos_sysctl.c b/src/macos_sysctl.c
new file mode 100644 (file)
index 0000000..0a37f06
--- /dev/null
@@ -0,0 +1,74 @@
+#include "common.h"
+#include <sys/sysctl.h>
+
+#define GETSYSCTL(name, var) getsysctl(name, &(var), sizeof(var))
+
+// MacOS calculates load averages once every 5 seconds
+#define MIN_LOADAVG_UPDATE_EVERY 5
+
+int getsysctl(const char *name, void *ptr, size_t len);
+
+int do_macos_sysctl(int update_every, usec_t dt) {
+    (void)dt;
+
+    static int do_loadavg = -1;
+
+    if (unlikely(do_loadavg == -1)) {
+        do_loadavg              = config_get_boolean("plugin:macos:sysctl", "enable load average", 1);
+    }
+
+    RRDSET *st;
+
+    int system_pagesize = getpagesize(); // wouldn't it be better to get value directly from hw.pagesize?
+    int i, n;
+    int common_error = 0;
+    size_t size;
+
+    // NEEDED BY: do_loadavg
+    static usec_t last_loadavg_usec = 0;
+    struct loadavg sysload;
+
+    if (last_loadavg_usec <= dt) {
+        if (likely(do_loadavg)) {
+            if (unlikely(GETSYSCTL("vm.loadavg", sysload))) {
+                do_loadavg = 0;
+                error("DISABLED: system.load");
+            } else {
+
+                st = rrdset_find_bytype("system", "load");
+                if (unlikely(!st)) {
+                    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);
+                    rrddim_add(st, "load1", NULL, 1, 1000, RRDDIM_ABSOLUTE);
+                    rrddim_add(st, "load5", NULL, 1, 1000, RRDDIM_ABSOLUTE);
+                    rrddim_add(st, "load15", NULL, 1, 1000, RRDDIM_ABSOLUTE);
+                }
+                else rrdset_next(st);
+
+                rrddim_set(st, "load1", (collected_number) ((double)sysload.ldavg[0] / sysload.fscale * 1000));
+                rrddim_set(st, "load5", (collected_number) ((double)sysload.ldavg[1] / sysload.fscale * 1000));
+                rrddim_set(st, "load15", (collected_number) ((double)sysload.ldavg[2] / sysload.fscale * 1000));
+                rrdset_done(st);
+            }
+        }
+
+        last_loadavg_usec = st->update_every * USEC_PER_SEC;
+    }
+    else last_loadavg_usec -= dt;
+
+    return 0;
+}
+
+int getsysctl(const char *name, void *ptr, size_t len)
+{
+    size_t nlen = len;
+
+    if (unlikely(sysctlbyname(name, ptr, &nlen, NULL, 0) == -1)) {
+        error("MACOS: sysctl(%s...) failed: %s", name, strerror(errno));
+        return 1;
+    }
+    if (unlikely(nlen != len)) {
+        error("MACOS: sysctl(%s...) expected %lu, got %lu", name, (unsigned long)len, (unsigned long)nlen);
+        return 1;
+    }
+    return 0;
+}
index ab651a7735169cdd38e0ecd201761909b20348e1..d55e1c2662148da5d8d036fea426d27cfc86b1a5 100644 (file)
@@ -45,11 +45,13 @@ struct netdata_static_thread {
 
     {"tc",                 "plugins",   "tc",         1, NULL, NULL, tc_main},
     {"idlejitter",         "plugins",   "idlejitter", 1, NULL, NULL, cpuidlejitter_main},
-#if !(defined(__FreeBSD__) || defined(__APPLE__))
-    {"proc",               "plugins",   "proc",       1, NULL, NULL, proc_main},
-#else
+#if defined(__FreeBSD__)
     {"freebsd",            "plugins",   "freebsd",    1, NULL, NULL, freebsd_main},
-#endif /* __FreeBSD__ || __APPLE__*/
+#elif defined(__APPLE__)
+    {"macos",              "plugins",   "macos",      1, NULL, NULL, macos_main},
+#else
+    {"proc",               "plugins",   "proc",       1, NULL, NULL, proc_main},
+#endif /* __FreeBSD__, __APPLE__*/
     {"cgroups",            "plugins",   "cgroups",    1, NULL, NULL, cgroups_main},
     {"check",              "plugins",   "checks",     0, NULL, NULL, checks_main},
     {"backends",            NULL,       NULL,         1, NULL, NULL, backends_main},
diff --git a/src/plugin_macos.c b/src/plugin_macos.c
new file mode 100644 (file)
index 0000000..2f3a9cf
--- /dev/null
@@ -0,0 +1,74 @@
+#include "common.h"
+
+void *macos_main(void *ptr)
+{
+    (void)ptr;
+
+    info("MACOS Plugin thread created with task id %d", gettid());
+
+    if(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) != 0)
+        error("Cannot set pthread cancel type to DEFERRED.");
+
+    if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0)
+        error("Cannot set pthread cancel state to ENABLE.");
+
+    // disable (by default) various interface that are not needed
+    /*
+    config_get_boolean("plugin:proc:/proc/net/dev:lo", "enabled", 0);
+    config_get_boolean("plugin:proc:/proc/net/dev:fireqos_monitor", "enabled", 0);
+    */
+
+    // when ZERO, attempt to do it
+    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);
+
+    // keep track of the time each module was called
+    unsigned long long sutime_macos_sysctl = 0ULL;
+    unsigned long long sutime_macos_mach_smi = 0ULL;
+
+    usec_t step = rrd_update_every * USEC_PER_SEC;
+    for(;;) {
+        usec_t now = now_realtime_usec();
+        usec_t next = now - (now % step) + step;
+
+        while(now < next) {
+            sleep_usec(next - now);
+            now = now_realtime_usec();
+        }
+
+        if(unlikely(netdata_exit)) break;
+
+        // BEGIN -- the job to be done
+
+        if(!vdo_macos_sysctl) {
+            debug(D_PROCNETDEV_LOOP, "MACOS: calling do_macos_sysctl().");
+            now = now_realtime_usec();
+            vdo_macos_sysctl = do_macos_sysctl(rrd_update_every, (sutime_macos_sysctl > 0)?now - sutime_macos_sysctl:0ULL);
+            sutime_macos_sysctl = now;
+        }
+        if(unlikely(netdata_exit)) break;
+
+        if(!vdo_macos_mach_smi) {
+            debug(D_PROCNETDEV_LOOP, "MACOS: calling do_macos_mach_smi().");
+            now = now_realtime_usec();
+            vdo_macos_mach_smi = do_macos_mach_smi(rrd_update_every, (sutime_macos_mach_smi > 0)?now - sutime_macos_mach_smi:0ULL);
+            sutime_macos_mach_smi = now;
+        }
+        if(unlikely(netdata_exit)) break;
+
+        // END -- the job is done
+
+        // --------------------------------------------------------------------
+
+        if(!vdo_cpu_netdata) {
+            global_statistics_charts();
+            registry_statistics();
+        }
+    }
+
+    info("MACOS thread exiting");
+
+    pthread_exit(NULL);
+    return NULL;
+}
diff --git a/src/plugin_macos.h b/src/plugin_macos.h
new file mode 100644 (file)
index 0000000..b903ff5
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef NETDATA_PLUGIN_MACOS_H
+#define NETDATA_PLUGIN_MACOS_H 1
+
+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);
+
+#endif /* NETDATA_PLUGIN_MACOS_H */