[rrd-users] Need help with shell script`s

Simon Hobson linux at thehobsons.co.uk
Tue Jan 6 09:12:54 CET 2009


X Y wrote:

># # # my Graph sh # # #
>#!/bin/sh
>
>WWWPREFIX=/usr/local/www/data/rrdtool
>RRDPREFIX=/usr/local/rrdtool/db
>
>/usr/local/bin/rrdtool graph $WWWPREFIX/ipfw_test.png \
>     --width 500 --height 500 --imgformat PNG \
>     --start -43200 \
>     --title "Q!"  --rigid  --color BACK#FAFAFA  \
>     --vertical-label Kbit/sec \
>     DEF:html_shtml=$RRDPREFIX/ipfw_test.rrd:html_shtml:AVERAGE   \
>     DEF:interface_in=$RRDPREFIX/ipfw_test.rrd:interface_in:AVERAGE   \
>     DEF:outerface_in=$RRDPREFIX/ipfw_test.rrd:outerface_in:AVERAGE   \
>     DEF:interface_out=$RRDPREFIX/ipfw_test.rrd:interface_out:AVERAGE   \
>     DEF:outerface_out=$RRDPREFIX/ipfw_test.rrd:outerface_out:AVERAGE   \
>     CDEF:web=html_shtml,128,/                     \

      ^^^^^^^^^^



>     CDEF:localin=interface_in,128,/                     \
>     CDEF:inetin=outerface_in,128,/                     \
>     CDEF:localout=interface_out,128,/                     \
>     CDEF:inetout=outerface_out,128,/                     \
>     VDEF:html_sum=html_shtml,TOTAL                     \
>     VDEF:int_in_sum=interface_in,TOTAL                   \
>     VDEF:out_in_sum=outerface_in,TOTAL                      \
>     VDEF:int_out_sum=interface_out,TOTAL                      \
>     VDEF:out_out_sum=outerface_out,TOTAL                        \
>     VDEF:maxhtm=web,MAXIMUM                   \
>     VDEF:maxintin=localin,MAXIMUM                 \
>     VDEF:maxoutin=inetin,MAXIMUM                        \
>     VDEF:maxinout=localout,MAXIMUM                    \
>     VDEF:maxoutout=inetout,MAXIMUM                    \
>     VDEF:avghtm=html_shtml,AVERAGE                   \
>     VDEF:avginin=localin,AVERAGE                 \
>     VDEF:avgoutin=inetin,AVERAGE                        \
>     VDEF:avginout=localout,AVERAGE                    \
>     VDEF:avgoutout=inetout,AVERAGE                    \
>
>     LINE1:web#CCCCCC:"HTML-SHTML"        \
>     GPRINT:maxhtm:"Max=%lf%s"      \
>     GPRINT:avghtm:"Avg=%lf%s"      \
>     GPRINT:html_sum:"Sum=%lf %sbytes\l"    \
>
>     LINE1:localin#FF6600:"Local IN"          \
>     GPRINT:maxintin:"Max=%lf%s"       \
>     GPRINT:avginin:"Avg=%lf%s"       \
>     GPRINT:sumint_in_sum:"Sum=%lf %sbytes\l"     \
>
>     LINE1:inetin#0000FF:"Inet IN"        \
>     GPRINT:maxoutin:"Max=%lf%s"      \
>     GPRINT:avgoutin:"Avg=%lf%s"      \
>     GPRINT:out_in_sum:"Sum=%lf %sbytes\l"    \
>
>     LINE1:localout#FF1100:"Local OUT"        \
>     GPRINT:maxinout:"Max=%lf%s"      \
>     GPRINT:avginout:"Avg=%lf%s"      \
>     GPRINT:int_out_sum:"Sum=%lf %sbytes\l"    \
>
>    LINE1:inetout#FF0011:"Inet OUT"        \
>     GPRINT:maxoutout:"Max=%lf%s"      \
>     GPRINT:avgoutout:"Avg=%lf%s"      \
>     GPRINT:out_out_sum:"Sum=%lf %sbytes\l"    \
>
>Cant figure out why i get
>
>LINE1:web#CCCCCC:HTML-SHTML: not found

"web" is a CDEF, ie it is an array of Y values corresponding to X 
axis values. You need a VDEF which condenses these down to one value 
using a specified consolidation function - like you've done 
with"maxhtm".


One other point, I would suggest you explicitly set the end time and 
start time, using a step value that corresponds with one of your 
stored data sets. You are less likely to get the wrong data used (eg 
a low res dataset used if it fills the specified time span better 
than a high res one you expected to be used.


In my graphs I use :
     --end ${Etime} --start end-${Period}

And at the start of my graph generation script, I have :

>   Etime=`/bin/date +%s`
>   Etime=$(( ${Etime} / ${Step} * ${Step} ))
>   PrintedTime=$(/bin/date -d "19700101 00:00 +0000 ${Etime}sec" 
>+"%H\:%M\:%S %a %d %b %Y")
>   Exptime=$(( ${Etime} + ${Step} ))
>   echo "Content-Type: image/png
>Last-Modified: `date --rfc-2822 -d "19700101 00:00 +0000 ${Etime}sec"`
>Expires: `date --rfc-2822 -d "19700101 00:00 +0000 ${Exptime}sec"`
>"

Etime is used for generating the graph.
PrintedTime is used to add a "data to <date/time>" legend on the graph.
And the last 5 lines output the HTML headers before the image is sent 
- in particular, the Exptime tells the browser to cache the image 
until it's due for a refresh - ie the next ${Step} period. Graphs are 
generated with the --lazy option so they are not redrawn if the data 
hasn't changed since the last time it was done.

Step and Period are set before calling the routine, I have code like :

>Options="${QUERY_STRING}"
>while [ ! -z "${Options}" ]
>do
>   Option=`echo ${Options} | cut -f1 -d'&'`
>   Options=`echo ${Options} | cut -s -f2- -d'&'`
>
>   case ${Option} in
>     scale=day )         TimeScale=day
>                         TimeScaleHead="Day"
>                         Step=300
>                         Period=90000 ;; # 25h

Which is checking the parameters passed in the image url (eg 
image.cgi?scale=day) and setting the values needed. Step and period 
are done so that period/step is exactly the number of pixels in the 
graph which can significantly reduce processing time on complex 
graphs (I have a graph with 510 stacked elements on it, plus another 
1022 values in the legend, graph of activity by IP address for a full 
class C network !) and gives 'crisper' looking graphs.


I have mine set up now so that I have a script that generates dynamic 
pages with image URLs in them, along the lines of :

image.cgi?scale=day
image.cgi?scale=week
image.cgi?scale=month
image.cgi?scale=year

And then another cgi that generates the images as required.

The image cgi basically does this :

>   process the parameters passed in teh URL and get the graph parameters
>   output the HTML headers (as above)
>   echo "<some rrdgraph code>" | \
>     /usr/bin/rrdcgi --filter - 2>&1 > /dev/null
>   cat imagefile.png


-- 
Simon Hobson

Visit http://www.magpiesnestpublishing.co.uk/ for books by acclaimed
author Gladys Hobson. Novels - poetry - short stories - ideal as
Christmas stocking fillers. Some available as e-books.



More information about the rrd-users mailing list