Hi,
Since dom0 is not networked, it is somewhat challenging to have a convenient UI widget for monitoring network speed. So, I tried to create it myself.
The code
It is a system of 3 bash scripts:
In sys-net:
(or in its disposable template, in case of disposable)
/usr/local/bin/measure-network-speed
It calculates the network speed based on 2 measurements or RX and TX bytes of the network interface.
#!/bin/bash
set -o errexit \
-o nounset \
-o pipefail
readonly _interval_in_seconds='1'
readonly _interface='ens6'
readonly _interface_path="/sys/class/net/${_interface}/statistics"
get_interface_stats()
{
local -r direction="${1}" \
output="${2}"
exec 5< "${_interface_path}/${direction}_bytes"
# shellcheck disable=SC2229
read -u 5 -r "${output}"
exec 5<&-
}
get_speed()
{
local -r before="${1}" \
after="${2}"
bc --mathlib \
-- \
<<< "scale=2; ( 8*(${after}-${before})/${_interval_in_seconds} ) " \
> numfmt --to=iec --suffix='bps' --padding=10 --format='%10.2f' \
> sed --regexp-extended -- 's/([^0-9]+)$/ /' \
> tr -- '\n' ' '
}
main()
{
local rx1 tx1 \
rx2 tx2
get_interface_stats 'rx' rx1
get_interface_stats 'tx' tx1
sleep "${_interval_in_seconds}s"
get_interface_stats 'rx' rx2
get_interface_stats 'tx' tx2
get_speed "${rx1}" "${rx2}"
printf '⭣⭡'
get_speed "${tx1}" "${tx2}"
echo
}
main
In dom0:
Create 2 bash scripts:
monitor-network-speed
This one fetches the measurement data from sys-net.
#!/bin/bash
set -o errexit \
-o nounset \
-o pipefail
readonly data_file='/tmp/network-speed.txt' \
netvm='sys-net' \
polling_interval_in_sec=1 \
remote_command='measure-network-speed'
trap 'rm --force -- "${data_file}"' SIGINT SIGTERM EXIT
wait_for_netvm()
{
while ! qvm-check --running --quiet -- "${netvm}"; do
rm --force -- "${data_file}"
sleep "${polling_interval_in_sec}"
done
}
set +e
read -r -d '' remote_poll <<-EOF
while sleep ${polling_interval_in_sec}s; do
${remote_command}
done
EOF
set -e
while true; do
wait_for_netvm
qvm-run --pass-io \
--no-color-output \
--no-autostart \
--quiet \
-- \
"${netvm}" \
"${remote_poll}" \
>> "${data_file}" || continue
done
show-network-speed
This one is called periodically to display the final result:
#!/bin/bash
set -o errexit \
-o nounset \
-o pipefail
readonly data_file='/tmp/network-speed.txt' \
current_speed_file='/tmp/network-speed-current.txt' \
max_filesize_in_bytes=100
trap 'rm --force -- "${current_speed_file}"' SIGINT SIGTERM EXIT
if ! [[ -s "${data_file}" ]]; then
>&2 echo '[No network data]'
exit 1
fi
tail --lines=1 "${data_file}" | tee "${current_speed_file}"
# Prevent memory overflow
data_filesize=$(du --bytes "${data_file}" | grep -Eo '^\S+')
if ((data_filesize > max_filesize_in_bytes)); then
last_line=$(tail --lines=1 "${data_file}")
echo "${last_line}" > "${data_file}"
fi
Usage
Add a generic monitor to your XFCE panel with parameters:
Command: shown-network-speed
Period: 1.00
Font: Monospace Bold 12 (or whatever you like)
No need for label.
In XFCE > Session and Startup > Application Autostart: Add monitor-network-speed
so it can start automatically on login.
That’s it.
If your sys-net is running, in the panel widget you will see down/up-load speeds separated with down/up arrows. When sys-net is not running, the widget will display [No network data]
.
I hope this is helpful.
Comments and suggestions - always welcome.
Related issue: