diff misc/dcc-stats-graph.in @ 0:c7f6b056b673

First import of vendor version
author Peter Gervai <grin@grin.hu>
date Tue, 10 Mar 2009 13:49:58 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/dcc-stats-graph.in	Tue Mar 10 13:49:58 2009 +0100
@@ -0,0 +1,429 @@
+#! /bin/sh -e
+
+# graph collected DCC statistics in .png files.
+#   [-x]	    debugging
+#   [-q]	    quiet
+#   [-B]	    make big graphs
+#   [-G db]	    make graph of database size
+#   [-G db-min]	    make graph of database size without maximum size
+#   [-G traffic-noratio]	database size without spam ratios
+#   [-G traffic]		mail message rates and spam ratios
+#   [-G ratio]			spam ratios
+#   [-h dcc_homedir]
+#   [-T @RRDTOOL@]  see http://people.ee.ethz.ch/~oetiker/webtools/rrdtool/
+#			or the FreeBSD package.
+#   [-O rrdopts]    additional rrdtool options for all graphs
+#   [-t title]	    for graphs; '%1' is replaced with the type of graph
+#   [-s span]	    time covered by graphs.
+#			The default is "1day,1week,1month,1year"
+#   [-S stop-epoch] end of the graph
+#   [-y vresol]    day, minute, ... vertical access for messages
+#   gname	    basic file name for graphs, - for stdout
+#   rrd1,...	    RRD databases that will be combined to produce the graphs
+
+# The rrd files must be initialzed with dcc-stats-init, which is called
+#   automatically by dcc-stats-collect.  Data must be collected every
+#   10 minutes with dcc-stats-collect.  The rrd files should be in
+#   @prefix@/stats
+
+
+# Copyright (c) 2008 by Rhyolite Software, LLC
+#
+# This agreement is not applicable to any entity which sells anti-spam
+# solutions to others or provides an anti-spam solution as part of a
+# security solution sold to other entities, or to a private network
+# which employs the DCC or uses data provided by operation of the DCC
+# but does not provide corresponding data to other users.
+#
+# Permission to use, copy, modify, and distribute this software without
+# changes for any purpose with or without fee is hereby granted, provided
+# that the above copyright notice and this permission notice appear in all
+# copies and any distributed versions or copies are either unchanged
+# or not called anything similar to "DCC" or "Distributed Checksum
+# Clearinghouse".
+#
+# Parties not eligible to receive a license under this agreement can
+# obtain a commercial license to use DCC by contacting Rhyolite Software
+# at sales@rhyolite.com.
+#
+# A commercial license would be for Distributed Checksum and Reputation
+# Clearinghouse software.  That software includes additional features.  This
+# free license for Distributed ChecksumClearinghouse Software does not in any
+# way grant permision to use Distributed Checksum and Reputation Clearinghouse
+# software
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND RHYOLITE SOFTWARE, LLC DISCLAIMS ALL
+# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL RHYOLITE SOFTWARE, LLC
+# BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
+# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+# ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+# SOFTWARE.
+#	Rhyolite Software DCC 1.3.103-1.71 $Revision$
+#	@configure_input@
+
+DCC_HOMEDIR=@prefix@
+DEBUG=
+RRDTOOL=@RRDTOOL@
+# check the args once to get the home directory
+while getopts "xqBdRmh:G:T:O:t:s:S:y:" c; do
+    case $c in
+	x) set -x; DEBUG=-x=;;
+	h) DCC_HOMEDIR="$OPTARG";;
+	*) ;;
+    esac
+done
+. $DCC_HOMEDIR/dcc_conf
+
+BIG=
+GRAPH_DB=
+GRAPH_TRAFFIC=
+GRAPH_RATIO=
+GRAPH_SET=
+RRDOPTS=
+TITLE_SET=
+SPANS_SET=
+SPANS="1day,1week,1month,1year"
+STOP=
+YRESOL=86400
+YLABEL=day
+USAGE="`basename $0`: [-xqB] [-h homedir] [-T rrdtool] [-O rrdopts] [-G type]
+	[t title] [-s spans] [-S stop-epoch] [-y day|hour|min|sec] gname rrd"
+OPTIND=1
+while getopts "xqBdRmh:G:T:O:t:s:S:y:" c; do
+    case $c in
+	x) ;;				    # handled above
+	q) exec 1>/dev/null;;
+	h) ;;				    # handled above
+	B) BIG=yes;;
+	d) GRAPH_SET=yes; GRAPH_DB=yes;;			# obsolete
+	R) GRAPH_RATIO=;;					# obsolete
+	m) GRAPH_SET=yes; GRAPH_TRAFFIC=yes; GRAPH_RATIO=yes;;	# obsolete
+	G) GRAPH_SET=yes
+	    case "$OPTARG" in
+		db) GRAPH_DB=db;;
+		db-min) GRAPH_DB=db-min;;
+		traffic-noratio) GRAPH_TRAFFIC=yes;;
+		traffic) GRAPH_TRAFFIC=yes; GRAPH_RATIO=yes;;
+		ratio) GRAPH_RATIO=yes;;
+		*) echo "$USAGE" 1>&2; exit 1;;
+	    esac
+	    ;;
+	T) RRDTOOL="$OPTARG";;
+	O) RRDOPTS="$RRDOPTS $OPTARG";;
+	t) TITLE_SET=yes; TITLE_PAT="$OPTARG";;
+	s) SPANS_SET=yes; SPANS="$OPTARG";;
+	S) if expr "$OPTARG" : '[0-9]*$' >/dev/null		\
+		&& test "$OPTARG" -gt 1033870038		\
+		     -a "$OPTARG" -lt 2000000000; then
+		STOP=$OPTARG
+	    else
+		echo "$OPTARG is a bad number of seconds since the Epoch" 1>&2
+		exit 1;
+	    fi
+	    ;;
+	y)
+	case "$OPTARG" in
+	    day) YRESOL=86400; YLABEL=day;;
+	    hour) YRESOL=3600; YLABEL=hour;;
+	    min) YRESOL=60; YLABEL=min;;
+	    sec) YRESOL=1; YLABEL=sec;;
+	esac
+	;;
+	*) echo "$USAGE" 1>&2; exit 1;;
+    esac
+done
+shift `expr $OPTIND - 1 || true`
+if test "$#" -lt 1; then
+    echo "$USAGE" 1>&2
+    exit 1
+fi
+
+if test -z "$GRAPH_SET"; then
+    GRAPH_RATIO=yes			# bug compatible with old versions
+fi
+
+BASE_DIR="$DCC_HOMEDIR/stats"
+cd "$BASE_DIR"
+
+GNAME=$1
+if test "$#" -ge 2; then
+    # assume .rrd file is same as the graph name if the .rrd file is absent
+    shift
+fi
+FILE=$1
+# trim unneeded directory names
+FILE=`echo "$FILE" | sed -e "s@$BASE_DIR/*@@"`
+if test ! -s "$FILE"; then
+    echo "$FILE is not a good rrd file" 1>&2
+    exit 1
+fi
+
+if test "$TITLE_SET" != yes; then
+    if test "X$GNAME" != X-; then
+	TITLE_PAT="%1 at $GNAME"
+    else
+	TITLE_PAT="%1"
+    fi
+fi
+
+if test -n "`$RRDTOOL version | grep '^RRDtool 1\.0'`"; then
+    RRDVERSION=1.0
+else
+    RRDVERSION=
+fi
+
+if test -n "$BIG"; then
+    XYEAR_MONTHS=1
+    GSIZE="--width 600 --height 240"
+    P_YGRID=					# % or spam ratio vertical grid
+    M_YGRID=					# messages vertical grid
+    H_YGRID="--alt-autoscale-max"		# database vertical grid
+    M_YLABEL="message/$YLABEL"
+    AVGFMT="%.0lf/$YLABEL"
+    LABEL_REPORTS="total mail"
+    LABEL_BULK="likely spam"
+    LABEL_SPAM="trapped spam"
+else
+    XYEAR_MONTHS=2
+    GSIZE="--width 200 --height 40"
+    P_YGRID="--y-grid 25:2"
+    if test "$RRDVERSION" = 1.0; then
+	M_YGRID="--alt-y-mrtg"
+	H_YGRID="--alt-y-mrtg"
+    else
+	M_YGRID=
+	H_YGRID=
+    fi
+    M_YLABEL=msgs/$YLABEL
+    AVGFMT="%.1lf %S/$YLABEL"
+    LABEL_REPORTS="total"
+    LABEL_BULK="likely spam"
+    LABEL_SPAM="trapped"
+fi
+
+# use only a few colors to try to be portable
+C_GREEN='#00ff7f'
+C_YELLOW='#ffff00'
+C_PINK='#ffb6c1'
+C_INDIANRED='#ff6a6a'
+C_RED2='#ee0000'
+C_BLUE='#0000ff'
+C_SKY_BLUE='#87cefa'
+C_ORANGE='#ffa500'
+C_DARK_ORANGE='#ff8c00'
+C_BLACK='#000000'
+
+
+FTYPE=png
+ATTRIBS="$GSIZE --imgformat PNG --lower-limit 0"
+
+
+
+# find good ending dates
+date2ts () {
+    if test "$3" -eq 0; then
+	eval $1=new $2="' '"
+	return
+    fi
+
+    NEW_END=$3
+    if test -n "$4"; then
+	NEW_END=`expr $NEW_END - $NEW_END % $4 || true`
+    fi
+    eval $1=$NEW_END
+
+    if NEW_TS=`date -r $NEW_END '+%x %R %Z'  2>/dev/null`; then : ;
+    else
+	# deal with systems that do not have `date -r`
+	NEW_TS=`@PERL@ -e "use POSIX qw(strftime); \
+		print strftime '%x %R %Z', localtime($LAST);"`
+    fi
+    if test "$RRDVERSION" != 1.0; then
+	NEW_TS=`echo "$NEW_TS" | sed -e 's/:/\\\:/g'`
+    fi
+    eval $2="'COMMENT:$NEW_TS'"
+}
+
+STEP=`$RRDTOOL info $FILE | sed -n -e 's/^step = \([0-9][0-9]*\)/\1/p'`
+LAST=`$RRDTOOL last $FILE`
+if test -n "$STOP" -a "$LAST" -gt 0"$STOP"; then
+    LAST="$STOP"
+fi
+# avoid odd times when individual servers were polled
+LAST=`expr $LAST - $LAST % $STEP || true`
+
+date2ts END END_COMMENT $LAST
+date2ts END_DAY END_DAY_COMMENT $LAST 86400
+
+
+for DUR in `echo $SPANS | tr ',' ' '`; do
+    case $DUR in
+	1d*)
+	    DUR=1day
+	    SPAN=24h
+	    XGRID="--x-grid HOUR:1:HOUR:2:HOUR:2:0:%k"
+	    # as the "rdtool graph" man page suggests, don't be fooled
+	    # by daylight savings time
+	    ;;
+	1w*)
+	    DUR=1week
+	    SPAN=168h
+	    # 24*3600 = 86400
+	    if test -n "$BIG"; then
+		XGRID="--x-grid HOUR:6:DAY:1:DAY:1:86400:%a\ %m/%d"
+	    else
+		XGRID="--x-grid HOUR:6:DAY:1:DAY:1:86400:%a"
+	    fi
+	    # as the "rdtool graph" man page suggests, don't be fooled
+	    # by daylight savings time
+	    ;;
+	1m*)
+	    DUR=1month
+	    SPAN=$DUR
+	    XGRID="--x-grid WEEK:1:WEEK:1:WEEK:1:0:%b/%d"
+	    ;;
+	1y*)
+	    DUR=1year
+	    SPAN=$DUR
+	    # label every month on big graphs and every other on small
+	    # 28*24*60*60 = 2419200
+	    XGRID="--x-grid MONTH:1:YEAR:1:MONTH:$XYEAR_MONTHS:2419200:%b"
+	    ;;
+	2y*)
+	    DUR=2years
+	    SPAN=$DUR
+	    if test "$XYEAR_MONTHS" = 2; then
+		# small graph with 1 label/year
+		# 365*24*60*60 = 31536000 = year
+		XGRID="--x-grid YEAR:1:YEAR:1:YEAR:1:31536000:%Y"
+	    else
+		# label every other month on big graphs
+		# 28*24*60*60 = 2419200
+		XYEAR_MONTHS=2
+		XGRID="--x-grid MONTH:1:YEAR:1:MONTH:2:2419200:%b"
+	    fi
+	    ;;
+	*)
+	    case $DUR in
+		3y*) DUR=3years;;
+		4y*) DUR=4years;;
+		# assume everything else is the 5 year maximum in the RRD files
+		*) DUR=5years;;
+	    esac
+	    SPAN=$DUR
+	    if test "$XYEAR_MONTHS" = 2; then
+		# small graph with 1 label/year
+		# 365*24*60*60 = 31536000 = year
+		XGRID="--x-grid YEAR:1:YEAR:1:YEAR:1:31536000:%Y"
+	    else
+		# big graph with 1 label/year
+		XGRID="--x-grid MONTH:1:MONTH:12:MONTH:12:0:%b/%y"
+	    fi
+	    ;;
+    esac
+
+    ONAME=-
+
+    PERCENT='reports,/,100,*,0,100,LIMIT'
+    if test $YRESOL -eq 1; then
+	YUNIT="0,1e12,LIMIT"
+    else
+	YUNIT="$YRESOL,*,0,1e12,LIMIT"
+    fi
+
+    if test "$GRAPH_RATIO" = yes; then
+	if test "X$GNAME" != X-; then
+	    ONAME=$GNAME-spam-ratio.$DUR.$FTYPE
+	    echo "$ONAME: " | tr -d '\012'
+	fi
+	TITLE=`echo "$TITLE_PAT" | sed -e 's/%1/Spam Ratio/g'`
+	RATIOS="'CDEF:percentbulk=bulk,$PERCENT'			\
+	    'CDEF:percentspam=spam,$PERCENT'				\
+	    'AREA:percentbulk$C_INDIANRED:$LABEL_BULK'			\
+	    'AREA:percentspam$C_PINK:$LABEL_SPAM'"
+	RATIOS="$RATIOS'\j' 'GPRINT:percentbulk:AVERAGE:%.0lf%%'"
+	    if test -n "$BIG"; then
+		RATIOS="$RATIOS						\
+		    '$END_COMMENT'					\
+		    'GPRINT:percentspam:AVERAGE:%.0lf%%\j'"
+	    else
+		RATIOS="$RATIOS '$END_COMMENT\j'"
+	    fi
+	eval $RRDTOOL graph $ONAME "$RRDOPTS"				\
+	    --end $END --start end-$SPAN				\
+	    $ATTRIBS "--title '$TITLE'"					\
+	    $XGRID $P_YGRID --upper-limit 100				\
+	    DEF:reports=$FILE:reports:AVERAGE				\
+	    DEF:bulk=$FILE:bulk:AVERAGE					\
+	    DEF:spam=$FILE:spam:AVERAGE					\
+	    $RATIOS
+	if test "X$GNAME" = X-; then
+	    exit
+	fi
+    fi
+
+    if test "$GRAPH_TRAFFIC" = yes; then
+	if test "X$GNAME" != X-; then
+	    ONAME=$GNAME-spam.$DUR.$FTYPE
+	    echo "$ONAME: " | tr -d '\012'
+	fi
+	TITLE=`echo "$TITLE_PAT" | sed -e 's/%1/Mail Checked/g'`
+	if test -n "$BIG"; then
+	    LEGEND="'GPRINT:greports:AVERAGE:$AVGFMT'			\
+		'GPRINT:gbulk:AVERAGE:$AVGFMT'				\
+		'GPRINT:gspam:AVERAGE:$AVGFMT'"
+	    LEGEND="$LEGEND'\j' '$END_COMMENT\c'"
+	else
+	    LEGEND="'GPRINT:greports:AVERAGE:$AVGFMT' '$END_COMMENT\j'"
+	fi
+	TRAFFIC="'DEF:reports=$FILE:reports:AVERAGE'			\
+	    'CDEF:greports=reports,$YUNIT'				\
+	    'DEF:bulk=$FILE:bulk:AVERAGE'				\
+	    'CDEF:gbulk=bulk,$YUNIT'					\
+	    'DEF:spam=$FILE:spam:AVERAGE'				\
+	    'CDEF:gspam=spam,$YUNIT'					\
+	    'AREA:greports$C_SKY_BLUE:$LABEL_REPORTS'			\
+	    'AREA:gbulk$C_INDIANRED:$LABEL_BULK'			\
+	    'AREA:gspam$C_PINK:$LABEL_SPAM'"
+	eval $RRDTOOL graph $ONAME "$RRDOPTS"				\
+	    --end $END --start end-$SPAN				\
+	    $ATTRIBS "--title '$TITLE'"					\
+	    $XGRID $M_YGRID --vertical-label $M_YLABEL			\
+	    $TRAFFIC"'\j'" $LEGEND
+	if test "X$GNAME" = X-; then
+	    exit
+	fi
+    fi
+
+    # database size graph
+    if test -n "$GRAPH_DB" -a \( -n "$SPANS_SET" -o $SPAN != 24h \); then
+	if test "X$GNAME" != X-; then
+	    ONAME=$GNAME-hashes.$DUR.$FTYPE
+	    echo "$ONAME: " | tr -d '\012'
+	fi
+	TITLE=`echo "$TITLE_PAT" | sed -e 's/%1/Checksums/g'`
+	# show only the minimum values for old RRD files
+	if test "$GRAPH_DB" = yes; then
+	    if test -z "`$RRDTOOL info $FILE				\
+			    | grep '^rra.*cf = .MAX.'`"; then
+		GRAPH_DB=db-min
+	    fi
+	fi
+	if test "$GRAPH_DB" = db-min; then
+	    DISPLAY="DEF:minhash=$FILE:hashes:MIN			\
+		AREA:minhash$C_PINK"
+	else
+	    DISPLAY="DEF:minhash=$FILE:hashes:MIN			\
+		DEF:maxhash=$FILE:hashes:MAX				\
+		AREA:maxhash$C_INDIANRED:max				\
+		AREA:minhash$C_PINK:min"
+	fi
+	# take the database values from the last server
+	eval $RRDTOOL graph $ONAME $RRDOPTS				\
+	    --end $END_DAY --start end-$SPAN				\
+	    $ATTRIBS --step 86400 "--title '$TITLE'"			\
+	    $XGRID $H_YGRID $DISPLAY "'$END_DAY_COMMENT\c'"
+    fi
+done