[gnome-system-monitor/ubergraph: 7/7] Convert procfs based network usage to GLibTop based per-interface stats



commit 40902b66bcf6a924332e015911b391594eb4aa59
Author: Robert Roth <robert roth off gmail com>
Date:   Sun Jul 14 03:36:21 2013 +0300

    Convert procfs based network usage to GLibTop based per-interface stats

 src/sysmon.c         |  134 +++++++++++++++++++++++++++++--------------------
 src/sysmon.h         |   19 +++++--
 src/system-monitor.c |   44 ++++++++++------
 3 files changed, 120 insertions(+), 77 deletions(-)
---
diff --git a/src/sysmon.c b/src/sysmon.c
index f8a75fe..04d1b7d 100644
--- a/src/sysmon.c
+++ b/src/sysmon.c
@@ -3,6 +3,9 @@
 #include <stdlib.h>
 #include <dlfcn.h>
 #include <gtk/gtk.h>
+#include <glib.h>
+#include <glibtop/netlist.h>
+#include <glibtop/netload.h>
 
 #include "sysmon.h"
 
@@ -21,6 +24,22 @@ smon_cpu_has_freq_scaling (gint cpu)
        return ret;
 }
 
+gsize
+smon_get_cpu_count (void)
+{
+   return get_nprocs();
+}
+
+gsize
+smon_get_net_interface_count (void)
+{  
+   if (G_UNLIKELY(!net_info.len)) {
+       glibtop_netlist dummy;
+       return g_strv_length(glibtop_get_netlist(&dummy));
+   }
+   return net_info.len;
+}
+
 gdouble
 smon_get_cpu_info (UberLineGraph *graph,     /* IN */
               guint          line,      /* IN */
@@ -31,18 +50,14 @@ smon_get_cpu_info (UberLineGraph *graph,     /* IN */
        gdouble value = UBER_LINE_GRAPH_NO_VALUE;
 
        g_assert_cmpint(line, >, 0);
-       g_assert_cmpint(line, <=, cpu_info.len * 2);
+       g_assert_cmpint(line, <=, cpu_info.len);
 
-       if ((line % 2) != 0) {
-               i = (line - 1) / 2;
-               value = cpu_info.total[i] * cpu_info.freq[i] / 100.0;
-               /*
-                * Update label text.
-                */
-               text = g_strdup_printf("CPU%d  %0.1f %%", i + 1, value);
-               uber_label_set_text(UBER_LABEL(cpu_info.labels[i]), text);
-               g_free(text);
-       } // else value = cpu_info.freq[((line - 1) / 2)];
+    i = line-1;
+    value = cpu_info.total[i] * cpu_info.freq[i] / 100.0;
+       /* Update label text. */
+       text = g_strdup_printf("CPU%d  %0.1f %%", i + 1, value);
+       uber_label_set_text(UBER_LABEL(cpu_info.labels[i]), text);
+       g_free(text);
        return value;
 }
 
@@ -52,12 +67,14 @@ smon_get_net_info (UberLineGraph *graph,     /* IN */
               gpointer       user_data) /* IN */
 {
        gdouble value = UBER_LINE_GRAPH_NO_VALUE;
-       switch (line) {
-       case 1:
-               value = net_info.total_in;
+       switch (line % 2) {
+       case 0:
+        if (net_info.total_in!=NULL)
+               value = net_info.total_in[line / 2];
                break;
-       case 2:
-               value = net_info.total_out;
+       case 1:
+        if (net_info.total_out !=NULL)
+               value = net_info.total_out[line / 2];
                break;
        default:
                g_assert_not_reached();
@@ -202,54 +219,61 @@ smon_next_cpu_freq_info (void)
 void
 smon_next_net_info (void)
 {
-       GError *error = NULL;
        gulong total_in = 0;
        gulong total_out = 0;
-       gulong bytes_in;
-       gulong bytes_out;
-       gulong dummy;
-       gchar *buf = NULL;
-       gchar iface[32] = { 0 };
-       gchar *line;
        gsize len;
-       gint l = 0;
+    gsize count = 0;
        gint i;
 
-       if (!g_file_get_contents("/proc/net/dev", &buf, &len, &error)) {
-               g_printerr("%s", error->message);
-               g_error_free(error);
-               return;
+   if (G_UNLIKELY(!net_info.len)) {
+        glibtop_netlist netlist;
+
+        net_info.ifnames = glibtop_get_netlist(&netlist);
+        
+        net_info.len = g_strv_length(net_info.ifnames);
+
+        g_assert(net_info.len);
+               /*
+                * Allocate data for sampling.
+                */
+               net_info.labels = g_new0(GtkWidget*, 2*net_info.len);
+        net_info.total_out = g_new0(gdouble, net_info.len);
+               net_info.total_in = g_new0(gdouble, net_info.len);
+               net_info.last_total_out = g_new0(gdouble, net_info.len);
+               net_info.last_total_in = g_new0(gdouble, net_info.len);
+
        }
 
-       line = buf;
+    len = net_info.len;
+
        for (i = 0; i < len; i++) {
-               if (buf[i] == ':') {
-                       buf[i] = ' ';
-               } else if (buf[i] == '\n') {
-                       buf[i] = '\0';
-                       if (++l > 2) { // ignore first two lines
-                               if (sscanf(line, "%31s %lu %lu %lu %lu %lu %lu %lu %lu %lu",
-                                          iface, &bytes_in,
-                                          &dummy, &dummy, &dummy, &dummy,
-                                          &dummy, &dummy, &dummy,
-                                          &bytes_out) != 10) {
-                                       g_warning("Skipping invalid line: %s", line);
-                               } else if (g_strcmp0(iface, "lo") != 0) {
-                                       total_in += bytes_in;
-                                       total_out += bytes_out;
-                               }
-                               line = NULL;
-                       }
-                       line = &buf[++i];
-               }
-       }
+        glibtop_netload netload;
+        glibtop_get_netload (&netload, net_info.ifnames[i]);
+        if (netload.if_flags & (1 << GLIBTOP_IF_FLAGS_LOOPBACK))
+            continue;
 
-       if ((net_info.last_total_in != 0.) && (net_info.last_total_out != 0.)) {
-               net_info.total_in = (total_in - net_info.last_total_in);
-               net_info.total_out = (total_out - net_info.last_total_out);
+        /* Skip interfaces without any IPv4/IPv6 address (or
+           those with only a LINK ipv6 addr) However we need to
+           be able to exclude these while still keeping the
+           value so when they get online (with NetworkManager
+           for example) we don't get a suddent peak.  Once we're
+           able to get this, ignoring down interfaces will be
+           possible too.  */
+        if (!(netload.flags & (1 << GLIBTOP_NETLOAD_ADDRESS6)
+                 & (netload.scope6 != GLIBTOP_IF_IN6_SCOPE_LINK))
+            & !(netload.flags & (1 << GLIBTOP_NETLOAD_ADDRESS)))
+            continue;
+               total_in = netload.bytes_in;
+               total_out = netload.bytes_out;
+        if ((net_info.last_total_in[i] != 0.) && (net_info.last_total_out[count] != 0.)) {
+                   net_info.total_in[count] = (total_in - net_info.last_total_in[count]);
+                   net_info.total_out[count] = (total_out - net_info.last_total_out[count]);
+           }
+        net_info.ifnames[count] = net_info.ifnames[i];
+        net_info.last_total_in[count] = total_in;
+        net_info.last_total_out[count] = total_out;
+        count++;
        }
+    net_info.len = count;
 
-       net_info.last_total_in = total_in;
-       net_info.last_total_out = total_out;
-       g_free(buf);
 }
diff --git a/src/sysmon.h b/src/sysmon.h
index 2d736ef..a1fd1a0 100644
--- a/src/sysmon.h
+++ b/src/sysmon.h
@@ -1,13 +1,13 @@
 #ifndef __SMONCPU_H__
 #define __SMONCPU_H__
 
-#include <gdk/gdkx.h>
 #include <glib.h>
 
 #include "uber-line-graph.h"
 
 typedef struct
 {
+    // number of cores
        guint       len;
        gdouble    *total;
        gdouble    *freq;
@@ -20,10 +20,13 @@ typedef struct
 
 typedef struct
 {
-       gdouble total_in;
-       gdouble total_out;
-       gdouble last_total_in;
-       gdouble last_total_out;
+    guint    len;
+    gchar   **ifnames;
+       gdouble *total_in;
+       gdouble *total_out;
+       gdouble *last_total_in;
+       gdouble *last_total_out;
+    GtkWidget **labels;
 } NetInfo;
 
 extern CpuInfo      cpu_info;
@@ -50,4 +53,10 @@ smon_next_cpu_freq_info (void);
 void
 smon_next_net_info (void);
 
+gsize
+smon_get_cpu_count (void);
+
+gsize
+smon_get_net_interface_count (void);
+
 #endif /* __SMONCPU_H__ */
diff --git a/src/system-monitor.c b/src/system-monitor.c
index 7bca1f1..ee37b54 100644
--- a/src/system-monitor.c
+++ b/src/system-monitor.c
@@ -51,7 +51,6 @@ gint
 main (gint   argc,   /* IN */
       gchar *argv[]) /* IN */
 {
-       gdouble dashes[] = { 1.0, 4.0 };
        UberRange cpu_range = { 0., 100., 100. };
        UberRange net_range = { 0., 512., 512. };
        GtkWidget *window;
@@ -60,18 +59,21 @@ main (gint   argc,   /* IN */
        GtkWidget *label;
        GtkAccelGroup *ag;
        GdkRGBA color;
-       gint lineno;
-       gint nprocs;
+    gchar* text;
+       gsize nprocs;
+    gsize nnet;
        gint i;
        gint mod;
 
        gtk_init(&argc, &argv);
-       nprocs = get_nprocs();
        /*
         * Warm up differential samplers.
         */
        smon_next_cpu_info();
        smon_next_cpu_freq_info();
+    smon_next_net_info();
+    nprocs = smon_get_cpu_count();
+    nnet = smon_get_net_interface_count();
        /*
         * Create window and graphs.
         */
@@ -98,11 +100,11 @@ main (gint   argc,   /* IN */
                 * XXX: Add the line regardless. Just dont populate it if we don't
                 *      have data.
                 */
-               lineno = uber_line_graph_add_line(UBER_LINE_GRAPH(cpu), &color, NULL);
-               if (smon_cpu_has_freq_scaling(i)) {
-                       uber_line_graph_set_line_dash(UBER_LINE_GRAPH(cpu), lineno,
-                                                     dashes, G_N_ELEMENTS(dashes), 0);
-               }
+               //lineno = uber_line_graph_add_line(UBER_LINE_GRAPH(cpu), &color, NULL);
+               //if (smon_cpu_has_freq_scaling(i)) {
+               //      uber_line_graph_set_line_dash(UBER_LINE_GRAPH(cpu), lineno,
+               //                                    dashes, G_N_ELEMENTS(dashes), 0);
+               //}
        }
        /*
         * Add lines for bytes in/out.
@@ -111,15 +113,23 @@ main (gint   argc,   /* IN */
        uber_line_graph_set_data_func(UBER_LINE_GRAPH(net),
                                      smon_get_net_info, NULL, NULL);
        uber_graph_set_format(UBER_GRAPH(net), UBER_GRAPH_FORMAT_DIRECT1024);
-       label = uber_label_new();
-       uber_label_set_text(UBER_LABEL(label), "Bytes In");
-       gdk_rgba_parse(&color, "#a40000");
-       uber_line_graph_add_line(UBER_LINE_GRAPH(net), &color, UBER_LABEL(label));
-       label = uber_label_new();
-       uber_label_set_text(UBER_LABEL(label), "Bytes Out");
-       gdk_rgba_parse(&color, "#4e9a06");
-       uber_line_graph_add_line(UBER_LINE_GRAPH(net), &color, UBER_LABEL(label));
 
+    for (i = 0; i < nnet; i++) {
+           label = uber_label_new();
+        text = g_strdup_printf("%s Bytes In", net_info.ifnames[i]);
+           uber_label_set_text(UBER_LABEL(label),text);
+        g_free(text);
+           gdk_rgba_parse(&color, "#a40000");
+           uber_line_graph_add_line(UBER_LINE_GRAPH(net), &color, UBER_LABEL(label));
+        net_info.labels[2*i] = label;
+           label = uber_label_new();
+           text = g_strdup_printf("%s Bytes Out", net_info.ifnames[i]);
+           uber_label_set_text(UBER_LABEL(label),text);
+        g_free(text);
+           gdk_rgba_parse(&color, "#4e9a06");
+           uber_line_graph_add_line(UBER_LINE_GRAPH(net), &color, UBER_LABEL(label));
+        net_info.labels[2*i+1] = label;
+    }
        /*
         * Add graphs.
         */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]