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