A simple pythonic script to log internet bandwidth usage on Linux

We often want to log internet bandwidth on our laptops or PCs in order to track our usage over a period of time. This also comes handy to cross-check our usage with that of our ISP’s invoice. Now how to do it on linux? While the Windows folk have all kinds of utilities for this kind of thing, we lunix folk have to invent it ourselves.

Some time ago, I wrote this small python script that writes your bandwidth stats to a log file each time you disconnect your internet connection. This, I’ve tested on ubuntu 12.04 and debian wheezy:

Source file: Tata.py

#!/usr/bin/python
# author: Prahlad Yeri
import subprocess, os, datetime, sys
def execute(command):
    try:
        p=subprocess.Popen(command, shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
        p.wait()
        result=p.communicate()
        #print str(result)
        if len(result[0])>0:
            return result[0].strip()
        else:
            return result[1].strip()
    except Exception as e:
        print ‘error occured:’ + errorstring
        return errorstring
#main
mypath = ‘/etc/NetworkManager/dispatcher.d/’
iface = sys.argv[1].strip()
status = sys.argv[2].strip()
log=open(mypath + ‘tata.log’,’a’)
#log.write(iface + ‘:’ + status + ‘\n’)
#log.close()
for part in sys.argv:
        log.write(‘argv:’ + part + ‘\n’)
if (iface == ‘ppp0’ or iface == ‘ttyUSB0’) and status == ‘down’:
        s = execute(‘iptables -L -v’)
        rules = s.splitlines()
        rx,tx = 0,0
        rxdrop, txdrop = 0,0
        inrule = False
        outrule = False
        for rule in rules:
                log.write(‘rule:’ + rule.strip() + ‘\n’)
                words = rule.strip().split()
                if rule.strip().startswith(“Chain OUTPUT”):
                        log.write(‘switch to outrule’)
                        outrule = True
                        inrule = False
                elif rule.strip().startswith(“Chain INPUT”):
                        log.write(‘switch to inrule’)
                        inrule = True
                        outrule = False
                elif rule.strip().startswith(“Chain FORWARD”):
                        log.write(‘switch to no rule’)
                        inrule=False
                        outrule=False
                elif len(words) >=3:
                        if words[6].strip() == “ppp0”:
                                #log.write(‘bytes=’ + words[1]
                                if inrule:
                                        if words[2].strip() == ‘DROP’:
                                                rxdrop += int(words[1].replace(‘K’,’000′).replace(‘M’,’000000′))
                                        else:
                                                rx += int(words[1].replace(‘K’,’000′).replace(‘M’,’000000′))
                                elif outrule:
                                        if words[2].strip() == ‘DROP’:
                                                txdrop += int(words[1].replace(‘K’,’000′).replace(‘M’,’000000′))
                                        else:
                                                tx += int(words[1].replace(‘K’,’000′).replace(‘M’,’000000′))
        #print ‘rx=’ + str(rx) + ‘ tx=’ + str(tx)
        #print ‘rxdrop=’ + str(rxdrop) + ‘ txdrop=’ + str(txdrop)
        execute(“iptables –zero”)
        header=”
        lines=[]
        if not os.path.exists(mypath + ‘usage.csv’):
                #create header
                header = ‘date,rx,tx,rx-dropped,tx-dropped,rx-tot,tx-tot\n’
        f = open(mypath + ‘usage.csv’,’a’)
        if len(header) > 0:
                lines.append(header)
        lines.append(str(datetime.datetime.now()).split(‘.’)[0] + ‘,’ + str(rx) + ‘,’ + str(tx) + ‘,’ + str(rxdrop) + ‘,’ + str(txdrop) + ‘,’ + str(rx+rxdrop) + ‘,’ + str(tx+txdrop) + ‘\n’)
        #rx = execute(‘cat /sys/class/net/ppp0/statistics/rx_bytes’)
        #tx = execute(‘cat /sys/class/net/ppp0/statistics/tx_bytes’)
        #strdate=str(datetime.datetime.now())
        #line = strdate + ‘,’ + rx + ‘,’ + tx + ‘\n’
        f.writelines(lines)
        f.close()
        log.close()
        sys.exit(0)

In the above script, replace ppp0 with the interface-name for the name of interface through which you access internet. For mobile broadbands it is typically ppp0, but you can issue the “ifconfig” command to list them all and make sure.

You have to place this script at /etc/NetworkManager/dispatcher.d on debian/ubuntu systems so that it runs each time you stop using the modem. In case of other systems, or in case you don’t use NetworkManager, refer to your distro documentation to check the folder/script which is executed when an interface is down.

Advertisements