2 #include <sys/sysctl.h>
3 // NEEDED BY: do_bandwidth
6 #define GETSYSCTL(name, var) getsysctl(name, &(var), sizeof(var))
8 // MacOS calculates load averages once every 5 seconds
9 #define MIN_LOADAVG_UPDATE_EVERY 5
11 int getsysctl(const char *name, void *ptr, size_t len);
13 int do_macos_sysctl(int update_every, usec_t dt) {
16 static int do_loadavg = -1, do_swap = -1, do_bandwidth = -1;
18 if (unlikely(do_loadavg == -1)) {
19 do_loadavg = config_get_boolean("plugin:macos:sysctl", "enable load average", 1);
20 do_swap = config_get_boolean("plugin:macos:sysctl", "system swap", 1);
21 do_bandwidth = config_get_boolean("plugin:macos:sysctl", "bandwidth", 1);
26 int system_pagesize = getpagesize(); // wouldn't it be better to get value directly from hw.pagesize?
31 // NEEDED BY: do_loadavg
32 static usec_t last_loadavg_usec = 0;
33 struct loadavg sysload;
36 struct xsw_usage swap_usage;
38 // NEEDED BY: do_bandwidth
40 static char *ifstatdata = NULL;
42 struct if_msghdr *ifm;
48 if (last_loadavg_usec <= dt) {
49 if (likely(do_loadavg)) {
50 if (unlikely(GETSYSCTL("vm.loadavg", sysload))) {
52 error("DISABLED: system.load");
55 st = rrdset_find_bytype("system", "load");
57 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);
58 rrddim_add(st, "load1", NULL, 1, 1000, RRDDIM_ABSOLUTE);
59 rrddim_add(st, "load5", NULL, 1, 1000, RRDDIM_ABSOLUTE);
60 rrddim_add(st, "load15", NULL, 1, 1000, RRDDIM_ABSOLUTE);
64 rrddim_set(st, "load1", (collected_number) ((double)sysload.ldavg[0] / sysload.fscale * 1000));
65 rrddim_set(st, "load5", (collected_number) ((double)sysload.ldavg[1] / sysload.fscale * 1000));
66 rrddim_set(st, "load15", (collected_number) ((double)sysload.ldavg[2] / sysload.fscale * 1000));
71 last_loadavg_usec = st->update_every * USEC_PER_SEC;
73 else last_loadavg_usec -= dt;
75 if (likely(do_swap)) {
76 if (unlikely(GETSYSCTL("vm.swapusage", swap_usage))) {
78 error("DISABLED: system.swap");
80 st = rrdset_find("system.swap");
82 st = rrdset_create("system", "swap", NULL, "swap", NULL, "System Swap", "MB", 201, update_every, RRDSET_TYPE_STACKED);
85 rrddim_add(st, "free", NULL, 1, 1048576, RRDDIM_ABSOLUTE);
86 rrddim_add(st, "used", NULL, 1, 1048576, RRDDIM_ABSOLUTE);
90 rrddim_set(st, "free", swap_usage.xsu_avail);
91 rrddim_set(st, "used", swap_usage.xsu_used);
96 // --------------------------------------------------------------------
98 if (likely(do_bandwidth)) {
103 mib[4] = NET_RT_IFLIST2;
105 if (unlikely(sysctl(mib, 6, NULL, &size, NULL, 0))) {
106 error("MACOS: sysctl(%s...) failed: %s", "net interfaces", strerror(errno));
108 error("DISABLED: system.ipv4");
110 ifstatdata = reallocz(ifstatdata, size);
111 if (unlikely(sysctl(mib, 6, ifstatdata, &size, NULL, 0) < 0)) {
112 error("MACOS: sysctl(%s...) failed: %s", "net interfaces", strerror(errno));
114 error("DISABLED: system.ipv4");
116 lim = ifstatdata + size;
117 iftot.ift_ibytes = iftot.ift_obytes = 0;
118 for (next = ifstatdata; next < lim; ) {
119 ifm = (struct if_msghdr *)next;
120 next += ifm->ifm_msglen;
122 if (ifm->ifm_type == RTM_IFINFO2) {
123 struct if_msghdr2 *if2m = (struct if_msghdr2 *)ifm;
125 iftot.ift_ibytes += if2m->ifm_data.ifi_ibytes;
126 iftot.ift_obytes += if2m->ifm_data.ifi_obytes;
129 st = rrdset_find("system.ipv4");
131 st = rrdset_create("system", "ipv4", NULL, "network", NULL, "IPv4 Bandwidth", "kilobits/s", 500, update_every, RRDSET_TYPE_AREA);
133 rrddim_add(st, "InOctets", "received", 8, 1024, RRDDIM_INCREMENTAL);
134 rrddim_add(st, "OutOctets", "sent", -8, 1024, RRDDIM_INCREMENTAL);
136 else rrdset_next(st);
138 rrddim_set(st, "InOctets", iftot.ift_ibytes);
139 rrddim_set(st, "OutOctets", iftot.ift_obytes);
148 int getsysctl(const char *name, void *ptr, size_t len)
152 if (unlikely(sysctlbyname(name, ptr, &nlen, NULL, 0) == -1)) {
153 error("MACOS: sysctl(%s...) failed: %s", name, strerror(errno));
156 if (unlikely(nlen != len)) {
157 error("MACOS: sysctl(%s...) expected %lu, got %lu", name, (unsigned long)len, (unsigned long)nlen);