1b5663de9SDag-Erling Smørgrav#!/bin/sh
2b5663de9SDag-Erling Smørgrav#
3b5663de9SDag-Erling Smørgrav# plugin for munin to monitor usage of unbound servers.
4b5663de9SDag-Erling Smørgrav# To install copy this to /usr/local/share/munin/plugins/unbound_munin_
5b5663de9SDag-Erling Smørgrav# and use munin-node-configure (--suggest, --shell).
6b5663de9SDag-Erling Smørgrav#
7b5663de9SDag-Erling Smørgrav# (C) 2008 W.C.A. Wijngaards.  BSD Licensed.
8b5663de9SDag-Erling Smørgrav#
9b5663de9SDag-Erling Smørgrav# To install; enable statistics and unbound-control in unbound.conf
10b5663de9SDag-Erling Smørgrav#	server:		extended-statistics: yes
11b5663de9SDag-Erling Smørgrav#			statistics-cumulative: no
12b5663de9SDag-Erling Smørgrav#			statistics-interval: 0
13b5663de9SDag-Erling Smørgrav#	remote-control:	control-enable: yes
14b5663de9SDag-Erling Smørgrav# Run the command unbound-control-setup to generate the key files.
15b5663de9SDag-Erling Smørgrav#
16b5663de9SDag-Erling Smørgrav# Environment variables for this script
17b5663de9SDag-Erling Smørgrav#	unbound_conf	- where the unbound.conf file is located.
18b5663de9SDag-Erling Smørgrav#	unbound_control	- where to find unbound-control executable.
19b5663de9SDag-Erling Smørgrav#	spoof_warn	- what level to warn about spoofing
20b5663de9SDag-Erling Smørgrav#	spoof_crit	- what level to crit about spoofing
21b5663de9SDag-Erling Smørgrav#
22b5663de9SDag-Erling Smørgrav# You can set them in your munin/plugin-conf.d/plugins.conf file
23b5663de9SDag-Erling Smørgrav# with:
24b5663de9SDag-Erling Smørgrav# [unbound*]
25b5663de9SDag-Erling Smørgrav# user root
26b5663de9SDag-Erling Smørgrav# env.unbound_conf /usr/local/etc/unbound/unbound.conf
27b5663de9SDag-Erling Smørgrav# env.unbound_control /usr/local/sbin/unbound-control
28b5663de9SDag-Erling Smørgrav# env.spoof_warn 1000
29b5663de9SDag-Erling Smørgrav# env.spoof_crit 100000
30b5663de9SDag-Erling Smørgrav#
31b5663de9SDag-Erling Smørgrav# This plugin can create different graphs depending on what name
32b5663de9SDag-Erling Smørgrav# you link it as (with ln -s) into the plugins directory
33b5663de9SDag-Erling Smørgrav# You can link it multiple times.
34b5663de9SDag-Erling Smørgrav# If you are only a casual user, the _hits and _by_type are most interesting,
35b5663de9SDag-Erling Smørgrav# possibly followed by _by_rcode.
36b5663de9SDag-Erling Smørgrav#
37b5663de9SDag-Erling Smørgrav#	unbound_munin_hits	- base volume, cache hits, unwanted traffic
38b5663de9SDag-Erling Smørgrav#	unbound_munin_queue	- to monitor the internal requestlist
39b5663de9SDag-Erling Smørgrav#	unbound_munin_memory	- memory usage
40b5663de9SDag-Erling Smørgrav#	unbound_munin_by_type	- incoming queries by type
41b5663de9SDag-Erling Smørgrav#	unbound_munin_by_class	- incoming queries by class
42b5663de9SDag-Erling Smørgrav#	unbound_munin_by_opcode	- incoming queries by opcode
43b5663de9SDag-Erling Smørgrav#	unbound_munin_by_rcode	- answers by rcode, validation status
44b5663de9SDag-Erling Smørgrav#	unbound_munin_by_flags	- incoming queries by flags
45b5663de9SDag-Erling Smørgrav#	unbound_munin_histogram	- histogram of query resolving times
46b5663de9SDag-Erling Smørgrav#
47b5663de9SDag-Erling Smørgrav# Magic markers - optional - used by installation scripts and
48b5663de9SDag-Erling Smørgrav# munin-config:  (originally contrib family but munin-node-configure ignores it)
49b5663de9SDag-Erling Smørgrav#
50b5663de9SDag-Erling Smørgrav#%# family=auto
51b5663de9SDag-Erling Smørgrav#%# capabilities=autoconf suggest
52b5663de9SDag-Erling Smørgrav
53b5663de9SDag-Erling Smørgrav# POD documentation
54b5663de9SDag-Erling Smørgrav: <<=cut
55b5663de9SDag-Erling Smørgrav=head1 NAME
56b5663de9SDag-Erling Smørgrav
57b5663de9SDag-Erling Smørgravunbound_munin_ - Munin plugin to monitor the Unbound DNS resolver.
58b5663de9SDag-Erling Smørgrav
59b5663de9SDag-Erling Smørgrav=head1 APPLICABLE SYSTEMS
60b5663de9SDag-Erling Smørgrav
61b5663de9SDag-Erling SmørgravSystem with unbound daemon.
62b5663de9SDag-Erling Smørgrav
63b5663de9SDag-Erling Smørgrav=head1 CONFIGURATION
64b5663de9SDag-Erling Smørgrav
65b5663de9SDag-Erling Smørgrav  [unbound*]
66b5663de9SDag-Erling Smørgrav  user root
67b5663de9SDag-Erling Smørgrav  env.unbound_conf /usr/local/etc/unbound/unbound.conf
68b5663de9SDag-Erling Smørgrav  env.unbound_control /usr/local/sbin/unbound-control
69b5663de9SDag-Erling Smørgrav  env.spoof_warn 1000
70b5663de9SDag-Erling Smørgrav  env.spoof_crit 100000
71b5663de9SDag-Erling Smørgrav
72b5663de9SDag-Erling SmørgravUse the .env settings to override the defaults.
73b5663de9SDag-Erling Smørgrav
74b5663de9SDag-Erling Smørgrav=head1 USAGE
75b5663de9SDag-Erling Smørgrav
76b5663de9SDag-Erling SmørgravCan be used to present different graphs. Use ln -s for that name in
77b5663de9SDag-Erling Smørgravthe plugins directory to enable the graph.
78b5663de9SDag-Erling Smørgravunbound_munin_hits	- base volume, cache hits, unwanted traffic
79b5663de9SDag-Erling Smørgravunbound_munin_queue	- to monitor the internal requestlist
80b5663de9SDag-Erling Smørgravunbound_munin_memory	- memory usage
81b5663de9SDag-Erling Smørgravunbound_munin_by_type	- incoming queries by type
82b5663de9SDag-Erling Smørgravunbound_munin_by_class	- incoming queries by class
83b5663de9SDag-Erling Smørgravunbound_munin_by_opcode	- incoming queries by opcode
84b5663de9SDag-Erling Smørgravunbound_munin_by_rcode	- answers by rcode, validation status
85b5663de9SDag-Erling Smørgravunbound_munin_by_flags	- incoming queries by flags
86b5663de9SDag-Erling Smørgravunbound_munin_histogram - histogram of query resolving times
87b5663de9SDag-Erling Smørgrav
88b5663de9SDag-Erling Smørgrav=head1 AUTHOR
89b5663de9SDag-Erling Smørgrav
90b5663de9SDag-Erling SmørgravCopyright 2008 W.C.A. Wijngaards
91b5663de9SDag-Erling Smørgrav
92b5663de9SDag-Erling Smørgrav=head1 LICENSE
93b5663de9SDag-Erling Smørgrav
94b5663de9SDag-Erling SmørgravBSD
95b5663de9SDag-Erling Smørgrav
96b5663de9SDag-Erling Smørgrav=cut
97b5663de9SDag-Erling Smørgrav
985469a995SCy Schubertstate="${MUNIN_PLUGSTATE}/unbound.state"
995469a995SCy Schubertseentags="${MUNIN_PLUGSTATE}/unbound-seentags.state"
100b5663de9SDag-Erling Smørgravconf=${unbound_conf:-/usr/local/etc/unbound/unbound.conf}
101b5663de9SDag-Erling Smørgravctrl=${unbound_control:-/usr/local/sbin/unbound-control}
102b5663de9SDag-Erling Smørgravwarn=${spoof_warn:-1000}
103b5663de9SDag-Erling Smørgravcrit=${spoof_crit:-100000}
104b5663de9SDag-Erling Smørgravlock=$state.lock
105b5663de9SDag-Erling Smørgrav
106b5663de9SDag-Erling Smørgrav# number of seconds between polling attempts.
107b5663de9SDag-Erling Smørgrav# makes the statefile hang around for at least this many seconds,
108b5663de9SDag-Erling Smørgrav# so that multiple links of this script can share the results.
109b5663de9SDag-Erling Smørgravlee=55
110b5663de9SDag-Erling Smørgrav
111b5663de9SDag-Erling Smørgrav# to keep things within 19 characters
112b5663de9SDag-Erling SmørgravABBREV="-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/"
113b5663de9SDag-Erling Smørgrav
114b5663de9SDag-Erling Smørgrav# get value from $1 into return variable $value
115b5663de9SDag-Erling Smørgravget_value ( ) {
116b5663de9SDag-Erling Smørgrav	value="`grep '^'$1'=' $state | sed -e 's/^.*=//'`"
117b5663de9SDag-Erling Smørgrav	if test "$value"x = ""x; then
118b5663de9SDag-Erling Smørgrav		value="0"
119b5663de9SDag-Erling Smørgrav	fi
120b5663de9SDag-Erling Smørgrav}
121b5663de9SDag-Erling Smørgrav
1225469a995SCy Schubert# Update list of seen query types etc to seentags file. This is run while
1235469a995SCy Schubert# holding the lock, after the state file is updated.
1245469a995SCy Schubertupdate_seentags() {
1255469a995SCy Schubert    tmplist="$(cat ${seentags} 2> /dev/null)
1265469a995SCy Schubertnum.query.type.A
1275469a995SCy Schubertnum.query.class.IN
1285469a995SCy Schubertnum.query.opcode.QUERY
1295469a995SCy Schubertnum.answer.rcode.NOERROR
1305469a995SCy Schubert"
1315469a995SCy Schubert    (echo "${tmplist}"; grep ^num ${state} | sed -e 's/=.*//') | sort -u > ${seentags}
1325469a995SCy Schubert}
1335469a995SCy Schubert
134b5663de9SDag-Erling Smørgrav# download the state from the unbound server.
135b5663de9SDag-Erling Smørgravget_state ( ) {
136b5663de9SDag-Erling Smørgrav	# obtain lock for fetching the state
137b5663de9SDag-Erling Smørgrav	# because there is a race condition in fetching and writing to file
138b5663de9SDag-Erling Smørgrav
139b5663de9SDag-Erling Smørgrav	# see if the lock is stale, if so, take it
140b5663de9SDag-Erling Smørgrav	if test -f $lock ; then
141b5663de9SDag-Erling Smørgrav		pid="`cat $lock 2>&1`"
142b5663de9SDag-Erling Smørgrav		kill -0 "$pid" >/dev/null 2>&1
143b5663de9SDag-Erling Smørgrav		if test $? -ne 0 -a "$pid" != $$ ; then
144b5663de9SDag-Erling Smørgrav			echo $$ >$lock
145b5663de9SDag-Erling Smørgrav		fi
146b5663de9SDag-Erling Smørgrav	fi
147b5663de9SDag-Erling Smørgrav
148b5663de9SDag-Erling Smørgrav	i=0
149b5663de9SDag-Erling Smørgrav	while test ! -f $lock || test "`cat $lock 2>&1`" != $$; do
150b5663de9SDag-Erling Smørgrav		while test -f $lock; do
151b5663de9SDag-Erling Smørgrav			# wait
152b5663de9SDag-Erling Smørgrav			i=`expr $i + 1`
153b5663de9SDag-Erling Smørgrav			if test $i -gt 1000; then
154b5663de9SDag-Erling Smørgrav				sleep 1;
155b5663de9SDag-Erling Smørgrav			fi
156b5663de9SDag-Erling Smørgrav			if test $i -gt 1500; then
157b5663de9SDag-Erling Smørgrav				echo "error locking $lock" "=" `cat $lock`
158b5663de9SDag-Erling Smørgrav				rm -f $lock
159b5663de9SDag-Erling Smørgrav				exit 1
160b5663de9SDag-Erling Smørgrav			fi
161b5663de9SDag-Erling Smørgrav		done
162b5663de9SDag-Erling Smørgrav		# try to get it
163bc892140SDag-Erling Smørgrav		if echo $$ >$lock ; then : ; else break; fi
164b5663de9SDag-Erling Smørgrav	done
165b5663de9SDag-Erling Smørgrav	# do not refetch if the file exists and only LEE seconds old
166b5663de9SDag-Erling Smørgrav	if test -f $state; then
167b5663de9SDag-Erling Smørgrav		now=`date +%s`
168b5663de9SDag-Erling Smørgrav		get_value "time.now"
169b5663de9SDag-Erling Smørgrav		value="`echo $value | sed -e 's/\..*$//'`"
170b5663de9SDag-Erling Smørgrav		if test $now -lt `expr $value + $lee`; then
171b5663de9SDag-Erling Smørgrav			rm -f $lock
172b5663de9SDag-Erling Smørgrav			return
173b5663de9SDag-Erling Smørgrav		fi
174b5663de9SDag-Erling Smørgrav	fi
175b5663de9SDag-Erling Smørgrav	$ctrl -c $conf stats > $state
176b5663de9SDag-Erling Smørgrav	if test $? -ne 0; then
177b5663de9SDag-Erling Smørgrav		echo "error retrieving data from unbound server"
178b5663de9SDag-Erling Smørgrav		rm -f $lock
179b5663de9SDag-Erling Smørgrav		exit 1
180b5663de9SDag-Erling Smørgrav	fi
1815469a995SCy Schubert	update_seentags
182b5663de9SDag-Erling Smørgrav	rm -f $lock
183b5663de9SDag-Erling Smørgrav}
184b5663de9SDag-Erling Smørgrav
185b5663de9SDag-Erling Smørgravif test "$1" = "autoconf" ; then
186b5663de9SDag-Erling Smørgrav	if test ! -f $conf; then
187b5663de9SDag-Erling Smørgrav		echo no "($conf does not exist)"
188c0caa2e2SCy Schubert		exit 0
189b5663de9SDag-Erling Smørgrav	fi
190b5663de9SDag-Erling Smørgrav	if test ! -d `dirname $state`; then
191b5663de9SDag-Erling Smørgrav		echo no "(`dirname $state` directory does not exist)"
192c0caa2e2SCy Schubert		exit 0
193b5663de9SDag-Erling Smørgrav	fi
194b5663de9SDag-Erling Smørgrav	echo yes
195b5663de9SDag-Erling Smørgrav	exit 0
196b5663de9SDag-Erling Smørgravfi
197b5663de9SDag-Erling Smørgrav
198b5663de9SDag-Erling Smørgravif test "$1" = "suggest" ; then
199b5663de9SDag-Erling Smørgrav	echo "hits"
200b5663de9SDag-Erling Smørgrav	echo "queue"
201b5663de9SDag-Erling Smørgrav	echo "memory"
202b5663de9SDag-Erling Smørgrav	echo "by_type"
203b5663de9SDag-Erling Smørgrav	echo "by_class"
204b5663de9SDag-Erling Smørgrav	echo "by_opcode"
205b5663de9SDag-Erling Smørgrav	echo "by_rcode"
206b5663de9SDag-Erling Smørgrav	echo "by_flags"
207b5663de9SDag-Erling Smørgrav	echo "histogram"
208b5663de9SDag-Erling Smørgrav	exit 0
209b5663de9SDag-Erling Smørgravfi
210b5663de9SDag-Erling Smørgrav
211b5663de9SDag-Erling Smørgrav# determine my type, by name
212b5663de9SDag-Erling Smørgravid=`echo $0 | sed -e 's/^.*unbound_munin_//'`
213b5663de9SDag-Erling Smørgravif test "$id"x = ""x; then
214b5663de9SDag-Erling Smørgrav	# some default to keep people sane.
215b5663de9SDag-Erling Smørgrav	id="hits"
216b5663de9SDag-Erling Smørgravfi
217b5663de9SDag-Erling Smørgrav
218b5663de9SDag-Erling Smørgrav# if $1 exists in statefile, config is echoed with label $2
219b5663de9SDag-Erling Smørgravexist_config ( ) {
220b5663de9SDag-Erling Smørgrav	mn=`echo $1 | sed $ABBREV | tr . _`
221b5663de9SDag-Erling Smørgrav	if grep '^'$1'=' $state >/dev/null 2>&1; then
222b5663de9SDag-Erling Smørgrav		echo "$mn.label $2"
223b5663de9SDag-Erling Smørgrav		echo "$mn.min 0"
224b5663de9SDag-Erling Smørgrav		echo "$mn.type ABSOLUTE"
225b5663de9SDag-Erling Smørgrav	fi
226b5663de9SDag-Erling Smørgrav}
227b5663de9SDag-Erling Smørgrav
228b5663de9SDag-Erling Smørgrav# print label and min 0 for a name $1 in unbound format
229b5663de9SDag-Erling Smørgravp_config ( ) {
230b5663de9SDag-Erling Smørgrav	mn=`echo $1 | sed $ABBREV | tr . _`
231b5663de9SDag-Erling Smørgrav	echo $mn.label "$2"
232b5663de9SDag-Erling Smørgrav	echo $mn.min 0
233b5663de9SDag-Erling Smørgrav	echo $mn.type $3
234b5663de9SDag-Erling Smørgrav}
235b5663de9SDag-Erling Smørgrav
236b5663de9SDag-Erling Smørgravif test "$1" = "config" ; then
237b5663de9SDag-Erling Smørgrav	if test ! -f $state; then
238b5663de9SDag-Erling Smørgrav		get_state
239b5663de9SDag-Erling Smørgrav	fi
240b5663de9SDag-Erling Smørgrav	case $id in
241b5663de9SDag-Erling Smørgrav	hits)
242b5663de9SDag-Erling Smørgrav		echo "graph_title Unbound DNS traffic and cache hits"
243b5663de9SDag-Erling Smørgrav		echo "graph_args --base 1000 -l 0"
244b5663de9SDag-Erling Smørgrav		echo "graph_vlabel queries / \${graph_period}"
245b5663de9SDag-Erling Smørgrav		echo "graph_scale no"
2465469a995SCy Schubert		echo "graph_category dns"
247b5663de9SDag-Erling Smørgrav		for x in `grep "^thread[0-9][0-9]*\.num\.queries=" $state |
248b5663de9SDag-Erling Smørgrav			sed -e 's/=.*//'`; do
249b5663de9SDag-Erling Smørgrav			exist_config $x "queries handled by `basename $x .num.queries`"
250b5663de9SDag-Erling Smørgrav		done
251b5663de9SDag-Erling Smørgrav		p_config "total.num.queries" "total queries from clients" "ABSOLUTE"
252b5663de9SDag-Erling Smørgrav		p_config "total.num.cachehits" "cache hits" "ABSOLUTE"
253b5663de9SDag-Erling Smørgrav		p_config "total.num.prefetch" "cache prefetch" "ABSOLUTE"
254b5663de9SDag-Erling Smørgrav		p_config "num.query.tcp" "TCP queries" "ABSOLUTE"
255b5663de9SDag-Erling Smørgrav		p_config "num.query.tcpout" "TCP out queries" "ABSOLUTE"
256*0a92a9fcSCy Schubert		p_config "num.query.udpout" "UDP out queries" "ABSOLUTE"
257091e9e46SCy Schubert		p_config "num.query.tls" "TLS queries" "ABSOLUTE"
258091e9e46SCy Schubert		p_config "num.query.tls.resume" "TLS resumes" "ABSOLUTE"
259b5663de9SDag-Erling Smørgrav		p_config "num.query.ipv6" "IPv6 queries" "ABSOLUTE"
260b5663de9SDag-Erling Smørgrav		p_config "unwanted.queries" "queries that failed acl" "ABSOLUTE"
261b5663de9SDag-Erling Smørgrav		p_config "unwanted.replies" "unwanted or unsolicited replies" "ABSOLUTE"
262b5663de9SDag-Erling Smørgrav		echo "u_replies.warning $warn"
263b5663de9SDag-Erling Smørgrav		echo "u_replies.critical $crit"
264b5663de9SDag-Erling Smørgrav		echo "graph_info DNS queries to the recursive resolver. The unwanted replies could be innocent duplicate packets, late replies, or spoof threats."
265b5663de9SDag-Erling Smørgrav		;;
266b5663de9SDag-Erling Smørgrav	queue)
267b5663de9SDag-Erling Smørgrav		echo "graph_title Unbound requestlist size"
268b5663de9SDag-Erling Smørgrav		echo "graph_args --base 1000 -l 0"
269b5663de9SDag-Erling Smørgrav		echo "graph_vlabel number of queries"
270b5663de9SDag-Erling Smørgrav		echo "graph_scale no"
2715469a995SCy Schubert		echo "graph_category dns"
272b5663de9SDag-Erling Smørgrav		p_config "total.requestlist.avg" "Average size of queue on insert" "GAUGE"
273b5663de9SDag-Erling Smørgrav		p_config "total.requestlist.max" "Max size of queue (in 5 min)" "GAUGE"
274b5663de9SDag-Erling Smørgrav		p_config "total.requestlist.overwritten" "Number of queries replaced by new ones" "GAUGE"
275b5663de9SDag-Erling Smørgrav		p_config "total.requestlist.exceeded" "Number of queries dropped due to lack of space" "GAUGE"
276b5663de9SDag-Erling Smørgrav		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."
277b5663de9SDag-Erling Smørgrav		;;
278b5663de9SDag-Erling Smørgrav	memory)
279b5663de9SDag-Erling Smørgrav		echo "graph_title Unbound memory usage"
280b5663de9SDag-Erling Smørgrav		echo "graph_args --base 1024 -l 0"
281b5663de9SDag-Erling Smørgrav		echo "graph_vlabel memory used in bytes"
2825469a995SCy Schubert		echo "graph_category dns"
283b5663de9SDag-Erling Smørgrav		p_config "mem.cache.rrset" "RRset cache memory" "GAUGE"
284b5663de9SDag-Erling Smørgrav		p_config "mem.cache.message" "Message cache memory" "GAUGE"
285b5663de9SDag-Erling Smørgrav		p_config "mem.mod.iterator" "Iterator module memory" "GAUGE"
286b5663de9SDag-Erling Smørgrav		p_config "mem.mod.validator" "Validator module and key cache memory" "GAUGE"
287b5663de9SDag-Erling Smørgrav		p_config "msg.cache.count" "msg cache count" "GAUGE"
288b5663de9SDag-Erling Smørgrav		p_config "rrset.cache.count" "rrset cache count" "GAUGE"
289b5663de9SDag-Erling Smørgrav		p_config "infra.cache.count" "infra cache count" "GAUGE"
290b5663de9SDag-Erling Smørgrav		p_config "key.cache.count" "key cache count" "GAUGE"
291b5663de9SDag-Erling Smørgrav		echo "graph_info The memory used by unbound."
292b5663de9SDag-Erling Smørgrav		;;
293b5663de9SDag-Erling Smørgrav	by_type)
294b5663de9SDag-Erling Smørgrav		echo "graph_title Unbound DNS queries by type"
295b5663de9SDag-Erling Smørgrav		echo "graph_args --base 1000 -l 0"
296b5663de9SDag-Erling Smørgrav		echo "graph_vlabel queries / \${graph_period}"
297b5663de9SDag-Erling Smørgrav		echo "graph_scale no"
2985469a995SCy Schubert		echo "graph_category dns"
2995469a995SCy Schubert		for nm in `grep "^num.query.type" $seentags`; do
300b5663de9SDag-Erling Smørgrav			tp=`echo $nm | sed -e s/num.query.type.//`
301b5663de9SDag-Erling Smørgrav			p_config "$nm" "$tp" "ABSOLUTE"
302b5663de9SDag-Erling Smørgrav		done
303b5663de9SDag-Erling Smørgrav		echo "graph_info queries by DNS RR type queried for"
304b5663de9SDag-Erling Smørgrav		;;
305b5663de9SDag-Erling Smørgrav	by_class)
306b5663de9SDag-Erling Smørgrav		echo "graph_title Unbound DNS queries by class"
307b5663de9SDag-Erling Smørgrav		echo "graph_args --base 1000 -l 0"
308b5663de9SDag-Erling Smørgrav		echo "graph_vlabel queries / \${graph_period}"
309b5663de9SDag-Erling Smørgrav		echo "graph_scale no"
3105469a995SCy Schubert		echo "graph_category dns"
3115469a995SCy Schubert		for nm in `grep "^num.query.class" $seentags`; do
312b5663de9SDag-Erling Smørgrav			tp=`echo $nm | sed -e s/num.query.class.//`
313b5663de9SDag-Erling Smørgrav			p_config "$nm" "$tp" "ABSOLUTE"
314b5663de9SDag-Erling Smørgrav		done
315b5663de9SDag-Erling Smørgrav		echo "graph_info queries by DNS RR class queried for."
316b5663de9SDag-Erling Smørgrav		;;
317b5663de9SDag-Erling Smørgrav	by_opcode)
318b5663de9SDag-Erling Smørgrav		echo "graph_title Unbound DNS queries by opcode"
319b5663de9SDag-Erling Smørgrav		echo "graph_args --base 1000 -l 0"
320b5663de9SDag-Erling Smørgrav		echo "graph_vlabel queries / \${graph_period}"
321b5663de9SDag-Erling Smørgrav		echo "graph_scale no"
3225469a995SCy Schubert		echo "graph_category dns"
3235469a995SCy Schubert		for nm in `grep "^num.query.opcode" $seentags`; do
324b5663de9SDag-Erling Smørgrav			tp=`echo $nm | sed -e s/num.query.opcode.//`
325b5663de9SDag-Erling Smørgrav			p_config "$nm" "$tp" "ABSOLUTE"
326b5663de9SDag-Erling Smørgrav		done
327b5663de9SDag-Erling Smørgrav		echo "graph_info queries by opcode in the query packet."
328b5663de9SDag-Erling Smørgrav		;;
329b5663de9SDag-Erling Smørgrav	by_rcode)
330b5663de9SDag-Erling Smørgrav		echo "graph_title Unbound DNS answers by return code"
331b5663de9SDag-Erling Smørgrav		echo "graph_args --base 1000 -l 0"
332b5663de9SDag-Erling Smørgrav		echo "graph_vlabel answer packets / \${graph_period}"
333b5663de9SDag-Erling Smørgrav		echo "graph_scale no"
3345469a995SCy Schubert		echo "graph_category dns"
3355469a995SCy Schubert		for nm in `grep "^num.answer.rcode" $seentags`; do
336b5663de9SDag-Erling Smørgrav			tp=`echo $nm | sed -e s/num.answer.rcode.//`
337b5663de9SDag-Erling Smørgrav			p_config "$nm" "$tp" "ABSOLUTE"
338b5663de9SDag-Erling Smørgrav		done
339b5663de9SDag-Erling Smørgrav		p_config "num.answer.secure" "answer secure" "ABSOLUTE"
340b5663de9SDag-Erling Smørgrav		p_config "num.answer.bogus" "answer bogus" "ABSOLUTE"
341b5663de9SDag-Erling Smørgrav		p_config "num.rrset.bogus" "num rrsets marked bogus" "ABSOLUTE"
342b5663de9SDag-Erling Smørgrav		echo "graph_info answers sorted by return value. rrsets bogus is the number of rrsets marked bogus per \${graph_period} by the validator"
343b5663de9SDag-Erling Smørgrav		;;
344b5663de9SDag-Erling Smørgrav	by_flags)
345b5663de9SDag-Erling Smørgrav		echo "graph_title Unbound DNS incoming queries by flags"
346b5663de9SDag-Erling Smørgrav		echo "graph_args --base 1000 -l 0"
347b5663de9SDag-Erling Smørgrav		echo "graph_vlabel queries / \${graph_period}"
348b5663de9SDag-Erling Smørgrav		echo "graph_scale no"
3495469a995SCy Schubert		echo "graph_category dns"
350b5663de9SDag-Erling Smørgrav		p_config "num.query.flags.QR" "QR (query reply) flag" "ABSOLUTE"
351b5663de9SDag-Erling Smørgrav		p_config "num.query.flags.AA" "AA (auth answer) flag" "ABSOLUTE"
352b5663de9SDag-Erling Smørgrav		p_config "num.query.flags.TC" "TC (truncated) flag" "ABSOLUTE"
353b5663de9SDag-Erling Smørgrav		p_config "num.query.flags.RD" "RD (recursion desired) flag" "ABSOLUTE"
354b5663de9SDag-Erling Smørgrav		p_config "num.query.flags.RA" "RA (rec avail) flag" "ABSOLUTE"
355b5663de9SDag-Erling Smørgrav		p_config "num.query.flags.Z" "Z (zero) flag" "ABSOLUTE"
356b5663de9SDag-Erling Smørgrav		p_config "num.query.flags.AD" "AD (auth data) flag" "ABSOLUTE"
357b5663de9SDag-Erling Smørgrav		p_config "num.query.flags.CD" "CD (check disabled) flag" "ABSOLUTE"
358b5663de9SDag-Erling Smørgrav		p_config "num.query.edns.present" "EDNS OPT present" "ABSOLUTE"
359b5663de9SDag-Erling Smørgrav		p_config "num.query.edns.DO" "DO (DNSSEC OK) flag" "ABSOLUTE"
360b5663de9SDag-Erling Smørgrav		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."
361b5663de9SDag-Erling Smørgrav		;;
362b5663de9SDag-Erling Smørgrav	histogram)
363b5663de9SDag-Erling Smørgrav		echo "graph_title Unbound DNS histogram of reply time"
364b5663de9SDag-Erling Smørgrav		echo "graph_args --base 1000 -l 0"
365b5663de9SDag-Erling Smørgrav		echo "graph_vlabel queries / \${graph_period}"
366b5663de9SDag-Erling Smørgrav		echo "graph_scale no"
3675469a995SCy Schubert		echo "graph_category dns"
368b5663de9SDag-Erling Smørgrav		echo hcache.label "cache hits"
369b5663de9SDag-Erling Smørgrav		echo hcache.min 0
370b5663de9SDag-Erling Smørgrav		echo hcache.type ABSOLUTE
371b5663de9SDag-Erling Smørgrav		echo hcache.draw AREA
372b5663de9SDag-Erling Smørgrav		echo hcache.colour 999999
373b5663de9SDag-Erling Smørgrav		echo h64ms.label "0 msec - 66 msec"
374b5663de9SDag-Erling Smørgrav		echo h64ms.min 0
375b5663de9SDag-Erling Smørgrav		echo h64ms.type ABSOLUTE
376b5663de9SDag-Erling Smørgrav		echo h64ms.draw STACK
377b5663de9SDag-Erling Smørgrav		echo h64ms.colour 0000FF
378b5663de9SDag-Erling Smørgrav		echo h128ms.label "66 msec - 131 msec"
379b5663de9SDag-Erling Smørgrav		echo h128ms.min 0
380b5663de9SDag-Erling Smørgrav		echo h128ms.type ABSOLUTE
381b5663de9SDag-Erling Smørgrav		echo h128ms.colour 1F00DF
382b5663de9SDag-Erling Smørgrav		echo h128ms.draw STACK
383b5663de9SDag-Erling Smørgrav		echo h256ms.label "131 msec - 262 msec"
384b5663de9SDag-Erling Smørgrav		echo h256ms.min 0
385b5663de9SDag-Erling Smørgrav		echo h256ms.type ABSOLUTE
386b5663de9SDag-Erling Smørgrav		echo h256ms.draw STACK
387b5663de9SDag-Erling Smørgrav		echo h256ms.colour 3F00BF
388b5663de9SDag-Erling Smørgrav		echo h512ms.label "262 msec - 524 msec"
389b5663de9SDag-Erling Smørgrav		echo h512ms.min 0
390b5663de9SDag-Erling Smørgrav		echo h512ms.type ABSOLUTE
391b5663de9SDag-Erling Smørgrav		echo h512ms.draw STACK
392b5663de9SDag-Erling Smørgrav		echo h512ms.colour 5F009F
393b5663de9SDag-Erling Smørgrav		echo h1s.label "524 msec - 1 sec"
394b5663de9SDag-Erling Smørgrav		echo h1s.min 0
395b5663de9SDag-Erling Smørgrav		echo h1s.type ABSOLUTE
396b5663de9SDag-Erling Smørgrav		echo h1s.draw STACK
397b5663de9SDag-Erling Smørgrav		echo h1s.colour 7F007F
398b5663de9SDag-Erling Smørgrav		echo h2s.label "1 sec - 2 sec"
399b5663de9SDag-Erling Smørgrav		echo h2s.min 0
400b5663de9SDag-Erling Smørgrav		echo h2s.type ABSOLUTE
401b5663de9SDag-Erling Smørgrav		echo h2s.draw STACK
402b5663de9SDag-Erling Smørgrav		echo h2s.colour 9F005F
403b5663de9SDag-Erling Smørgrav		echo h4s.label "2 sec - 4 sec"
404b5663de9SDag-Erling Smørgrav		echo h4s.min 0
405b5663de9SDag-Erling Smørgrav		echo h4s.type ABSOLUTE
406b5663de9SDag-Erling Smørgrav		echo h4s.draw STACK
407b5663de9SDag-Erling Smørgrav		echo h4s.colour BF003F
408b5663de9SDag-Erling Smørgrav		echo h8s.label "4 sec - 8 sec"
409b5663de9SDag-Erling Smørgrav		echo h8s.min 0
410b5663de9SDag-Erling Smørgrav		echo h8s.type ABSOLUTE
411b5663de9SDag-Erling Smørgrav		echo h8s.draw STACK
412b5663de9SDag-Erling Smørgrav		echo h8s.colour DF001F
413b5663de9SDag-Erling Smørgrav		echo h16s.label "8 sec - ..."
414b5663de9SDag-Erling Smørgrav		echo h16s.min 0
415b5663de9SDag-Erling Smørgrav		echo h16s.type ABSOLUTE
416b5663de9SDag-Erling Smørgrav		echo h16s.draw STACK
417b5663de9SDag-Erling Smørgrav		echo h16s.colour FF0000
418b5663de9SDag-Erling Smørgrav		echo "graph_info Histogram of the reply times for queries."
419b5663de9SDag-Erling Smørgrav		;;
420b5663de9SDag-Erling Smørgrav	esac
421b5663de9SDag-Erling Smørgrav
422b5663de9SDag-Erling Smørgrav	exit 0
423b5663de9SDag-Erling Smørgravfi
424b5663de9SDag-Erling Smørgrav
425b5663de9SDag-Erling Smørgrav# do the stats itself
426b5663de9SDag-Erling Smørgravget_state
427b5663de9SDag-Erling Smørgrav
428b5663de9SDag-Erling Smørgrav# get the time elapsed
429b5663de9SDag-Erling Smørgravget_value "time.elapsed"
430b5663de9SDag-Erling Smørgravif test $value = 0 || test $value = "0.000000"; then
431b5663de9SDag-Erling Smørgrav	echo "error: time elapsed 0 or could not retrieve data"
432b5663de9SDag-Erling Smørgrav	exit 1
433b5663de9SDag-Erling Smørgravfi
434b5663de9SDag-Erling Smørgravelapsed="$value"
435b5663de9SDag-Erling Smørgrav
436b5663de9SDag-Erling Smørgrav# print value for $1
437b5663de9SDag-Erling Smørgravprint_value ( ) {
438b5663de9SDag-Erling Smørgrav	mn=`echo $1 | sed $ABBREV | tr . _`
439b5663de9SDag-Erling Smørgrav	get_value $1
440b5663de9SDag-Erling Smørgrav	echo "$mn.value" $value
441b5663de9SDag-Erling Smørgrav}
442b5663de9SDag-Erling Smørgrav
443b5663de9SDag-Erling Smørgrav# print value if line already found in $2
444b5663de9SDag-Erling Smørgravprint_value_line ( ) {
445b5663de9SDag-Erling Smørgrav	mn=`echo $1 | sed $ABBREV | tr . _`
446b5663de9SDag-Erling Smørgrav	value="`echo $2 | sed -e 's/^.*=//'`"
447b5663de9SDag-Erling Smørgrav	echo "$mn.value" $value
448b5663de9SDag-Erling Smørgrav}
449b5663de9SDag-Erling Smørgrav
450b5663de9SDag-Erling Smørgrav
451b5663de9SDag-Erling Smørgravcase $id in
452b5663de9SDag-Erling Smørgravhits)
453b5663de9SDag-Erling Smørgrav	for x in `grep "^thread[0-9][0-9]*\.num\.queries=" $state |
454b5663de9SDag-Erling Smørgrav		sed -e 's/=.*//'` total.num.queries \
455b5663de9SDag-Erling Smørgrav		total.num.cachehits total.num.prefetch num.query.tcp \
456*0a92a9fcSCy Schubert		num.query.tcpout num.query.udpout num.query.tls num.query.tls.resume \
457091e9e46SCy Schubert		num.query.ipv6 unwanted.queries \
458b5663de9SDag-Erling Smørgrav		unwanted.replies; do
459b5663de9SDag-Erling Smørgrav		if grep "^"$x"=" $state >/dev/null 2>&1; then
460b5663de9SDag-Erling Smørgrav			print_value $x
461b5663de9SDag-Erling Smørgrav		fi
462b5663de9SDag-Erling Smørgrav	done
463b5663de9SDag-Erling Smørgrav	;;
464b5663de9SDag-Erling Smørgravqueue)
465b5663de9SDag-Erling Smørgrav	for x in total.requestlist.avg total.requestlist.max \
466b5663de9SDag-Erling Smørgrav		total.requestlist.overwritten total.requestlist.exceeded; do
467b5663de9SDag-Erling Smørgrav		print_value $x
468b5663de9SDag-Erling Smørgrav	done
469b5663de9SDag-Erling Smørgrav	;;
470b5663de9SDag-Erling Smørgravmemory)
471b5663de9SDag-Erling Smørgrav	for x in mem.cache.rrset mem.cache.message mem.mod.iterator \
472b5663de9SDag-Erling Smørgrav		mem.mod.validator msg.cache.count rrset.cache.count \
473b5663de9SDag-Erling Smørgrav		infra.cache.count key.cache.count; do
474b5663de9SDag-Erling Smørgrav		print_value $x
475b5663de9SDag-Erling Smørgrav	done
476b5663de9SDag-Erling Smørgrav	;;
477b5663de9SDag-Erling Smørgravby_type)
4785469a995SCy Schubert	for nm in `grep "^num.query.type" $seentags`; do
4795469a995SCy Schubert		print_value $nm
480b5663de9SDag-Erling Smørgrav	done
481b5663de9SDag-Erling Smørgrav	;;
482b5663de9SDag-Erling Smørgravby_class)
4835469a995SCy Schubert	for nm in `grep "^num.query.class" $seentags`; do
4845469a995SCy Schubert		print_value $nm
485b5663de9SDag-Erling Smørgrav	done
486b5663de9SDag-Erling Smørgrav	;;
487b5663de9SDag-Erling Smørgravby_opcode)
4885469a995SCy Schubert	for nm in `grep "^num.query.opcode" $seentags`; do
4895469a995SCy Schubert		print_value $nm
490b5663de9SDag-Erling Smørgrav	done
491b5663de9SDag-Erling Smørgrav	;;
492b5663de9SDag-Erling Smørgravby_rcode)
4935469a995SCy Schubert	for nm in `grep "^num.answer.rcode" $seentags`; do
4945469a995SCy Schubert		print_value $nm
495b5663de9SDag-Erling Smørgrav	done
496b5663de9SDag-Erling Smørgrav	print_value "num.answer.secure"
497b5663de9SDag-Erling Smørgrav	print_value "num.answer.bogus"
498b5663de9SDag-Erling Smørgrav	print_value "num.rrset.bogus"
499b5663de9SDag-Erling Smørgrav	;;
500b5663de9SDag-Erling Smørgravby_flags)
501b5663de9SDag-Erling Smørgrav	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
502b5663de9SDag-Erling Smørgrav		print_value $x
503b5663de9SDag-Erling Smørgrav	done
504b5663de9SDag-Erling Smørgrav	;;
505b5663de9SDag-Erling Smørgravhistogram)
506b5663de9SDag-Erling Smørgrav	get_value total.num.cachehits
507b5663de9SDag-Erling Smørgrav	echo hcache.value $value
508b5663de9SDag-Erling Smørgrav	r=0
509b5663de9SDag-Erling Smørgrav	for x in histogram.000000.000000.to.000000.000001 \
510b5663de9SDag-Erling Smørgrav		histogram.000000.000001.to.000000.000002 \
511b5663de9SDag-Erling Smørgrav		histogram.000000.000002.to.000000.000004 \
512b5663de9SDag-Erling Smørgrav		histogram.000000.000004.to.000000.000008 \
513b5663de9SDag-Erling Smørgrav		histogram.000000.000008.to.000000.000016 \
514b5663de9SDag-Erling Smørgrav		histogram.000000.000016.to.000000.000032 \
515b5663de9SDag-Erling Smørgrav		histogram.000000.000032.to.000000.000064 \
516b5663de9SDag-Erling Smørgrav		histogram.000000.000064.to.000000.000128 \
517b5663de9SDag-Erling Smørgrav		histogram.000000.000128.to.000000.000256 \
518b5663de9SDag-Erling Smørgrav		histogram.000000.000256.to.000000.000512 \
519b5663de9SDag-Erling Smørgrav		histogram.000000.000512.to.000000.001024 \
520b5663de9SDag-Erling Smørgrav		histogram.000000.001024.to.000000.002048 \
521b5663de9SDag-Erling Smørgrav		histogram.000000.002048.to.000000.004096 \
522b5663de9SDag-Erling Smørgrav		histogram.000000.004096.to.000000.008192 \
523b5663de9SDag-Erling Smørgrav		histogram.000000.008192.to.000000.016384 \
524b5663de9SDag-Erling Smørgrav		histogram.000000.016384.to.000000.032768 \
525b5663de9SDag-Erling Smørgrav		histogram.000000.032768.to.000000.065536; do
526b5663de9SDag-Erling Smørgrav		get_value $x
527b5663de9SDag-Erling Smørgrav		r=`expr $r + $value`
528b5663de9SDag-Erling Smørgrav	done
529b5663de9SDag-Erling Smørgrav	echo h64ms.value $r
530b5663de9SDag-Erling Smørgrav	get_value histogram.000000.065536.to.000000.131072
531b5663de9SDag-Erling Smørgrav	echo h128ms.value $value
532b5663de9SDag-Erling Smørgrav	get_value histogram.000000.131072.to.000000.262144
533b5663de9SDag-Erling Smørgrav	echo h256ms.value $value
534b5663de9SDag-Erling Smørgrav	get_value histogram.000000.262144.to.000000.524288
535b5663de9SDag-Erling Smørgrav	echo h512ms.value $value
536b5663de9SDag-Erling Smørgrav	get_value histogram.000000.524288.to.000001.000000
537b5663de9SDag-Erling Smørgrav	echo h1s.value $value
538b5663de9SDag-Erling Smørgrav	get_value histogram.000001.000000.to.000002.000000
539b5663de9SDag-Erling Smørgrav	echo h2s.value $value
540b5663de9SDag-Erling Smørgrav	get_value histogram.000002.000000.to.000004.000000
541b5663de9SDag-Erling Smørgrav	echo h4s.value $value
542b5663de9SDag-Erling Smørgrav	get_value histogram.000004.000000.to.000008.000000
543b5663de9SDag-Erling Smørgrav	echo h8s.value $value
544b5663de9SDag-Erling Smørgrav	r=0
545b5663de9SDag-Erling Smørgrav	for x in histogram.000008.000000.to.000016.000000 \
546b5663de9SDag-Erling Smørgrav		histogram.000016.000000.to.000032.000000 \
547b5663de9SDag-Erling Smørgrav		histogram.000032.000000.to.000064.000000 \
548b5663de9SDag-Erling Smørgrav		histogram.000064.000000.to.000128.000000 \
549b5663de9SDag-Erling Smørgrav		histogram.000128.000000.to.000256.000000 \
550b5663de9SDag-Erling Smørgrav		histogram.000256.000000.to.000512.000000 \
551b5663de9SDag-Erling Smørgrav		histogram.000512.000000.to.001024.000000 \
552b5663de9SDag-Erling Smørgrav		histogram.001024.000000.to.002048.000000 \
553b5663de9SDag-Erling Smørgrav		histogram.002048.000000.to.004096.000000 \
554b5663de9SDag-Erling Smørgrav		histogram.004096.000000.to.008192.000000 \
555b5663de9SDag-Erling Smørgrav		histogram.008192.000000.to.016384.000000 \
556b5663de9SDag-Erling Smørgrav		histogram.016384.000000.to.032768.000000 \
557b5663de9SDag-Erling Smørgrav		histogram.032768.000000.to.065536.000000 \
558b5663de9SDag-Erling Smørgrav		histogram.065536.000000.to.131072.000000 \
559b5663de9SDag-Erling Smørgrav		histogram.131072.000000.to.262144.000000 \
560b5663de9SDag-Erling Smørgrav		histogram.262144.000000.to.524288.000000; do
561b5663de9SDag-Erling Smørgrav		get_value $x
562b5663de9SDag-Erling Smørgrav		r=`expr $r + $value`
563b5663de9SDag-Erling Smørgrav	done
564b5663de9SDag-Erling Smørgrav	echo h16s.value $r
565b5663de9SDag-Erling Smørgrav	;;
566b5663de9SDag-Erling Smørgravesac
567