This is an old revision of the document!
Docker rates.sh
This prints out a table of instantaneous network bandwidth use.
#!/usr/bin/env bash
# Instantaneous per-container network rates (B/s). No extra packages.
INTERVAL=1
TMPDIR=${TMPDIR:-/tmp}
PREV="$TMPDIR/net.prev.$$.txt"
NOW="$TMPDIR/net.now.$$.txt"
OUT="$TMPDIR/net.out.$$.txt"
cleanup(){ rm -f "$PREV" "$NOW" "$OUT"; exit 0; }
trap cleanup INT TERM
collect() {
target="$1"
: > "$target"
docker ps -q | while read -r id; do
[ -z "$id" ] && continue
name=$(docker inspect --format '{{.Name}}' "$id" 2>/dev/null | sed 's#/##')
pid=$(docker inspect --format '{{.State.Pid}}' "$id" 2>/dev/null)
if [ -r "/proc/$pid/net/dev" ]; then
read rx tx < <(awk 'NR>2{rx+=$2;tx+=$10}END{print rx,tx}' /proc/"$pid"/net/dev 2>/dev/null || echo "0 0")
else
rx=0; tx=0
fi
# id<TAB>name<TAB>pid<TAB>rx<TAB>tx
printf '%s\t%s\t%s\t%s\t%s\n' "$id" "$name" "$pid" "$rx" "$tx" >> "$target"
done
}
# seed previous snapshot
collect "$PREV"
sleep "$INTERVAL"
while true; do
ts=$(date +"%F %T")
collect "$NOW"
# load previous counters into associative arrays
declare -A PRX PTX PNAME
while IFS=$'\t' read -r id name pid rx tx; do
PRX["$id"]=$rx
PTX["$id"]=$tx
PNAME["$id"]=$name
done < "$PREV"
: > "$OUT"
while IFS=$'\t' read -r id name pid arx atx; do
brx=${PRX[$id]:-0}
btx=${PTX[$id]:-0}
rx_rate=$((arx - brx))
tx_rate=$((atx - btx))
[ "$rx_rate" -lt 0 ] && rx_rate=0
[ "$tx_rate" -lt 0 ] && tx_rate=0
total=$((rx_rate + tx_rate))
# total<TAB>name<TAB>rx_rate<TAB>tx_rate<TAB>total
printf '%d\t%s\t%d\t%d\t%d\n' "$total" "$name" "$rx_rate" "$tx_rate" "$total" >> "$OUT"
done < "$NOW"
echo "==== $ts (rates over ${INTERVAL}s) ===="
if [ -s "$OUT" ]; then
sort -t $'\t' -nr -k1,1 "$OUT" | awk -F'\t' '{printf "%-28s RX:%8d B/s TX:%8d B/s TOT:%8d B/s\n", $2, $3, $4, $5}'
else
echo "No containers found."
fi
mv "$NOW" "$PREV"
sleep "$INTERVAL"
done