]> arthur.barton.de Git - netdata.git/commitdiff
Add IPv4 bandwidth chart to macOS plugin
authorVladimir Kobal <vlad@prokk.net>
Wed, 28 Dec 2016 13:40:32 +0000 (08:40 -0500)
committerVladimir Kobal <vlad@prokk.net>
Wed, 28 Dec 2016 13:40:32 +0000 (08:40 -0500)
src/macos_sysctl.c

index 8a129dabf70125c161a47f692ebd5a82b9fe5c11..1f02a63b121bece5195426b3cf1dbd48aa736c9e 100644 (file)
@@ -1,5 +1,7 @@
 #include "common.h"
 #include <sys/sysctl.h>
+// NEEDED BY: do_bandwidth
+#include <net/route.h>
 
 #define GETSYSCTL(name, var) getsysctl(name, &(var), sizeof(var))
 
@@ -11,11 +13,12 @@ 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, do_swap = -1;
+    static int do_loadavg = -1, do_swap = -1, do_bandwidth = -1;
 
     if (unlikely(do_loadavg == -1)) {
         do_loadavg              = config_get_boolean("plugin:macos:sysctl", "enable load average", 1);
         do_swap                 = config_get_boolean("plugin:macos:sysctl", "system swap", 1);
+        do_bandwidth            = config_get_boolean("plugin:macos:sysctl", "bandwidth", 1);
     }
 
     RRDSET *st;
@@ -32,6 +35,16 @@ int do_macos_sysctl(int update_every, usec_t dt) {
     // NEEDED BY: do_swap
     struct xsw_usage swap_usage;
 
+    // NEEDED BY: do_bandwidth
+    int mib[6];
+    static char *ifstatdata = NULL;
+    char *lim, *next;
+    struct if_msghdr *ifm;
+    struct iftot {
+        u_long  ift_ibytes;
+        u_long  ift_obytes;
+    } iftot = {0, 0};
+
     if (last_loadavg_usec <= dt) {
         if (likely(do_loadavg)) {
             if (unlikely(GETSYSCTL("vm.loadavg", sysload))) {
@@ -80,6 +93,55 @@ int do_macos_sysctl(int update_every, usec_t dt) {
         }
     }
 
+    // --------------------------------------------------------------------
+
+    if (likely(do_bandwidth)) {
+        mib[0] = CTL_NET;
+        mib[1] = PF_ROUTE;
+        mib[2] = 0;
+        mib[3] = AF_INET;
+        mib[4] = NET_RT_IFLIST2;
+        mib[5] = 0;
+        if (unlikely(sysctl(mib, 6, NULL, &size, NULL, 0))) {
+            error("MACOS: sysctl(%s...) failed: %s", "net interfaces", strerror(errno));
+            do_bandwidth = 0;
+            error("DISABLED: system.ipv4");
+        } else {
+            ifstatdata = reallocz(ifstatdata, size);
+            if (unlikely(sysctl(mib, 6, ifstatdata, &size, NULL, 0) < 0)) {
+                error("MACOS: sysctl(%s...) failed: %s", "net interfaces", strerror(errno));
+                do_bandwidth = 0;
+                error("DISABLED: system.ipv4");
+            } else {
+                lim = ifstatdata + size;
+                iftot.ift_ibytes = iftot.ift_obytes = 0;
+                for (next = ifstatdata; next < lim; ) {
+                    ifm = (struct if_msghdr *)next;
+                    next += ifm->ifm_msglen;
+
+                    if (ifm->ifm_type == RTM_IFINFO2) {
+                        struct if_msghdr2 *if2m = (struct if_msghdr2 *)ifm;
+
+                        iftot.ift_ibytes += if2m->ifm_data.ifi_ibytes;
+                        iftot.ift_obytes += if2m->ifm_data.ifi_obytes;
+                    }
+                }
+                st = rrdset_find("system.ipv4");
+                if (unlikely(!st)) {
+                    st = rrdset_create("system", "ipv4", NULL, "network", NULL, "IPv4 Bandwidth", "kilobits/s", 500, update_every, RRDSET_TYPE_AREA);
+
+                    rrddim_add(st, "InOctets", "received", 8, 1024, RRDDIM_INCREMENTAL);
+                    rrddim_add(st, "OutOctets", "sent", -8, 1024, RRDDIM_INCREMENTAL);
+                }
+                else rrdset_next(st);
+
+                rrddim_set(st, "InOctets", iftot.ift_ibytes);
+                rrddim_set(st, "OutOctets", iftot.ift_obytes);
+                rrdset_done(st);
+            }
+        }
+    }
+
     return 0;
 }