Vnstat webpage generation

I am currently out of my primary appartment and using metered mobile connection, so i needed a way to monitor my traffic. Vnstat seemed to be the best and lightest option.
https://wiki.archlinux.org/title/VnStat
I already integrated a short summary in my Cheatsheet, but i wanted something more fancy. Unfortunately there are no acceptable gui-s out there for this. There is a heavy electron app which is buggy and not updated, and there is a web server app. Well, as an ex web developer i liked the idea of something web based, but i did not like to run a web server just for this, so i made my own solution or the problem

Here is a little visual demo

And here is the script in case somebody finds it useful. Of course, you need to install vnstat first and enable and start the service. And yes, it can be made to run as a service in background, but i planned to open it only from time to time so i did not see the need to have it permanenty running in background.

#!/bin/bash
# Creator: Todor Uzunov a.k.a. Teo
# License: GNU - free like free speech and free beer for everybody!
while true; do
vnstati -d -L -ic --style 0 --scale 120 -o /tmp/day.png
#vnstati -5g -L -ic --style 0 --scale 120 -o /tmp/5g.png
vnstati -5 48 -L -ic --style 0 --scale 120 -o /tmp/5min.png
vnstati -h 16 -L -ic --style 0 --scale 120 -o /tmp/hour.png
#vnstati -hg -L -ic --style 0 --scale 120 -o /tmp/hg.png
vnstati -m -L -ic --style 0 --scale 120 -o /tmp/month.png
#vnstati -s -L -ic --style 0 --scale 120 -o /tmp/sum.png
vnstati -t -L -ic --style 0 --scale 120 -o /tmp/top.png
vnstati -y -L -ic --style 0 --scale 120 -o /tmp/year.png
vnstati -vs 1 -L -ic --style 0 --scale 120 -o /tmp/smry_min.png
vnstati -vs -L -ic --style 0 --scale 120 -o /tmp/smry_hr.png
cat << EOF > /tmp/vnstat.html
<!DOCTYPE html>
<html>
<head>
<title>Vnstat</title>
<meta name="keywords" content="vnstat">
<meta name="description" content="easy access to vnstati generated graphics">
<meta name="ROBOTS" content="NOINDEX, NOFOLLOW">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta http-equiv="content-type" content="application/xhtml+xml; charset=UTF-8">
<meta http-equiv="content-style-type" content="text/css">
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<meta http-equiv="refresh" content="120">
<style type="text/css">
.button {
  font: bold 15px Arial;
  text-decoration: none;
  background-color: #DDDDDD;
  color: #333333;
  padding: 2px 6px 2px 6px;
  border-top: 1px solid #CCCCCC;
  border-right: 1px solid #333333;
  border-bottom: 1px solid #333333;
  border-left: 1px solid #CCCCCC;
}
a:hover, a:active, a:focus { 

  background-color: #7A4141;
  color: #DDDDDD;
}
</style>
</head>
<body align="center" style="background-color: #4C4C4C; ">
<br id="summary_h" clear="all"><br clear="all"><a href="#summary_h" class="button">Summary (h)</a><a href="#summary_m" class="button">Summary (m)</a><a href="#top" class="button">Top</a><a href="#5min" class="button">5 min</a><a href="#hour" class="button">Hourly</a><a href="#day" class="button">Daily</a><a href="#month" class="button">Monthly</a><a href="#year" class="button">Yearly</a><br clear="all"><br clear="all">
<img src="/tmp/smry_hr.png" >
<br id="summary_m" clear="all"><br clear="all"><a href="#summary_h" class="button">Summary (h)</a><a href="#summary_m" class="button">Summary (m)</a><a href="#top" class="button">Top</a><a href="#5min" class="button">5 min</a><a href="#hour" class="button">Hourly</a><a href="#day" class="button">Daily</a><a href="#month" class="button">Monthly</a><a href="#year" class="button">Yearly</a><br clear="all"><br clear="all">
<img src="/tmp/smry_min.png" >
<br id="top" clear="all"><br clear="all"><a href="#summary_h" class="button">Summary (h)</a><a href="#summary_m" class="button">Summary (m)</a><a href="#top" class="button">Top</a><a href="#5min" class="button">5 min</a><a href="#hour" class="button">Hourly</a><a href="#day" class="button">Daily</a><a href="#month" class="button">Monthly</a><a href="#year" class="button">Yearly</a><br clear="all"><br clear="all">
<img src="/tmp/top.png" >
<br id="5min" clear="all"><br clear="all"><a href="#summary_h" class="button">Summary (h)</a><a href="#summary_m" class="button">Summary (m)</a><a href="#top" class="button">Top</a><a href="#5min" class="button">5 min</a><a href="#hour" class="button">Hourly</a><a href="#day" class="button">Daily</a><a href="#month" class="button">Monthly</a><a href="#year" class="button">Yearly</a><br clear="all"><br clear="all">
<img src="/tmp/5min.png" >
<br id="hour" clear="all"><br clear="all"><a href="#summary_h" class="button">Summary (h)</a><a href="#summary_m" class="button">Summary (m)</a><a href="#top" class="button">Top</a><a href="#5min" class="button">5 min</a><a href="#hour" class="button">Hourly</a><a href="#day" class="button">Daily</a><a href="#month" class="button">Monthly</a><a href="#year" class="button">Yearly</a><br clear="all"><br clear="all">
<img src="/tmp/hour.png" >
<br id="day" clear="all"><br clear="all"><a href="#summary_h" class="button">Summary (h)</a><a href="#summary_m" class="button">Summary (m)</a><a href="#top" class="button">Top</a><a href="#5min" class="button">5 min</a><a href="#hour" class="button">Hourly</a><a href="#day" class="button">Daily</a><a href="#month" class="button">Monthly</a><a href="#year" class="button">Yearly</a><br clear="all"><br clear="all">
<img src="/tmp/day.png" >
<br id="month" clear="all"><br clear="all"><a href="#summary_h" class="button">Summary (h)</a><a href="#summary_m" class="button">Summary (m)</a><a href="#top" class="button">Top</a><a href="#5min" class="button">5 min</a><a href="#hour" class="button">Hourly</a><a href="#day" class="button">Daily</a><a href="#month" class="button">Monthly</a><a href="#year" class="button">Yearly</a><br clear="all"><br clear="all">
<img src="/tmp/month.png" >
<br id="year" clear="all"><br clear="all"><a href="#summary_h" class="button">Summary (h)</a><a href="#summary_m" class="button">Summary (m)</a><a href="#top" class="button">Top</a><a href="#5min" class="button">5 min</a><a href="#hour" class="button">Hourly</a><a href="#day" class="button">Daily</a><a href="#month" class="button">Monthly</a><a href="#year" class="button">Yearly</a><br clear="all"><br clear="all">
<img src="/tmp/year.png" >
<br id="summary_h" clear="all"><br clear="all"><a href="#summary_h" class="button">Summary (h)</a><a href="#summary_m" class="button">Summary (m)</a><a href="#top" class="button">Top</a><a href="#5min" class="button">5 min</a><a href="#hour" class="button">Hourly</a><a href="#day" class="button">Daily</a><a href="#month" class="button">Monthly</a><a href="#year" class="button">Yearly</a><br clear="all"><br clear="all">
</body>
</html>
EOF
echo "You can now load file:///tmp/vnstat.html in you browser."
echo "The web page will autorefresh, the script will auto-regenerate the images while running."
echo "Press CTRL+C to exit"
echo ""
sleep 260
clear
done

p.s. by default vnstat writes to database every 5 minutes. If you adjust this thime in its config or service, do not forget to adjust the refresh times in the html and the sleep between pictures refresh in the script.

3 Likes