Skip to content

Instantly share code, notes, and snippets.

@chrisshroba
Created October 20, 2020 18:53
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chrisshroba/e31fd89b6a560733d3f915e8ee4deed8 to your computer and use it in GitHub Desktop.
Save chrisshroba/e31fd89b6a560733d3f915e8ee4deed8 to your computer and use it in GitHub Desktop.
Network Monitoring By Process
#!/usr/bin/env python3
import sys
import sqlite3
conn = sqlite3.connect('network_usage.db')
with conn:
conn.execute('CREATE TABLE IF NOT EXISTS usage (time string, proc text, process text, bytes_in integer, bytes_out integer);')
def record(time, proc, bytes_in, bytes_out):
process = '.'.join(proc.split('.')[:-1])
for i in range(5):
try:
with conn:
conn.execute('INSERT INTO usage (time, proc, process, bytes_in, bytes_out) VALUES(?,?,?,?,?);',
(time, proc, process, bytes_in, bytes_out))
return
except Exception as e:
print(e)
print("Trying again; that was attempt {}".format(i))
print("Exceeded 5 retries")
for line in sys.stdin:
line = line.strip()
if line.startswith('time,,'):
continue
time, proc, interface,state,bytes_in,bytes_out,rx_dupe,rx_ooo,re_tx,rtt_avg,rcvsize,tx_win,tc_class,tc_mgt,cc_algo,P,C,R,W,arch, *rest = line.split(',')
record(time, proc, bytes_in, bytes_out)

Run the following command to start collecting data about network usage (-P makes it work per process instead of per connection, -d makes it output deltas instead of absolute numbers, which is good because I want this script to start all processes at 0, -x makes it output raw numbers instead of human readable byte counts, and -L 0 makes it continuously run):

nettop -PdxL 0 | ./collect.py

Then, while that's running, you can run print_top_10_network_users.sh to see the current top processes in terms of network usage.

At some point in the future I'm planning to make this whole thing more professional, less hacky, and maybe offer it as an installable Mac App or something, but for now, this works!

{
echo ".timeout 1000"
echo "SELECT 'Total: ' || CAST(ROUND(sum(bytes_in)/1024./1024.,3) AS VARCHAR) || ' MB' FROM usage;"
echo "SELECT process || ': ' || CAST(ROUND(sum(bytes_in)/1024./1024.,3) AS VARCHAR) || ' MB'"
echo " FROM usage"
echo " GROUP BY process"
echo " ORDER BY sum(bytes_in) DESC"
echo " LIMIT 10"
} | sqlite3 ~/personal/network_usage/network_usage.db
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment