Syed Jahanzaib – Personal Blog to Share Knowledge !

June 5, 2015

Gnuplot = The DADA ABBU (Grandfather) of Graphing done via CLI

Filed under: Linux Related, Radius Manager — Tags: , , — Syed Jahanzaib / Pinochio~:) @ 12:28 PM

usergraph


Whatis Gnuplot:

As defined the Wikipedia. …

Gnuplot is a command-line program that can generate two- and three-dimensional plots of functions, data, and data fits. It is frequently used for publication-quality graphics as well as education. The program runs on all major computers and operating systems (GNU/Linux, Unix, Microsoft Windows, Mac OS X, and others).

I remember when I got in love with the MRTG and I spent many nights in mastering this giant. MRTG is overall a very good graphing too graph about any device but it usually works with snmp (and in some cases with shell scripts too). But what if I have data in a file with simple human readable format and I want to plot different columns in it? MRTG will not help in such cases, Gnuplot will come to rescue 🙂

I used Gnuplot to graph user download for the current month, In this example user data is taken from MYSQL radius DB and then graphed/plotted with Gnuplot.

As always being a duffer , dumber and incompetent, It took me 2-3 Days of continuous efforts to make it as a single script for bundled package.


 

Requirements for this script:

[You can modify it as per your requirements very easily, I just made it as per my own requirements : D ]

  1. Linux / UBUNTU / CENTOS
  2. MySQL with Radius DB
  3. Gnuplot Application

What this script will do ?

This script will take accounting data for the specified users for the current month by auto detecting the month/year.The file will look something like following

2015-03-01   1688961371   937706875
2015-03-02   2989190965   2974464964
2015-03-04   534479492   31747041
2015-03-05   809968366   170112567
2015-03-06   2189812711   1555484772

First column is DATE
Second column is user DOWNLOADED data in bytes
Third column is user UPLOADED data in bytes
Then it will save this accounting data in /tmp/USERNAME.TXT  (Username is what supplied by the user)
Then gnuplot will start its magic and will graph the data based on the supplied data.


 

To install Gnuplot on Ubuntu , issue following command

apt-get install -y gnuplot

Now create bash script as follows

mkdir /temp
touch /temp/usergraph.sh
nano /temp/usergraph.sh

and paste following. Make sure to change things according to your network

#!/bin/sh
# Freeradius / Mysql User Graph Generation 'ON THE FLY' using GNUPLOT
# you can use it like ./usergraph.sh 2016 01 (for Jan, 2016)
# By Syed Jahanzaib / aacable [at] hotmail.com
# https://aacable.wordpress.com
# Created: May, 2015
# Last Modified on  29th-JAN-2016

# Defining BASH Variables FOR MYSQL CREDENTIALS and host
SQLUSER="root"
SQLPASS="SQLPASSWORD"
SQLHOST="localhost"

# Date functions to find current date, month year, can be used in auto detect month type script
# you can modify it to auto detect as showed in other examples / zaib
NOW=$(date)
MONTH=$(date +"-%m")
CMONTH=`echo $MONTH  | sed -e 's/-//g'`
YEAR=$(date +"-%Y")
CYEAR=`echo $YEAR  | sed -e 's/-//g'`
FMONTH=$(date +"%B")
FULLMONTH=`echo $FMONTH # | sed -e 's/-//g'`

# Name of file in which mysql will dump the user accounting data for the current month
TMP="/tmp/$1.txt"
echo "$1 $2 $3"
# Fetch Accounting Data from MYSQL Freeradius radius DB, by using current Year/Month using username provide with the script , and output to file
mysql -u$SQLUSER -p$SQLPASS -h$SQLHOST -e "use radius; SELECT SQL_CALC_FOUND_ROWS date, SUM(allbytesdl) - COALESCE(SUM(specbytesdl), 0), SUM(allbytesul) - COALESCE(SUM(specbytesul), 0), SUM(alltime) - COALESCE(SUM(spectime), 0)
FROM (  SELECT LEFT(radacct.acctstarttime, 10) AS date,  acctoutputoctets AS allbytesdl, SUM(dlbytes) AS specbytesdl,  acctinputoctets AS allbytesul, SUM(ulbytes) AS specbytesul,
radacct.acctsessiontime AS alltime, SUM(rm_radacct.acctsessiontime) AS spectime  FROM radacct  LEFT JOIN rm_radacct ON rm_radacct.radacctid = radacct.radacctid
WHERE LEFT(radacct.acctstarttime, 7) LIKE '$2-$3%' AND radacct.username LIKE '$1' AND  FramedIPAddress LIKE '%' AND CallingStationId LIKE '%'   GROUP BY radacct.radacctid
) AS tmp GROUP BY date LIMIT 0, 50;" |awk '{print $1,$2,$3}' > $TMP
sed '1d' -i $TMP


# Run GNUPLOT SCRIPT on the FLY / by zaib
gnuplot << EOF
reset
set terminal jpeg size 1600,600
# Set output according to your requirement, like you can create file with the username for easier identification
set output "/var/www/$1.jpg"
set xdata time
set timefmt "%Y-%m-%d"
set format x "%d/%m"
set xtics 86400
set xtics rotate by -45
set xlabel "Date (day/month)"
set ylabel "Data Downloaded in GB"
set title "User Account - $1\n Download/Upload Report for Month $3 / Year $2\nTotal Data Used = $TOTAL GB\nThis report was created on $NOW\nPowered by Syed Jahanzaib / aacable@hotmail.com"
set key outside
set grid
set style data histogram
set style histogram cluster gap 1
set style fill solid
set boxwidth 0.9

plot "$TMP" using 1:(\$2/2**30):(sprintf("%.2f", \$2/2**30)) w boxes title "Download" lw 10, \
"$TMP" using 1:(\$3/2**30):(sprintf("%.2f", \$3/2**30)) w boxes lw 6 title "Upload", \
"$TMP" using 1:(\$2/2**30):(sprintf("%.2f", \$2/2**30)) w labels notitle center offset 0,2 tc rgb 'red', \
"$TMP" using 1:(\$3/2**30):(sprintf("%.2f", \$3/2**30)) w labels notitle center offset 0,1 tc rgb 'green'

EOF
# GNUPLOT Script ends here
# Thank you : ) / zaib

Running the SCRIPT

Now execute the script by

/temp/usergraph.sh USERNAME 2016 01

(Like usergraph.sh zaib 2016 01) this will create graph on the fly for use ‘zaib’ for January, 2016 month

If everything goes well and you dont’ see any errors after executing this script, then you can view the output by

http://yourip/username.jpg

Note: the jpg file will be placed in /var/www folder under the username format, for ubuntu.


usergraphThat’s it …

I showed the very basic usage of Gnuplot. Very Very Basic Level of it. This is only what I have learned so far in few days. But Gnuplot can do things beyond your imagination. Look at this gallery.

http://commons.wikimedia.org/wiki/Category:Gnuplot_diagrams

Gnuplot is a very good and customizable tool which is used all over the world to create simple OR very complex graphs in a go. Above all good part is that it can take data from local files and all can be done via scripting or terminal.

You should give it a try 🙂


Another version which takes year from your input and then create graph for the whole year usage for the network (overall)

This is another version which input year from you and then create graph for the whole year for overall network usage,


root@radius:/temp# cat year.sh
#!/bin/sh
# MYSQL USER NAME AND PASSWORD Variables
SQLUSER="root"
SQLPASS="SQLPASS"

# Date functions to find current date, month year
NOW=$(date)
MONTH=$(date +"-%m")
CMONTH=`echo $MONTH  | sed -e 's/-//g'`
YEAR=$(date +"-%Y")
CYEAR=`echo $YEAR  | sed -e 's/-//g'`
FMONTH=$(date +"%B")
FULLMONTH=`echo $FMONTH # | sed -e 's/-//g'`

mysql -u$SQLUSER -p$SQLPASS -e "use radius; SELECT SQL_CALC_FOUND_ROWS
date,
SUM(allbytesdl) - COALESCE(SUM(specbytesdl), 0),
SUM(allbytesul) - COALESCE(SUM(specbytesul), 0),
SUM(alltime) - COALESCE(SUM(spectime), 0)
FROM (
SELECT LEFT(radacct.acctstarttime, 7) AS date,
acctoutputoctets AS allbytesdl, SUM(dlbytes) AS specbytesdl,
acctinputoctets AS allbytesul, SUM(ulbytes) AS specbytesul,
radacct.acctsessiontime AS alltime, SUM(rm_radacct.acctsessiontime) AS spectime
FROM radacct
LEFT JOIN rm_radacct ON rm_radacct.radacctid = radacct.radacctid
WHERE LEFT(radacct.acctstarttime, 4) LIKE '$1%' AND radacct.username LIKE '%' AND
FramedIPAddress LIKE '%' AND CallingStationId LIKE '%'
GROUP BY radacct.radacctid
) AS tmp
GROUP BY date
LIMIT 0, 50;"  |awk '{print $1,$2,$3}' >  /tmp/raw

sed '1d' -i /tmp/raw
awk '{ print $1, $2 + $3; }' /tmp/raw > /tmp/final
echo DONE
# Name of file in which mysql will dump the user accounting data for the current month
TMP="/tmp/final"

# Run GNUPLOT SCRIPT on the FLY / by zaib
gnuplot << EOF
reset
set terminal jpeg size 1600,600
# Set output according to your requirement, like you can create file with the username for easier identification
set output "/var/www/radius.jpg"
set xdata time
set timefmt "%Y-%m"
set format x "%Y/%m"
#set ytics 1
set xtics rotate by -45
set xlabel "Date (month/year)"
set ylabel "Data Downloaded in GB"
set title "Download/Upload Report for $1\nThis report was created on $NOW\nPowered by Syed Jahanzaib / aacable@hotmail.com"
set key outside
set grid
set style data histogram
set style histogram cluster gap 1
set style fill solid
set boxwidth 0.9

plot "$TMP" using 1:(\$2/2**30):(sprintf("%.0f", \$2/2**30)) w boxes title "Download" lw 10, \
"$TMP" using 1:(\$2/2**30):(sprintf("%.0f", \$2/2**30)) w labels title "Data in GB" center offset 0,1 tc rgb 'red'

EOF
# GNUPLOT Script ends here
# Thank you : )

Now execute script as follows

./year.sh 2015

you ahve to supply year o it will generate overall graph which will look odd as we are graphing details for 1 year only,

Sample of above script will generate graph

as follows …

1-data-downloaded-in-year


 

Regard’s
Syed Jahanzaib

%d bloggers like this: