# 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