I've found a nice monitor which allows me to log a variety of runtime data of a single process. I'm looking for an equivalent that does the same for bandwidth usage. Ideally, the command should look like bwmon --pid 1 --log init.log
. Is there such? Can it run without admin privileges?
-
1related: superuser.com/questions/189128/…– akiraCommented Feb 4, 2011 at 20:08
-
serverfault.com/questions/36586/…– Ciro Santilli OurBigBook.comCommented May 26, 2016 at 20:04
4 Answers
If you're satisfied with general I/O bandwidth used (or if your program does almost entirely network I/O), then you could watch the /proc/<pid>/io
file. You want the rchar
and wchar
fields. You might want to subtract read_bytes
and write_bytes
, since they represent reads and writes to the storage layer. See section 3.3 of http://www.kernel.org/doc/Documentation/filesystems/proc.txt.
If you need more resolution.... you could maybe script this using lsof
and strace
, though it would be painful to get all the corner cases right. The basic idea is to parse the output of strace -p <pid>
, grabbing the first parameter (= the file descriptor) and the return value (= number of bytes) from read()
, write()
, send()
, and recv()
calls (NOTE there are several more syscalls to listen for; I haven't tracked them all down). Discard negative values; they indicate errors. Use lsof -p <pid>
to figure out which file descriptors are TCP/UDP sockets, and add up the counts per fd. This strategy doesn't require root as long as you own the process you're inspecting, but it would be really hairy to write, let alone write well.
try nethogs:
NetHogs is a small 'net top' tool. Instead of breaking the traffic down per protocol or per subnet, like most tools do, it groups bandwidth by process. NetHogs does not rely on a special kernel module to be loaded. If there's suddenly a lot of network traffic, you can fire up NetHogs and immediately see which PID is causing this. This makes it easy to indentify programs that have gone wild and are suddenly taking up your bandwidth.
-
2Sadly, it can't monitor a single process, and it doesn't log. The second requirement (logging) is much more important that the first one though. Oh, and it doesn't run without admin privileges :(– tshepangCommented Feb 4, 2011 at 19:25
-
1
-
You could try using nethogs with the -t flag (tracemode). The resulting output could then be parsed to extract the traffic of the single process you're interested in. Commented Apr 3, 2014 at 9:32
something to get you started (just in case you want to write it yourself):
#!/bin/bash
#
# usage: bwmon PID
IN=0; OUT=0; TIME=0
get_traffic() {
t=`awk '/eth0:/ { printf("%s,%d,%d\n",strftime("%s"),$2,$10); }' < /proc/$1/net/dev`
IN=${t#*,}; IN=${IN%,*}
OUT=${t##*,};
TIME=${t%%,*};
}
get_traffic $1
while true
do
_IN=$IN; _OUT=$OUT; _TIME=$TIME
get_traffic $1
echo "$TIME,$(( $TIME - $_TIME )),$IN,$(( $IN - $_IN )),$OUT,$(( $OUT - $_OUT))"
sleep 1
done
comments:
- checks only eth0
- checks every 1 second
- works only under linux, but other unixes work similar (procfs or whatever)
- output could be stored into a sqlite.db with
stat --printf="%N\n" /proc/PID/exe | cut -d ' ' -f 3
-
16I don't think this is actually a per-process counter; I think it's just the total interface count from the process' point of view. I ran a client/server
nc
pair over localhost, sending one byte per second, and watched/proc/<listening-nc-pid>/net/dev
. Then I ran a secondnc
pair, sending at maximum rate. The file I was watching very obviously counted the second pair's data along with the first pair's. Running on Linux 2.6.32.– JanderCommented Feb 5, 2011 at 8:33 -
I had an error
function strftime never defined
; it was fixed by installing gawk.– tshepangCommented Mar 3, 2011 at 11:12 -
4@Jander That's correct,
/proc/<pid>/net/dev
and/proc/net/dev
have the same content here. Hence the scipt only reports the traffic for eth0, not for the given process.– scaiCommented Aug 17, 2012 at 10:58 -
3Confirming that this is not an answer. It measures the interface counter for
eth0
, as seen by the process. It does not count data sent by the process through that interface.– NavinCommented Jun 30, 2016 at 12:44 -
@Navin an answer is anything that tries to answer the question. A wrong answer is still an answer. If this one is wrong, then you may downvote it, but it's still an answer.– terdon ♦Commented Jun 30, 2016 at 14:00
based on the answer by Jander
#!/usr/bin/env bash
# monitor network traffic of a process
# this is hard without root access
# and without extra capabilities: cap_net_admin, cap_new_raw
# which are also required by nethogs
# so we use total io as a proxy for network io
set -eu
process_name="$1"
pid=$(pgrep "$process_name")
while true; do
eval $(cat /proc/$pid/io | sed 's/: /=/')
time=$(date --utc +%s)
out=$rchar; in=$wchar
out=$(echo $out | numfmt --to=iec-i --format=%.6f)B
in=$(echo $in | numfmt --to=iec-i --format=%.6f)B
echo "$time,$out,$in"
sleep 1
done
alternatives to out=$rchar; in=$wchar
compared to the actual payload traffic
# payload traffic: up 1.450163TiB + down 688.649911MiB
# 1718872971,853.397302MiB,-87.720849GiB
#out=$((wchar - write_bytes)); in=$((rchar - read_bytes))
# 1718873132,108.031573GiB,1.829787TiB
#out=$wchar; in=$rchar
# 1718873187,107.232708GiB,1.915926TiB
#out=$write_bytes; in=$read_bytes
# 1718873228,1.916148TiB,107.256169GiB
#out=$read_bytes; in=$write_bytes
# 1718873309,1.830446TiB,108.136342GiB
out=$rchar; in=$wchar