commit 7673f1c7181785316d8d794d7818f47ac547debc Author: sebastian Date: Mon May 12 19:02:11 2025 +0200 initial diff --git a/README.md b/README.md new file mode 100644 index 0000000..5894c26 --- /dev/null +++ b/README.md @@ -0,0 +1,113 @@ +# perfi.sh + +A script that uses gnuplot to plot `iperf3` output in realtime. + +## iperf3 + + +``` +iperf3 -i $PINTERVAL -R -t $PTIME -f k -c $PERFHOST + +``` + +`-i` is the interval in Seconds. Can be a float like `0.1` + +`-f` is the ouptut and allows + +- `-k` Kbit/s +- `-m` Mbit/s +- `-K` Kbyte/s +- `-M` MByte/s + + +There exists a [list of public iperf servers](https://iperf.fr/iperf-servers.php). + + + +## stdbuf + +´iperf3` seems to buffer its `stdout`. A tool named `stdbuf` helps achieving realtime output, so the data can be piped into the next tool. + +``` +stdbuf -o0 iperf3 -i $PINTERVAL -R -t $PTIME -f k -c $PERFHOST + +``` + +`-o` refers to the `STDOUT` (there is also `-i` for `STDIN` and `-e` for `STDERR`). `0` will turn buffering off. `L` would enable Line Buffering. + + + +## awk + +`awk` is used to only get the data rate (7th column) + +iperf3 example output: + +``` +iperf3 -c 192.168.2.70 -f k -t 2 +Connecting to host 192.168.2.70, port 5201 +[ 5] local 192.168.2.199 port 59798 connected to 192.168.2.70 port 5201 +[ ID] Interval Transfer Bitrate Retr Cwnd +[ 5] 0.00-1.00 sec 28.3 MBytes 237649 Kbits/sec 0 1.21 MBytes +[ 5] 1.00-2.00 sec 31.2 MBytes 261938 Kbits/sec 0 2.16 MBytes +- - - - - - - - - - - - - - - - - - - - - - - - - +[ ID] Interval Transfer Bitrate Retr +[ 5] 0.00-2.00 sec 59.6 MBytes 249797 Kbits/sec 0 sender +[ 5] 0.00-2.02 sec 57.2 MBytes 237330 Kbits/sec receiver + +iperf Done. + +``` + + +``` +awk '/sec/&&!/receiver/&&!/sender/ {print $7}' +``` + +The `/sec/` will filter all lines that show a data rate. To filter out the summary at the end, we add `&&!/receiver/&&!/sender/`. `&&` is logical `AND` and `!` negates the token. + + +So this would result in + +``` + iperf3 -c 192.168.2.70 -f k -t 2 | awk '/sec/&&!/receiver/&&!/sender/ {print $7}' +281725 +262140 + +``` + +## feedgnuplot + +`feedgnuplot` is a wrapper that makes it simpler to feed data to `gnuplot` in real time. + +``` +feedgnuplot --lines --stream --ylabel 'KBytes/sec' --xlabel 'seconds' +``` + +`--lines` tells (feed)gnuplot to connect datapoints by lines (which is easier to read then only points/dots + +`--stream` tells (feed)gnuplot to update its data as it comes in. Per default it will do this once per second. + +`--ylabel / --xlabel` will write a caption. It is not mandatory, but if you want to share the plot later it looks nicer. + + +## Full commandline + +(See [perfi.sh](perfi.sh) + +```bash +stdbuf -o0 iperf3 -i $PINTERVAL -R -t $PTIME -f k -c $PERFHOST | stdbuf -o0 awk '/sec/&&!/receiver/&&!/sender/ {print $7}' | stdbuf -o0 feedgnuplot --lines --stream $PINTERVAL --ylabel 'Kbit/s' --xlabel "$PINTERVAL seconds" + +``` + + +## Result + +![gnuplot.png](A screenshot of the gnuplot of an iperf3 test) + +## Room for improvement + +- Let user have a commandline switch for the unit (kbit/s vs. mbit/s etc.) +- Add checks for dependencies and commandline switches + + diff --git a/gnuplot.png b/gnuplot.png new file mode 100644 index 0000000..27f3db8 Binary files /dev/null and b/gnuplot.png differ diff --git a/perfi.sh b/perfi.sh new file mode 100755 index 0000000..a044831 --- /dev/null +++ b/perfi.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +#function perfi() +#{ + +## +## usage: perfi HOST DURATION INTERVAL +## +## eg. perfi iperf3.servername.com 20 0.1 +## + +## hardcode stuff here: +PERFHOST=${1:-"iperf.it-north.net"} # default host +PTIME=${2:-"20"} # 20 seconds default +PINTERVAL=${3:-"0.5"} # 0.5 seconds interval + +echo "Using $PERFHOST with test duration $PTIME and interval $PINTERVAL" + +stdbuf -o0 iperf3 -i $PINTERVAL -R -t $PTIME -f k -c $PERFHOST | stdbuf -o0 awk '/sec/&&!/receiver/&&!/sender/ {print $7}' | stdbuf -o0 feedgnuplot --lines --stream $PINTERVAL --ylabel 'Kbit/s' --xlabel "$PINTERVAL seconds" + +#}