1368464Scy# read output of unbound-control stats
2368464Scy# and output prometheus metrics style output.
3368464Scy# use these options:
4368464Scy#	server:		extended-statistics: yes
5368464Scy#			statistics-cumulative: no
6368464Scy#			statistics-interval: 0
7368464Scy#	remote-control: control-enable: yes
8368464Scy# Can use it like unbound-control stats | awk -f "metrics.awk"
9368464Scy
10368464ScyBEGIN {
11368464Scy	FS="=";
12368464Scy}
13368464Scy# everything like total.num.queries=value is put in val["total.num.queries"]
14368464Scy/^.*\..*=/ {
15368464Scy	val[$1]=$2;
16368464Scy}
17368464Scy# print the output metrics
18368464ScyEND {
19368464Scy	print "# HELP unbound_hits_queries Unbound DNS traffic and cache hits"
20368464Scy	print "# TYPE unbound_hits_queries gauge"
21368464Scy	print "unbound_hits_queries{type=\"total.num.queries\"} " val["total.num.queries"];
22368464Scy	for (x=0; x<99; x++) {
23368464Scy		if(val["thread" $x ".num.queries"] != "") {
24368464Scy			print "unbound_hits_queries{type=\"thread" $x ".num.queries\"} " val["thread" $x ".num.queries"];
25368464Scy		}
26368464Scy	}
27368464Scy	print "unbound_hits_queries{type=\"total.num.cachehits\"} " val["total.num.cachehits"];
28368464Scy	print "unbound_hits_queries{type=\"total.num.prefetch\"} " val["total.num.prefetch"];
29368464Scy	print "unbound_hits_queries{type=\"num.query.tcp\"} " val["num.query.tcp"];
30368464Scy	print "unbound_hits_queries{type=\"num.query.tcpout\"} " val["num.query.tcpout"];
31368464Scy	print "unbound_hits_queries{type=\"num.query.tls\"} " val["num.query.tls"];
32368464Scy	print "unbound_hits_queries{type=\"num.query.tls.resume\"} " val["num.query.tls.resume"];
33368464Scy	print "unbound_hits_queries{type=\"num.query.ipv6\"} " val["num.query.ipv6"];
34368464Scy	print "unbound_hits_queries{type=\"unwanted.queries\"} " val["unwanted.queries"];
35368464Scy	print ""
36368464Scy
37368464Scy	print "# HELP unbound_queue_queries Unbound requestlist size"
38368464Scy	print "# TYPE unbound_queue_queries gauge"
39368464Scy	print "unbound_queue_queries{type=\"total.requestlist.avg\"} " val["total.requestlist.avg"];
40368464Scy	print "unbound_queue_queries{type=\"total.requestlist.max\"} " val["total.requestlist.max"];
41368464Scy	print "unbound_queue_queries{type=\"total.requestlist.overwritten\"} " val["total.requestlist.overwritten"];
42368464Scy	print "unbound_queue_queries{type=\"total.requestlist.exceeded\"} " val["total.requestlist.exceeded"];
43368464Scy	print ""
44368464Scy
45368464Scy	print "# HELP unbound_memory_bytes Unbound memory usage"
46368464Scy	print "# TYPE unbound_memory_bytes gauge"
47368464Scy	print "unbound_memory_bytes{type=\"mem.cache.rrset\"} " val["mem.cache.rrset"];
48368464Scy	print "unbound_memory_bytes{type=\"mem.cache.message\"} " val["mem.cache.message"];
49368464Scy	print "unbound_memory_bytes{type=\"mem.mod.iterator\"} " val["mem.mod.iterator"];
50368464Scy	if(val["mem.mod.validator"] != "") {
51368464Scy		print "unbound_memory_bytes{type=\"mem.mod.validator\"} " val["mem.mod.validator"];
52368464Scy	}
53368464Scy	if(val["mem.mod.respip"] != "") {
54368464Scy		print "unbound_memory_bytes{type=\"mem.mod.respip\"} " val["mem.mod.respip"];
55368464Scy	}
56368464Scy	if(val["mem.mod.subnet"] != "") {
57368464Scy		print "unbound_memory_bytes{type=\"mem.mod.subnet\"} " val["mem.mod.subnet"];
58368464Scy	}
59368464Scy	if(val["mem.mod.ipsecmod"] != "") {
60368464Scy		print "unbound_memory_bytes{type=\"mem.mod.ipsecmod\"} " val["mem.mod.ipsecmod"];
61368464Scy	}
62368464Scy	if(val["mem.mod.dynlibmod"] != "") {
63368464Scy		print "unbound_memory_bytes{type=\"mem.mod.dynlibmod\"} " val["mem.mod.dynlibmod"];
64368464Scy	}
65368464Scy	print "unbound_memory_bytes{type=\"msg.cache.count\"} " val["msg.cache.count"];
66368464Scy	print "unbound_memory_bytes{type=\"rrset.cache.count\"} " val["rrset.cache.count"];
67368464Scy	print "unbound_memory_bytes{type=\"infra.cache.count\"} " val["infra.cache.count"];
68368464Scy	print "unbound_memory_bytes{type=\"key.cache.count\"} " val["key.cache.count"];
69368464Scy	print ""
70368464Scy
71368464Scy	print "# HELP unbound_by_type_queries Unbound DNS queries by type"
72368464Scy	print "# TYPE unbound_by_type_queries gauge"
73368464Scy	for(x in val) {
74368464Scy		if(x ~ /^num.query.type./) {
75368464Scy			if(val[x] != "") {
76368464Scy				split(x, a, ".");
77368464Scy				print "unbound_by_type_queries{type=\"" a[4] "\"} " val[x];
78368464Scy			}
79368464Scy		}
80368464Scy	}
81368464Scy	print ""
82368464Scy
83368464Scy	print "# HELP unbound_by_class_queries Unbound DNS queries by class"
84368464Scy	print "# TYPE unbound_by_class_queries gauge"
85368464Scy	for(x in val) {
86368464Scy		if(x ~ /^num.query.class./) {
87368464Scy			if(val[x] != "") {
88368464Scy				split(x, a, ".");
89368464Scy				print "unbound_by_class_queries{class=\"" a[4] "\"} " val[x];
90368464Scy			}
91368464Scy		}
92368464Scy	}
93368464Scy	print ""
94368464Scy
95368464Scy	print "# HELP unbound_by_opcode_queries Unbound DNS queries by opcode"
96368464Scy	print "# TYPE unbound_by_opcode_queries gauge"
97368464Scy	for(x in val) {
98368464Scy		if(x ~ /^num.query.opcode./) {
99368464Scy			if(val[x] != "") {
100368464Scy				split(x, a, ".");
101368464Scy				print "unbound_by_opcode_queries{opcode=\"" a[4] "\"} " val[x];
102368464Scy			}
103368464Scy		}
104368464Scy	}
105368464Scy	print ""
106368464Scy
107368464Scy	print "# HELP unbound_by_rcode_queries Unbound DNS answers by rcode"
108368464Scy	print "# TYPE unbound_by_rcode_queries gauge"
109368464Scy	for(x in val) {
110368464Scy		if(x ~ /^num.answer.rcode./) {
111368464Scy			if(val[x] != "") {
112368464Scy				split(x, a, ".");
113368464Scy				print "unbound_by_rcode_queries{rcode=\"" a[4] "\"} " val[x];
114368464Scy			}
115368464Scy		}
116368464Scy	}
117368464Scy	print ""
118368464Scy
119368464Scy	print "# HELP unbound_by_flags_queries Unbound DNS queries by flags"
120368464Scy	print "# TYPE unbound_by_flags_queries gauge"
121368464Scy	for(x in val) {
122368464Scy		if(x ~ /^num.query.flags./) {
123368464Scy			if(val[x] != "") {
124368464Scy				split(x, a, ".");
125368464Scy				print "unbound_by_flags_queries{flag=\"" a[4] "\"} " val[x];
126368464Scy			}
127368464Scy		}
128368464Scy	}
129368464Scy	if(val["num.query.edns.present"] != "") {
130368464Scy		print "unbound_by_flags_queries{flag=\"num.query.edns.present\"} " val["num.query.edns.present"];
131368464Scy	}
132368464Scy	if(val["num.query.edns.DO"] != "") {
133368464Scy		print "unbound_by_flags_queries{flag=\"num.query.edns.DO\"} " val["num.query.edns.DO"];
134368464Scy	}
135368464Scy	print ""
136368464Scy
137368464Scy	print "# HELP unbound_histogram_seconds Unbound DNS histogram of reply time"
138368464Scy	print "# TYPE unbound_histogram_seconds gauge"
139368464Scy	print "unbound_histogram_seconds{bucket=\"000000.000000.to.000000.000001\"} " val["histogram.000000.000000.to.000000.000001"];
140368464Scy	print "unbound_histogram_seconds{bucket=\"000000.000001.to.000000.000002\"} " val["histogram.000000.000001.to.000000.000002"];
141368464Scy	print "unbound_histogram_seconds{bucket=\"000000.000002.to.000000.000004\"} " val["histogram.000000.000002.to.000000.000004"];
142368464Scy	print "unbound_histogram_seconds{bucket=\"000000.000004.to.000000.000008\"} " val["histogram.000000.000004.to.000000.000008"];
143368464Scy	print "unbound_histogram_seconds{bucket=\"000000.000008.to.000000.000016\"} " val["histogram.000000.000008.to.000000.000016"];
144368464Scy	print "unbound_histogram_seconds{bucket=\"000000.000016.to.000000.000032\"} " val["histogram.000000.000016.to.000000.000032"];
145368464Scy	print "unbound_histogram_seconds{bucket=\"000000.000032.to.000000.000064\"} " val["histogram.000000.000032.to.000000.000064"];
146368464Scy	print "unbound_histogram_seconds{bucket=\"000000.000064.to.000000.000128\"} " val["histogram.000000.000064.to.000000.000128"];
147368464Scy	print "unbound_histogram_seconds{bucket=\"000000.000128.to.000000.000256\"} " val["histogram.000000.000128.to.000000.000256"];
148368464Scy	print "unbound_histogram_seconds{bucket=\"000000.000256.to.000000.000512\"} " val["histogram.000000.000256.to.000000.000512"];
149368464Scy	print "unbound_histogram_seconds{bucket=\"000000.000512.to.000000.001024\"} " val["histogram.000000.000512.to.000000.001024"];
150368464Scy	print "unbound_histogram_seconds{bucket=\"000000.001024.to.000000.002048\"} " val["histogram.000000.001024.to.000000.002048"];
151368464Scy	print "unbound_histogram_seconds{bucket=\"000000.002048.to.000000.004096\"} " val["histogram.000000.002048.to.000000.004096"];
152368464Scy	print "unbound_histogram_seconds{bucket=\"000000.004096.to.000000.008192\"} " val["histogram.000000.004096.to.000000.008192"];
153368464Scy	print "unbound_histogram_seconds{bucket=\"000000.008192.to.000000.016384\"} " val["histogram.000000.008192.to.000000.016384"];
154368464Scy	print "unbound_histogram_seconds{bucket=\"000000.016384.to.000000.032768\"} " val["histogram.000000.016384.to.000000.032768"];
155368464Scy	print "unbound_histogram_seconds{bucket=\"000000.032768.to.000000.065536\"} " val["histogram.000000.032768.to.000000.065536"];
156368464Scy	print "unbound_histogram_seconds{bucket=\"000000.065536.to.000000.131072\"} " val["histogram.000000.065536.to.000000.131072"];
157368464Scy	print "unbound_histogram_seconds{bucket=\"000000.131072.to.000000.262144\"} " val["histogram.000000.131072.to.000000.262144"];
158368464Scy	print "unbound_histogram_seconds{bucket=\"000000.262144.to.000000.524288\"} " val["histogram.000000.262144.to.000000.524288"];
159368464Scy	print "unbound_histogram_seconds{bucket=\"000000.524288.to.000001.000000\"} " val["histogram.000000.524288.to.000001.000000"];
160368464Scy	print "unbound_histogram_seconds{bucket=\"000001.000000.to.000002.000000\"} " val["histogram.000001.000000.to.000002.000000"];
161368464Scy	print "unbound_histogram_seconds{bucket=\"000002.000000.to.000004.000000\"} " val["histogram.000002.000000.to.000004.000000"];
162368464Scy	print "unbound_histogram_seconds{bucket=\"000004.000000.to.000008.000000\"} " val["histogram.000004.000000.to.000008.000000"];
163368464Scy	print "unbound_histogram_seconds{bucket=\"000008.000000.to.000016.000000\"} " val["histogram.000008.000000.to.000016.000000"];
164368464Scy	print "unbound_histogram_seconds{bucket=\"000016.000000.to.000032.000000\"} " val["histogram.000016.000000.to.000032.000000"];
165368464Scy	print "unbound_histogram_seconds{bucket=\"000032.000000.to.000064.000000\"} " val["histogram.000032.000000.to.000064.000000"];
166368464Scy	print "unbound_histogram_seconds{bucket=\"000064.000000.to.000128.000000\"} " val["histogram.000064.000000.to.000128.000000"];
167368464Scy	print "unbound_histogram_seconds{bucket=\"000128.000000.to.000256.000000\"} " val["histogram.000128.000000.to.000256.000000"];
168368464Scy	print "unbound_histogram_seconds{bucket=\"000256.000000.to.000512.000000\"} " val["histogram.000256.000000.to.000512.000000"];
169368464Scy	print "unbound_histogram_seconds{bucket=\"000512.000000.to.001024.000000\"} " val["histogram.000512.000000.to.001024.000000"];
170368464Scy	print "unbound_histogram_seconds{bucket=\"001024.000000.to.002048.000000\"} " val["histogram.001024.000000.to.002048.000000"];
171368464Scy	print "unbound_histogram_seconds{bucket=\"002048.000000.to.004096.000000\"} " val["histogram.002048.000000.to.004096.000000"];
172368464Scy	print "unbound_histogram_seconds{bucket=\"004096.000000.to.008192.000000\"} " val["histogram.004096.000000.to.008192.000000"];
173368464Scy	print "unbound_histogram_seconds{bucket=\"008192.000000.to.016384.000000\"} " val["histogram.008192.000000.to.016384.000000"];
174368464Scy	print "unbound_histogram_seconds{bucket=\"016384.000000.to.032768.000000\"} " val["histogram.016384.000000.to.032768.000000"];
175368464Scy	print "unbound_histogram_seconds{bucket=\"032768.000000.to.065536.000000\"} " val["histogram.032768.000000.to.065536.000000"];
176368464Scy	print "unbound_histogram_seconds{bucket=\"065536.000000.to.131072.000000\"} " val["histogram.065536.000000.to.131072.000000"];
177368464Scy	print "unbound_histogram_seconds{bucket=\"131072.000000.to.262144.000000\"} " val["histogram.131072.000000.to.262144.000000"];
178368464Scy	print "unbound_histogram_seconds{bucket=\"262144.000000.to.524288.000000\"} " val["histogram.262144.000000.to.524288.000000"];
179368464Scy	print ""
180368464Scy}
181