182ead
#!/bin/sh
182ead
#
182ead
# plugin for munin to monitor usage of unbound servers.
182ead
#
182ead
# (C) 2008 W.C.A. Wijngaards.  BSD Licensed.
182ead
#
182ead
# To install; enable statistics and unbound-control in unbound.conf
182ead
#	server:		extended-statistics: yes
182ead
#			statistics-cumulative: no
182ead
#			statistics-interval: 0
182ead
#	remote-control:	control-enable: yes
182ead
# Run the command unbound-control-setup to generate the key files.
182ead
#
182ead
# Environment variables for this script
182ead
#	statefile	- where to put temporary statefile.
182ead
#	unbound_conf	- where the unbound.conf file is located.
182ead
#	unbound_control	- where to find unbound-control executable.
182ead
#	spoof_warn	- what level to warn about spoofing
182ead
#	spoof_crit	- what level to crit about spoofing
182ead
#
182ead
# You can set them in your munin/plugin-conf.d/plugins.conf file
182ead
# with:
182ead
# [unbound*]
182ead
# user root
182ead
# env.statefile /usr/local/var/munin/plugin-state/unbound-state
182ead
# env.unbound_conf /usr/local/etc/unbound/unbound.conf
182ead
# env.unbound_control /usr/local/sbin/unbound-control
182ead
# env.spoof_warn 1000
182ead
# env.spoof_crit 100000
182ead
#
182ead
# This plugin can create different graphs depending on what name
182ead
# you link it as (with ln -s) into the plugins directory
182ead
# You can link it multiple times.
182ead
# If you are only a casual user, the _hits and _by_type are most interesting,
182ead
# possibly followed by _by_rcode.
182ead
#
182ead
#	unbound_munin_hits	- base volume, cache hits, unwanted traffic
182ead
#	unbound_munin_queue	- to monitor the internal requestlist
182ead
#	unbound_munin_memory	- memory usage
182ead
#	unbound_munin_by_type	- incoming queries by type
182ead
#	unbound_munin_by_class	- incoming queries by class
182ead
#	unbound_munin_by_opcode	- incoming queries by opcode
182ead
#	unbound_munin_by_rcode	- answers by rcode, validation status
182ead
#	unbound_munin_by_flags	- incoming queries by flags
182ead
#	unbound_munin_histogram	- histogram of query resolving times
182ead
#
182ead
# Magic markers - optional - used by installation scripts and
182ead
# munin-config:
182ead
#
182ead
#%# family=contrib
182ead
#%# capabilities=autoconf suggest
182ead
182ead
# POD documentation
182ead
: <<=cut
182ead
=head1 NAME
182ead
182ead
unbound_munin_ - Munin plugin to monitor the Unbound DNS resolver.
182ead
182ead
=head1 APPLICABLE SYSTEMS
182ead
182ead
System with unbound daemon.
182ead
182ead
=head1 CONFIGURATION
182ead
182ead
  [unbound*]
182ead
  user root
182ead
  env.statefile /var/lib/munin/plugin-state/unbound-state
182ead
  env.unbound_conf /etc/unbound/unbound.conf
182ead
  env.unbound_control /usr/sbin/unbound-control
182ead
  env.spoof_warn 1000
182ead
  env.spoof_crit 100000
182ead
182ead
Use the .env settings to override the defaults.
182ead
182ead
=head1 USAGE
182ead
182ead
Can be used to present different graphs. Use ln -s for that name in
182ead
the plugins directory to enable the graph.
182ead
unbound_munin_hits	- base volume, cache hits, unwanted traffic
182ead
unbound_munin_queue	- to monitor the internal requestlist
182ead
unbound_munin_memory	- memory usage
182ead
unbound_munin_by_type	- incoming queries by type
182ead
unbound_munin_by_class	- incoming queries by class
182ead
unbound_munin_by_opcode	- incoming queries by opcode
182ead
unbound_munin_by_rcode	- answers by rcode, validation status
182ead
unbound_munin_by_flags	- incoming queries by flags
182ead
unbound_munin_histogram - histogram of query resolving times
182ead
182ead
=head1 AUTHOR
182ead
182ead
Copyright 2008 W.C.A. Wijngaards
182ead
182ead
=head1 LICENSE
182ead
182ead
BSD
182ead
182ead
=cut
182ead
182ead
state=${statefile:-/var/lib/munin/plugin-state/unbound-state}
182ead
conf=${unbound_conf:-/etc/unbound/unbound.conf}
182ead
ctrl=${unbound_control:-/usr/sbin/unbound-control}
182ead
warn=${spoof_warn:-1000}
182ead
crit=${spoof_crit:-100000}
182ead
lock=$state.lock
182ead
182ead
# number of seconds between polling attempts.
182ead
# makes the statefile hang around for at least this many seconds,
182ead
# so that multiple links of this script can share the results.
182ead
lee=55
182ead
182ead
# to keep things within 19 characters
182ead
ABBREV="-e s/total/t/ -e s/thread/t/ -e s/num/n/ -e s/query/q/ -e s/answer/a/ -e s/unwanted/u/ -e s/requestlist/ql/ -e s/type/t/ -e s/class/c/ -e s/opcode/o/ -e s/rcode/r/ -e s/edns/e/ -e s/mem/m/ -e s/cache/c/ -e s/mod/m/"
182ead
182ead
# get value from $1 into return variable $value
182ead
get_value ( ) {
182ead
	value="`grep '^'$1'=' $state | sed -e 's/^.*=//'`"
182ead
	if test "$value"x = ""x; then
182ead
		value="0"
182ead
	fi
182ead
}
182ead
182ead
# download the state from the unbound server.
182ead
get_state ( ) {
182ead
	# obtain lock for fetching the state
182ead
	# because there is a race condition in fetching and writing to file
182ead
182ead
	# see if the lock is stale, if so, take it 
182ead
	if test -f $lock ; then
182ead
		pid="`cat $lock 2>&1`"
182ead
		kill -0 "$pid" >/dev/null 2>&1
182ead
		if test $? -ne 0 -a "$pid" != $$ ; then
182ead
			echo $$ >$lock
182ead
		fi
182ead
	fi
182ead
182ead
	i=0
182ead
	while test ! -f $lock || test "`cat $lock 2>&1`" != $$; do
182ead
		while test -f $lock; do
182ead
			# wait
182ead
			i=`expr $i + 1`
182ead
			if test $i -gt 1000; then
182ead
				sleep 1;
182ead
			fi
182ead
			if test $i -gt 1500; then
182ead
				echo "error locking $lock" "=" `cat $lock`
182ead
				rm -f $lock
182ead
				exit 1
182ead
			fi
182ead
		done
182ead
		# try to get it
182ead
		echo $$ >$lock
182ead
	done
182ead
	# do not refetch if the file exists and only LEE seconds old
182ead
	if test -f $state; then
182ead
		now=`date +%s`
182ead
		get_value "time.now"
182ead
		value="`echo $value | sed -e 's/\..*$//'`"
182ead
		if test $now -lt `expr $value + $lee`; then
182ead
			rm -f $lock
182ead
			return
182ead
		fi
182ead
	fi
182ead
	$ctrl -c $conf stats > $state
182ead
	if test $? -ne 0; then
182ead
		echo "error retrieving data from unbound server"
182ead
		rm -f $lock
182ead
		exit 1
182ead
	fi
182ead
	rm -f $lock
182ead
}
182ead
182ead
if test "$1" = "autoconf" ; then
182ead
	if test ! -f $conf; then
182ead
		echo no "($conf does not exist)"
182ead
		exit 1
182ead
	fi
182ead
	if test ! -d `dirname $state`; then
182ead
		echo no "($state directory does not exist)"
182ead
		exit 1
182ead
	fi
182ead
	echo yes
182ead
	exit 0
182ead
fi
182ead
182ead
if test "$1" = "suggest" ; then
182ead
	echo "hits"
182ead
	echo "queue"
182ead
	echo "memory"
182ead
	echo "by_type"
182ead
	echo "by_class"
182ead
	echo "by_opcode"
182ead
	echo "by_rcode"
182ead
	echo "by_flags"
182ead
	echo "histogram"
182ead
	exit 0
182ead
fi
182ead
182ead
# determine my type, by name
182ead
id=`echo $0 | sed -e 's/^.*unbound_munin_//'`
182ead
if test "$id"x = ""x; then
182ead
	# some default to keep people sane.
182ead
	id="hits"
182ead
fi
182ead
182ead
# if $1 exists in statefile, config is echoed with label $2
182ead
exist_config ( ) {
182ead
	mn=`echo $1 | sed $ABBREV | tr . _`
182ead
	if grep '^'$1'=' $state >/dev/null 2>&1; then
182ead
		echo "$mn.label $2"
182ead
		echo "$mn.min 0"
182ead
	fi
182ead
}
182ead
182ead
# print label and min 0 for a name $1 in unbound format
182ead
p_config ( ) {
182ead
	mn=`echo $1 | sed $ABBREV | tr . _`
182ead
	echo $mn.label "$2"
182ead
	echo $mn.min 0
182ead
}
182ead
182ead
if test "$1" = "config" ; then
182ead
	if test ! -f $state; then
182ead
		get_state
182ead
	fi
182ead
	case $id in
182ead
	hits)
182ead
		echo "graph_title Unbound DNS traffic and cache hits"
182ead
		echo "graph_args --base 1000 -l 0"
182ead
		echo "graph_vlabel queries / second"
182ead
		echo "graph_category DNS"
182ead
		for x in thread0.num.queries thread1.num.queries \
182ead
		thread2.num.queries thread3.num.queries thread4.num.queries \
182ead
		thread5.num.queries thread6.num.queries thread7.num.queries; do
182ead
			exist_config $x "queries handled by `basename $x .num.queries`"
182ead
		done
182ead
		p_config "total.num.queries" "total queries from clients"
182ead
		p_config "total.num.cachehits" "cache hits"
182ead
		p_config "total.num.prefetch" "cache prefetch"
182ead
		p_config "num.query.tcp" "TCP queries"
182ead
		p_config "num.query.ipv6" "IPv6 queries"
182ead
		p_config "unwanted.queries" "queries that failed acl"
182ead
		p_config "unwanted.replies" "unwanted or unsolicited replies"
182ead
		echo "u_replies.warning $warn"
182ead
		echo "u_replies.critical $crit"
182ead
		echo "graph_info DNS queries to the recursive resolver. The unwanted replies could be innocent duplicate packets, late replies, or spoof threats."
182ead
		;;
182ead
	queue)
182ead
		echo "graph_title Unbound requestlist size"
182ead
		echo "graph_args --base 1000 -l 0"
182ead
		echo "graph_vlabel number of queries"
182ead
		echo "graph_category DNS"
182ead
		p_config "total.requestlist.avg" "Average size of queue on insert"
182ead
		p_config "total.requestlist.max" "Max size of queue (in 5 min)"
182ead
		p_config "total.requestlist.overwritten" "Number of queries replaced by new ones"
182ead
		p_config "total.requestlist.exceeded" "Number of queries dropped due to lack of space"
182ead
		echo "graph_info The queries that did not hit the cache and need recursion service take up space in the requestlist. If there are too many queries, first queries get overwritten, and at last resort dropped."
182ead
		;;
182ead
	memory)
182ead
		echo "graph_title Unbound memory usage"
182ead
		echo "graph_args --base 1024 -l 0"
182ead
		echo "graph_vlabel memory used in bytes"
182ead
		echo "graph_category DNS"
182ead
		p_config "mem.total.sbrk" "Total memory"
182ead
		p_config "mem.cache.rrset" "RRset cache memory"
182ead
		p_config "mem.cache.message" "Message cache memory"
182ead
		p_config "mem.mod.iterator" "Iterator module memory"
182ead
		p_config "mem.mod.validator" "Validator module and key cache memory"
182ead
		echo "graph_info The memory used by unbound."
182ead
		;;
182ead
	by_type)
182ead
		echo "graph_title Unbound DNS queries by type"
182ead
		echo "graph_args --base 1000 -l 0"
182ead
		echo "graph_vlabel queries / second"
182ead
		echo "graph_category DNS"
182ead
		for x in `grep "^num.query.type" $state`; do
182ead
			nm=`echo $x | sed -e 's/=.*$//'`
182ead
			tp=`echo $nm | sed -e s/num.query.type.//`
182ead
			p_config "$nm" "$tp"
182ead
		done
182ead
		echo "graph_info queries by DNS RR type queried for"
182ead
		;;
182ead
	by_class)
182ead
		echo "graph_title Unbound DNS queries by class"
182ead
		echo "graph_args --base 1000 -l 0"
182ead
		echo "graph_vlabel queries / second"
182ead
		echo "graph_category DNS"
182ead
		for x in `grep "^num.query.class" $state`; do
182ead
			nm=`echo $x | sed -e 's/=.*$//'`
182ead
			tp=`echo $nm | sed -e s/num.query.class.//`
182ead
			p_config "$nm" "$tp"
182ead
		done
182ead
		echo "graph_info queries by DNS RR class queried for."
182ead
		;;
182ead
	by_opcode)
182ead
		echo "graph_title Unbound DNS queries by opcode"
182ead
		echo "graph_args --base 1000 -l 0"
182ead
		echo "graph_vlabel queries / second"
182ead
		echo "graph_category DNS"
182ead
		for x in `grep "^num.query.opcode" $state`; do
182ead
			nm=`echo $x | sed -e 's/=.*$//'`
182ead
			tp=`echo $nm | sed -e s/num.query.opcode.//`
182ead
			p_config "$nm" "$tp"
182ead
		done
182ead
		echo "graph_info queries by opcode in the query packet."
182ead
		;;
182ead
	by_rcode)
182ead
		echo "graph_title Unbound DNS answers by return code"
182ead
		echo "graph_args --base 1000 -l 0"
182ead
		echo "graph_vlabel answer packets / second"
182ead
		echo "graph_category DNS"
182ead
		for x in `grep "^num.answer.rcode" $state`; do
182ead
			nm=`echo $x | sed -e 's/=.*$//'`
182ead
			tp=`echo $nm | sed -e s/num.answer.rcode.//`
182ead
			p_config "$nm" "$tp"
182ead
		done
182ead
		p_config "num.answer.secure" "answer secure"
182ead
		p_config "num.answer.bogus" "answer bogus"
182ead
		p_config "num.rrset.bogus" "num rrsets marked bogus"
182ead
		echo "graph_info answers sorted by return value. rrsets bogus is the number of rrsets marked bogus per second by the validator"
182ead
		;;
182ead
	by_flags)
182ead
		echo "graph_title Unbound DNS incoming queries by flags"
182ead
		echo "graph_args --base 1000 -l 0"
182ead
		echo "graph_vlabel queries / second"
182ead
		echo "graph_category DNS"
182ead
		p_config "num.query.flags.QR" "QR (query reply) flag"
182ead
		p_config "num.query.flags.AA" "AA (auth answer) flag"
182ead
		p_config "num.query.flags.TC" "TC (truncated) flag"
182ead
		p_config "num.query.flags.RD" "RD (recursion desired) flag"
182ead
		p_config "num.query.flags.RA" "RA (rec avail) flag"
182ead
		p_config "num.query.flags.Z" "Z (zero) flag"
182ead
		p_config "num.query.flags.AD" "AD (auth data) flag"
182ead
		p_config "num.query.flags.CD" "CD (check disabled) flag"
182ead
		p_config "num.query.edns.present" "EDNS OPT present"
182ead
		p_config "num.query.edns.DO" "DO (DNSSEC OK) flag"
182ead
		echo "graph_info This graphs plots the flags inside incoming queries. For example, if QR, AA, TC, RA, Z flags are set, the query can be rejected. RD, AD, CD and DO are legitimately set by some software."
182ead
		;;
182ead
	histogram)
182ead
		echo "graph_title Unbound DNS histogram of reply time"
182ead
		echo "graph_args --base 1000 -l 0"
182ead
		echo "graph_vlabel queries / second"
182ead
		echo "graph_category DNS"
182ead
		echo hcache.label "cache hits"
182ead
		echo hcache.min 0
182ead
		echo hcache.draw AREA
182ead
		echo hcache.colour 999999
182ead
		echo h64ms.label "0 msec - 66 msec"
182ead
		echo h64ms.min 0
182ead
		echo h64ms.draw STACK
182ead
		echo h64ms.colour 0000FF
182ead
		echo h128ms.label "66 msec - 131 msec"
182ead
		echo h128ms.min 0
182ead
		echo h128ms.colour 1F00DF
182ead
		echo h128ms.draw STACK
182ead
		echo h256ms.label "131 msec - 262 msec"
182ead
		echo h256ms.min 0
182ead
		echo h256ms.draw STACK
182ead
		echo h256ms.colour 3F00BF
182ead
		echo h512ms.label "262 msec - 524 msec"
182ead
		echo h512ms.min 0
182ead
		echo h512ms.draw STACK
182ead
		echo h512ms.colour 5F009F
182ead
		echo h1s.label "524 msec - 1 sec"
182ead
		echo h1s.min 0
182ead
		echo h1s.draw STACK
182ead
		echo h1s.colour 7F007F
182ead
		echo h2s.label "1 sec - 2 sec"
182ead
		echo h2s.min 0
182ead
		echo h2s.draw STACK
182ead
		echo h2s.colour 9F005F
182ead
		echo h4s.label "2 sec - 4 sec"
182ead
		echo h4s.min 0
182ead
		echo h4s.draw STACK
182ead
		echo h4s.colour BF003F
182ead
		echo h8s.label "4 sec - 8 sec"
182ead
		echo h8s.min 0
182ead
		echo h8s.draw STACK
182ead
		echo h8s.colour DF001F
182ead
		echo h16s.label "8 sec - ..."
182ead
		echo h16s.min 0
182ead
		echo h16s.draw STACK
182ead
		echo h16s.colour FF0000
182ead
		echo "graph_info Histogram of the reply times for queries."
182ead
		;;
182ead
	esac
182ead
182ead
	exit 0
182ead
fi
182ead
182ead
# do the stats itself
182ead
get_state
182ead
182ead
# get the time elapsed
182ead
get_value "time.elapsed"
182ead
if test $value = 0 || test $value = "0.000000"; then
182ead
	echo "error: time elapsed 0 or could not retrieve data"
182ead
	exit 1
182ead
fi
182ead
elapsed="$value"
182ead
182ead
# print value for $1 / elapsed
182ead
print_qps ( ) {
182ead
	mn=`echo $1 | sed $ABBREV | tr . _`
182ead
	get_value $1
182ead
	echo "$mn.value" `echo scale=6';' $value / $elapsed | bc `
182ead
}
182ead
182ead
# print qps if line already found in $2
182ead
print_qps_line ( ) {
182ead
	mn=`echo $1 | sed $ABBREV | tr . _`
182ead
	value="`echo $2 | sed -e 's/^.*=//'`"
182ead
	echo "$mn.value" `echo scale=6';' $value / $elapsed | bc `
182ead
}
182ead
182ead
# print value for $1
182ead
print_value ( ) {
182ead
	mn=`echo $1 | sed $ABBREV | tr . _`
182ead
	get_value $1
182ead
	echo "$mn.value" $value
182ead
}
182ead
182ead
case $id in
182ead
hits)
182ead
	for x in thread0.num.queries thread1.num.queries thread2.num.queries \
182ead
		thread3.num.queries thread4.num.queries thread5.num.queries \
182ead
		thread6.num.queries thread7.num.queries total.num.queries \
182ead
		total.num.cachehits total.num.prefetch num.query.tcp \
182ead
		num.query.ipv6 unwanted.queries unwanted.replies; do
182ead
		if grep "^"$x"=" $state >/dev/null 2>&1; then
182ead
			print_qps $x
182ead
		fi
182ead
	done
182ead
	;;
182ead
queue)
182ead
	for x in total.requestlist.avg total.requestlist.max \
182ead
		total.requestlist.overwritten total.requestlist.exceeded; do
182ead
		print_value $x
182ead
	done
182ead
	;;
182ead
memory)
182ead
	mn=`echo mem.total.sbrk | sed $ABBREV | tr . _`
182ead
	get_value 'mem.total.sbrk'
182ead
	if test $value -eq 0; then
182ead
		chk=`echo $ctrl | sed -e 's/-control$/-checkconf/'`
182ead
		pidf=`$chk -o pidfile $conf 2>&1`
182ead
		pid=`cat $pidf 2>&1`
182ead
		value=`ps -p "$pid" -o rss= 2>&1`
182ead
		if test "`expr $value + 1 - 1 2>&1`" -eq "$value" 2>&1; then
182ead
			value=`expr $value \* 1024` 
182ead
		else
182ead
			value=0
182ead
		fi
182ead
	fi
182ead
	echo "$mn.value" $value
182ead
	for x in mem.cache.rrset mem.cache.message \
182ead
		mem.mod.iterator mem.mod.validator; do
182ead
		print_value $x
182ead
	done
182ead
	;;
182ead
by_type)
182ead
	for x in `grep "^num.query.type" $state`; do
182ead
		nm=`echo $x | sed -e 's/=.*$//'`
182ead
		print_qps_line $nm $x
182ead
	done
182ead
	;;
182ead
by_class)
182ead
	for x in `grep "^num.query.class" $state`; do
182ead
		nm=`echo $x | sed -e 's/=.*$//'`
182ead
		print_qps_line $nm $x
182ead
	done
182ead
	;;
182ead
by_opcode)
182ead
	for x in `grep "^num.query.opcode" $state`; do
182ead
		nm=`echo $x | sed -e 's/=.*$//'`
182ead
		print_qps_line $nm $x
182ead
	done
182ead
	;;
182ead
by_rcode)
182ead
	for x in `grep "^num.answer.rcode" $state`; do
182ead
		nm=`echo $x | sed -e 's/=.*$//'`
182ead
		print_qps_line $nm $x
182ead
	done
182ead
	print_qps "num.answer.secure"
182ead
	print_qps "num.answer.bogus"
182ead
	print_qps "num.rrset.bogus"
182ead
	;;
182ead
by_flags)
182ead
	for x in num.query.flags.QR num.query.flags.AA num.query.flags.TC num.query.flags.RD num.query.flags.RA num.query.flags.Z num.query.flags.AD num.query.flags.CD num.query.edns.present num.query.edns.DO; do
182ead
		print_qps $x
182ead
	done
182ead
	;;
182ead
histogram)
182ead
	get_value total.num.cachehits
182ead
	echo hcache.value `echo scale=6';' $value / $elapsed | bc `
182ead
	r=0
182ead
	for x in histogram.000000.000000.to.000000.000001 \
182ead
		histogram.000000.000001.to.000000.000002 \
182ead
		histogram.000000.000002.to.000000.000004 \
182ead
		histogram.000000.000004.to.000000.000008 \
182ead
		histogram.000000.000008.to.000000.000016 \
182ead
		histogram.000000.000016.to.000000.000032 \
182ead
		histogram.000000.000032.to.000000.000064 \
182ead
		histogram.000000.000064.to.000000.000128 \
182ead
		histogram.000000.000128.to.000000.000256 \
182ead
		histogram.000000.000256.to.000000.000512 \
182ead
		histogram.000000.000512.to.000000.001024 \
182ead
		histogram.000000.001024.to.000000.002048 \
182ead
		histogram.000000.002048.to.000000.004096 \
182ead
		histogram.000000.004096.to.000000.008192 \
182ead
		histogram.000000.008192.to.000000.016384 \
182ead
		histogram.000000.016384.to.000000.032768 \
182ead
		histogram.000000.032768.to.000000.065536; do
182ead
		get_value $x
182ead
		r=`expr $r + $value`
182ead
	done
182ead
	echo h64ms.value `echo scale=6';' $r / $elapsed | bc `
182ead
	get_value histogram.000000.065536.to.000000.131072
182ead
	echo h128ms.value `echo scale=6';' $value / $elapsed | bc `
182ead
	get_value histogram.000000.131072.to.000000.262144
182ead
	echo h256ms.value `echo scale=6';' $value / $elapsed | bc `
182ead
	get_value histogram.000000.262144.to.000000.524288
182ead
	echo h512ms.value `echo scale=6';' $value / $elapsed | bc `
182ead
	get_value histogram.000000.524288.to.000001.000000
182ead
	echo h1s.value `echo scale=6';' $value / $elapsed | bc `
182ead
	get_value histogram.000001.000000.to.000002.000000
182ead
	echo h2s.value `echo scale=6';' $value / $elapsed | bc `
182ead
	get_value histogram.000002.000000.to.000004.000000
182ead
	echo h4s.value `echo scale=6';' $value / $elapsed | bc `
182ead
	get_value histogram.000004.000000.to.000008.000000
182ead
	echo h8s.value `echo scale=6';' $value / $elapsed | bc `
182ead
	r=0
182ead
	for x in histogram.000008.000000.to.000016.000000 \
182ead
		histogram.000016.000000.to.000032.000000 \
182ead
		histogram.000032.000000.to.000064.000000 \
182ead
		histogram.000064.000000.to.000128.000000 \
182ead
		histogram.000128.000000.to.000256.000000 \
182ead
		histogram.000256.000000.to.000512.000000 \
182ead
		histogram.000512.000000.to.001024.000000 \
182ead
		histogram.001024.000000.to.002048.000000 \
182ead
		histogram.002048.000000.to.004096.000000 \
182ead
		histogram.004096.000000.to.008192.000000 \
182ead
		histogram.008192.000000.to.016384.000000 \
182ead
		histogram.016384.000000.to.032768.000000 \
182ead
		histogram.032768.000000.to.065536.000000 \
182ead
		histogram.065536.000000.to.131072.000000 \
182ead
		histogram.131072.000000.to.262144.000000 \
182ead
		histogram.262144.000000.to.524288.000000; do
182ead
		get_value $x
182ead
		r=`expr $r + $value`
182ead
	done
182ead
	echo h16s.value `echo scale=6';' $r / $elapsed | bc `
182ead
	;;
182ead
esac