About half an hour of spare time got me this (sorry for the length):
#!/usr/bin/env python
#
# ifmon.py
#
# ifmon.py -- a prototype network throughput monitor for Linux
# Copyright (C) 2008 nixscripter@gmail.com
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# version 2 as published by the Free Software Foundation (not any
# later version).
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA
#
import re, os, sys
# default statistics file: $HOME/.ifpoll/stats
sf=os.path.join(os.environ['HOME'],".ifpoll"+os.path.sep+"stats")
ifaces = {}
def init(statfile): # reads data from previous boots, called first thing
if os.path.exists(statfile):
for line in file(statfile):
iface, nbytes = line.strip().split(":")
iface = iface.strip()
nbytes = nbytes.strip()
ifaces[iface] = int(nbytes)
assert os.path.exists("/proc/net/dev")
for line in file("/proc/net/dev"):
line = line.strip()
m = re.search(r"^(\w+):\s*(\d+)", line)
if not m: continue
iface = m.groups()[0]
if iface not in ifaces.keys(): ifaces[iface] = 0
def save_data(statfile): # writes data collected, called by signal handlers
for line in file("/proc/net/dev"):
line = line.strip()
m = re.search(r"^(\w+):\s*(\d+)", line)
if not m: continue
iface, nbytes = m.groups()
if iface not in ifaces.keys(): ifaces[iface] = 0
ifaces[iface] += int(nbytes)
if not os.path.exists(os.path.dirname(statfile)):
os.mkdir(os.path.dirname(statfile))
f = file(statfile, 'w')
for iface in ifaces.keys():
f.write("%s:%d\n" % (iface, ifaces[iface]))
f.close()
def since_last_reboot(interface):
assert os.path.exists("/proc/net/dev")
for line in file("/proc/net/dev", 'r'):
line = line.strip()
m = re.search(r"^(\w+):\s*(\d+)", line)
if not m: continue
iface, nbytes = m.groups()
if iface == interface: return int(nbytes)
return 0
def main(args):
if len(args) < 1:
print "Expected arguments"
return False
cmd = args.pop(0)
if cmd == 'reset':
save_data(sf)
print "data saved (in preparation for reboot)"
return True
if len(args) < 1:
print "Expected arguments"
return False
iface = args.pop(0)
if not iface in ifaces.keys():
print "Unknown interface '%s'" % iface
return False
if cmd == 'last':
l = since_last_reboot(iface)
print "interface has recieved ",l,"bytes of data since last reboot"
elif cmd == 'total':
t = ifaces[iface]
l = since_last_reboot(iface)
if not t or not l:
print "Unknown interface '%s'" % iface
return False
print "interface has recieved ",(t+l),"bytes of data"
else:
print "Invalid command"
return False
return True
init(sf)
if not main(sys.argv[1:]):
print "Usage: %s { reset | last | total } interface" % \
os.path.basename(sys.argv[0])
sys.exit(1)
else:
sys.exit(0)
Python is one of my good languages, and has GTK+ bindings.
My assumption is that the kernel stats are saved forever until the interface disappears. Then someone has to use the "reset" function to save the totals and consider the ones it gets next time as new.