OLD | NEW |
(Empty) | |
| 1 #!/usr/bin/env python |
| 2 # |
| 3 # $Id: iotop.py 1160 2011-10-14 18:50:36Z g.rodola@gmail.com $ |
| 4 # |
| 5 # Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved. |
| 6 # Use of this source code is governed by a BSD-style license that can be |
| 7 # found in the LICENSE file. |
| 8 |
| 9 """ |
| 10 Shows real-time network statistics. |
| 11 |
| 12 Author: Giampaolo Rodola' <g.rodola@gmail.com> |
| 13 """ |
| 14 |
| 15 import sys |
| 16 import os |
| 17 if os.name != 'posix': |
| 18 sys.exit('platform not supported') |
| 19 import curses |
| 20 import atexit |
| 21 import time |
| 22 |
| 23 import psutil |
| 24 |
| 25 |
| 26 # --- curses stuff |
| 27 def tear_down(): |
| 28 win.keypad(0) |
| 29 curses.nocbreak() |
| 30 curses.echo() |
| 31 curses.endwin() |
| 32 |
| 33 win = curses.initscr() |
| 34 atexit.register(tear_down) |
| 35 curses.endwin() |
| 36 lineno = 0 |
| 37 |
| 38 def print_line(line, highlight=False): |
| 39 """A thin wrapper around curses's addstr().""" |
| 40 global lineno |
| 41 try: |
| 42 if highlight: |
| 43 line += " " * (win.getmaxyx()[1] - len(line)) |
| 44 win.addstr(lineno, 0, line, curses.A_REVERSE) |
| 45 else: |
| 46 win.addstr(lineno, 0, line, 0) |
| 47 except curses.error: |
| 48 lineno = 0 |
| 49 win.refresh() |
| 50 raise |
| 51 else: |
| 52 lineno += 1 |
| 53 # --- curses stuff |
| 54 |
| 55 |
| 56 def bytes2human(n): |
| 57 """ |
| 58 >>> bytes2human(10000) |
| 59 '9.8 K' |
| 60 >>> bytes2human(100001221) |
| 61 '95.4 M' |
| 62 """ |
| 63 symbols = ('K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y') |
| 64 prefix = {} |
| 65 for i, s in enumerate(symbols): |
| 66 prefix[s] = 1 << (i+1)*10 |
| 67 for s in reversed(symbols): |
| 68 if n >= prefix[s]: |
| 69 value = float(n) / prefix[s] |
| 70 return '%.2f %s' % (value, s) |
| 71 return "0.00 B" |
| 72 |
| 73 def poll(interval): |
| 74 """Retrieve raw stats within an interval window.""" |
| 75 tot_before = psutil.network_io_counters() |
| 76 pnic_before = psutil.network_io_counters(pernic=True) |
| 77 # sleep some time |
| 78 time.sleep(interval) |
| 79 tot_after = psutil.network_io_counters() |
| 80 pnic_after = psutil.network_io_counters(pernic=True) |
| 81 return (tot_before, tot_after, pnic_before, pnic_after) |
| 82 |
| 83 |
| 84 def refresh_window(tot_before, tot_after, pnic_before, pnic_after): |
| 85 """Print stats on screen.""" |
| 86 global lineno |
| 87 |
| 88 # totals |
| 89 print_line("total bytes: sent: %-10s received: %s" \ |
| 90 % (bytes2human(tot_after.bytes_sent), |
| 91 bytes2human(tot_after.bytes_recv)) |
| 92 ) |
| 93 print_line("total packets: sent: %-10s received: %s" \ |
| 94 % (tot_after.packets_sent, tot_after.packets_recv) |
| 95 ) |
| 96 |
| 97 # per network interface |
| 98 print_line("") |
| 99 for nic in pnic_after: |
| 100 stats_before = pnic_before[nic] |
| 101 stats_after = pnic_after[nic] |
| 102 templ = "%-15s %15s %15s" |
| 103 print_line(templ % ( |
| 104 nic, "TOTAL", "PER-SEC"), |
| 105 highlight=True |
| 106 ) |
| 107 print_line(templ % ( |
| 108 "bytes-sent", |
| 109 bytes2human(stats_after.bytes_sent), |
| 110 bytes2human(stats_after.bytes_sent - stats_before.bytes_sent) + '/s'
, |
| 111 )) |
| 112 print_line(templ % ( |
| 113 "bytes-recv", |
| 114 bytes2human(stats_after.bytes_recv), |
| 115 bytes2human(stats_after.bytes_recv - stats_before.bytes_recv) + '/s'
, |
| 116 )) |
| 117 print_line(templ % ( |
| 118 "pkts-sent", |
| 119 stats_after.packets_sent, |
| 120 stats_after.packets_sent - stats_before.packets_sent, |
| 121 )) |
| 122 print_line(templ % ( |
| 123 "pkts-recv", |
| 124 stats_after.packets_recv, |
| 125 stats_after.packets_recv - stats_before.packets_recv, |
| 126 )) |
| 127 print_line("") |
| 128 win.refresh() |
| 129 lineno = 0 |
| 130 |
| 131 |
| 132 def main(): |
| 133 try: |
| 134 interval = 0 |
| 135 while 1: |
| 136 args = poll(interval) |
| 137 refresh_window(*args) |
| 138 interval = 1 |
| 139 except (KeyboardInterrupt, SystemExit): |
| 140 print |
| 141 |
| 142 if __name__ == '__main__': |
| 143 main() |
OLD | NEW |