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],
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 \
sys_kernel_mm_ksm.c \
$(NULL)
endif
+endif
netdata_LDADD = \
$(OPTIONAL_MATH_LIBS) \
#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"
#include "common.h"
-#ifndef __APPLE__
// NEEDED BY: struct vmtotal, struct vmmeter
#include <sys/vmmeter.h>
// NEEDED BY: struct devstat
#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"
static usec_t last_loadavg_usec = 0;
struct loadavg sysload;
-#ifndef __APPLE__
// NEEDED BY: do_cpu, do_cpu_cores
long cp_time[CPUSTATES];
// --------------------------------------------------------------------
-#endif /* __APPLE__ */
if (last_loadavg_usec <= dt) {
if (likely(do_loadavg)) {
if (unlikely(GETSYSCTL("vm.loadavg", sysload))) {
last_loadavg_usec = st->update_every * USEC_PER_SEC;
}
else last_loadavg_usec -= dt;
-#ifndef __APPLE__
// --------------------------------------------------------------------
freeifaddrs(ifap);
}
}
-#endif /* __APPLE__ */
return 0;
}
--- /dev/null
+#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;
+}
--- /dev/null
+#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;
+}
{"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},
--- /dev/null
+#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;
+}
--- /dev/null
+#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 */