Network Monitor widget for XFCE panel

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:

2 Likes