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