16

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?

2

4 Answers 4

8

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.

4

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.
3
  • 2
    Sadly, 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 :(
    – tshepang
    Commented Feb 4, 2011 at 19:25
  • 1
    You'll almost certainly need root privileges for this.
    – Falmarri
    Commented Feb 5, 2011 at 11:34
  • 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
2

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
6
  • 16
    I 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 second nc 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.
    – Jander
    Commented Feb 5, 2011 at 8:33
  • I had an error function strftime never defined; it was fixed by installing gawk.
    – tshepang
    Commented 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.
    – scai
    Commented Aug 17, 2012 at 10:58
  • 3
    Confirming 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.
    – Navin
    Commented 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
0

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .