[gnome-system-monitor/ubergraph: 7/7] Convert procfs based network usage to GLibTop based per-interface stats
- From: Robert Roth <robertroth src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-system-monitor/ubergraph: 7/7] Convert procfs based network usage to GLibTop based per-interface stats
- Date: Sun, 14 Jul 2013 00:37:05 +0000 (UTC)
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]