1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
|
#!/usr/bin/env python3
#
# $Id: iotop.py 1160 2011-10-14 18:50:36Z g.rodola@gmail.com $
#
# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Shows real-time network statistics.
Author: Giampaolo Rodola' <g.rodola@gmail.com>
$ python3 scripts/nettop.py
-----------------------------------------------------------
total bytes: sent: 1.49 G received: 4.82 G
total packets: sent: 7338724 received: 8082712
wlan0 TOTAL PER-SEC
-----------------------------------------------------------
bytes-sent 1.29 G 0.00 B/s
bytes-recv 3.48 G 0.00 B/s
pkts-sent 7221782 0
pkts-recv 6753724 0
eth1 TOTAL PER-SEC
-----------------------------------------------------------
bytes-sent 131.77 M 0.00 B/s
bytes-recv 1.28 G 0.00 B/s
pkts-sent 0 0
pkts-recv 1214470 0
"""
import sys
import time
try:
import curses
except ImportError:
sys.exit('platform not supported')
import psutil
from psutil._common import bytes2human
lineno = 0
win = curses.initscr()
def printl(line, highlight=False):
"""A thin wrapper around curses's addstr()."""
global lineno
try:
if highlight:
line += " " * (win.getmaxyx()[1] - len(line))
win.addstr(lineno, 0, line, curses.A_REVERSE)
else:
win.addstr(lineno, 0, line, 0)
except curses.error:
lineno = 0
win.refresh()
raise
else:
lineno += 1
def poll(interval):
"""Retrieve raw stats within an interval window."""
tot_before = psutil.net_io_counters()
pnic_before = psutil.net_io_counters(pernic=True)
# sleep some time
time.sleep(interval)
tot_after = psutil.net_io_counters()
pnic_after = psutil.net_io_counters(pernic=True)
return (tot_before, tot_after, pnic_before, pnic_after)
def refresh_window(tot_before, tot_after, pnic_before, pnic_after):
"""Print stats on screen."""
global lineno
# totals
printl(
"total bytes: sent: {:<10} received: {}".format(
bytes2human(tot_after.bytes_sent),
bytes2human(tot_after.bytes_recv),
)
)
# per-network interface details: let's sort network interfaces so
# that the ones which generated more traffic are shown first
printl("")
nic_names = list(pnic_after.keys())
nic_names.sort(key=lambda x: sum(pnic_after[x]), reverse=True)
for name in nic_names:
stats_before = pnic_before[name]
stats_after = pnic_after[name]
templ = "{:<15s} {:>15} {:>15}"
# fmt: off
printl(templ.format(name, "TOTAL", "PER-SEC"), highlight=True)
printl(templ.format(
"bytes-sent",
bytes2human(stats_after.bytes_sent),
bytes2human(
stats_after.bytes_sent - stats_before.bytes_sent) + '/s',
))
printl(templ.format(
"bytes-recv",
bytes2human(stats_after.bytes_recv),
bytes2human(
stats_after.bytes_recv - stats_before.bytes_recv) + '/s',
))
printl(templ.format(
"pkts-sent",
stats_after.packets_sent,
stats_after.packets_sent - stats_before.packets_sent,
))
printl(templ.format(
"pkts-recv",
stats_after.packets_recv,
stats_after.packets_recv - stats_before.packets_recv,
))
printl("")
# fmt: on
win.refresh()
lineno = 0
def setup():
curses.start_color()
curses.use_default_colors()
for i in range(curses.COLORS):
curses.init_pair(i + 1, i, -1)
curses.endwin()
win.nodelay(1)
def tear_down():
win.keypad(0)
curses.nocbreak()
curses.echo()
curses.endwin()
def main():
setup()
try:
interval = 0
while True:
if win.getch() == ord('q'):
break
args = poll(interval)
refresh_window(*args)
interval = 0.5
except (KeyboardInterrupt, SystemExit):
pass
finally:
tear_down()
if __name__ == '__main__':
main()
|