@cryptotaxi247 / netdata-1 / commits / d2e64e6dc

Multiple fixes:

* Improved readability regarding cahrt information generation. * Updated chart ordering to make it consistent between global and per-thread charts. * Updated dimension and family names to not have spaces and use all lowercase. * Changed to using a local copy of STAT_MAP to allow things to work with multiple jobs correctly.

Austin S. Hemmelgarn committed Jun 7, 2018 at 11:20 UTC d2e64e6dc0a91d8b2e695a99a3ac842cd87db4ae
1 file changed +91 -78
python.d/unbound.chart.py
+91 -78
@@ -12,36 +12,36 @@ from bases.loaders import YamlOrderedLoader
12
13 PRECISION = 1000
14
15 -ORDER = ['queries', 'reqlist', 'recursion']
15 +ORDER = ['queries', 'recursion', 'reqlist']
16
17 CHARTS = {
18 'queries': {
19 'options': [None, 'Queries Processed', 'queries', 'Unbound', 'unbound.queries', 'line'],
20 'lines': [
21 - ['ratelimit', 'Ratelimited', 'absolute', 1, 1],
22 - ['cachemiss', 'Cache Miss', 'absolute', 1, 1],
23 - ['cachehit', 'Cache Hit', 'absolute', 1, 1],
24 - ['expired', 'Expired', 'absolute', 1, 1],
25 - ['prefetch', 'Prefetched', 'absolute', 1, 1],
26 - ['recursive', 'Recursive', 'absolute', 1, 1]
21 + ['ratelimit', 'ratelimited', 'absolute', 1, 1],
22 + ['cachemiss', 'cache_miss', 'absolute', 1, 1],
23 + ['cachehit', 'cache_hit', 'absolute', 1, 1],
24 + ['expired', 'expired', 'absolute', 1, 1],
25 + ['prefetch', 'prefetched', 'absolute', 1, 1],
26 + ['recursive', 'recursive', 'absolute', 1, 1]
27 ]
28 },
29 - 'reqlist': {
30 - 'options': [None, 'Request List', 'items', 'Unbound', 'unbound.reqlist', 'line'],
29 + 'recursion': {
30 + 'options': [None, 'Recursion Timings', 'seconds', 'Unbound', 'unbound.recursion', 'line'],
31 'lines': [
32 - ['reqlist_avg', 'Average Size', 'absolute', 1, 1],
33 - ['reqlist_max', 'Maximum Size', 'absolute', 1, 1],
34 - ['reqlist_overwritten', 'Overwritten Requests', 'absolute', 1, 1],
35 - ['reqlist_exceeded', 'Overruns', 'absolute', 1, 1],
36 - ['reqlist_current', 'Current Size', 'absolute', 1, 1],
37 - ['reqlist_user', 'User Requests', 'absolute', 1, 1]
32 + ['recursive_avg', 'average', 'absolute', 1, PRECISION],
33 + ['recursive_med', 'median', 'absolute', 1, PRECISION]
34 ]
35 },
40 - 'recursion': {
41 - 'options': [None, 'Recursion Timings', 'seconds', 'Unbound', 'unbound.recursion', 'line'],
36 + 'reqlist': {
37 + 'options': [None, 'Request List', 'items', 'Unbound', 'unbound.reqlist', 'line'],
38 'lines': [
43 - ['recursive_avg', 'Average', 'absolute', 1, PRECISION],
44 - ['recursive_med', 'Median', 'absolute', 1, PRECISION]
39 + ['reqlist_avg', 'average_size', 'absolute', 1, 1],
40 + ['reqlist_max', 'maximum_size', 'absolute', 1, 1],
41 + ['reqlist_overwritten', 'overwritten_requests', 'absolute', 1, 1],
42 + ['reqlist_exceeded', 'overruns', 'absolute', 1, 1],
43 + ['reqlist_current', 'current_size', 'absolute', 1, 1],
44 + ['reqlist_user', 'user_requests', 'absolute', 1, 1]
45 ]
46 }
47 }
@@ -53,12 +53,12 @@ EXTENDED_CHARTS = {
53 'cache': {
54 'options': [None, 'Cache Sizes', 'items', 'Unbound', 'unbound.cache', 'stacked'],
55 'lines': [
56 - ['cache_message', 'Message Cache', 'absolute', 1, 1],
57 - ['cache_rrset', 'RRSet Cache', 'absolute', 1, 1],
58 - ['cache_infra', 'Infra Cache', 'absolute', 1, 1],
59 - ['cache_key', 'DNSSEC Key Cache', 'absolute', 1, 1],
60 - ['cache_dnscss', 'DNSCrypt Shared Secret Cache', 'absolute', 1, 1],
61 - ['cache_dnscn', 'DNSCrypt Nonce Cache', 'absolute', 1, 1]
56 + ['cache_message', 'message_cache', 'absolute', 1, 1],
57 + ['cache_rrset', 'rrset_cache', 'absolute', 1, 1],
58 + ['cache_infra', 'infra_cache', 'absolute', 1, 1],
59 + ['cache_key', 'dnssec_key_cache', 'absolute', 1, 1],
60 + ['cache_dnscss', 'dnscrypt_Shared_Secret_cache', 'absolute', 1, 1],
61 + ['cache_dnscn', 'dnscrypt_Nonce_cache', 'absolute', 1, 1]
62 ]
63 }
64 }
@@ -66,32 +66,32 @@ EXTENDED_CHARTS = {
66 # This is used as a templates for the per-thread charts.
67 PER_THREAD_CHARTS = {
68 '_queries': {
69 - 'options': [None, '{0} Queries Processed', 'queries', 'Queries Processed', 'unbound.threads.queries', 'line'],
69 + 'options': [None, '{longname} Queries Processed', 'queries', 'Queries Processed', 'unbound.threads.queries', 'line'],
70 'lines': [
71 - ['{0}_ratelimit', 'Ratelimited', 'absolute', 1, 1],
72 - ['{0}_cachemiss', 'Cache Miss', 'absolute', 1, 1],
73 - ['{0}_cachehit', 'Cache Hit', 'absolute', 1, 1],
74 - ['{0}_expired', 'Expired', 'absolute', 1, 1],
75 - ['{0}_prefetch', 'Prefetched', 'absolute', 1, 1],
76 - ['{0}_recursive', 'Recursive', 'absolute', 1, 1]
71 + ['{shortname}_ratelimit', 'ratelimited', 'absolute', 1, 1],
72 + ['{shortname}_cachemiss', 'cache_miss', 'absolute', 1, 1],
73 + ['{shortname}_cachehit', 'cache_hit', 'absolute', 1, 1],
74 + ['{shortname}_expired', 'expired', 'absolute', 1, 1],
75 + ['{shortname}_prefetch', 'prefetched', 'absolute', 1, 1],
76 + ['{shortname}_recursive', 'recursive', 'absolute', 1, 1]
77 ]
78 },
79 - '_reqlist': {
80 - 'options': [None, '{0} Request List', 'items', 'Request List', 'unbound.threads.reqlist', 'line'],
79 + '_recursion': {
80 + 'options': [None, '{longname} Recursion Timings', 'seconds', 'Recursive Timings', 'unbound.threads.recursion', 'line'],
81 'lines': [
82 - ['{0}_reqlist_avg', 'Average Size', 'absolute', 1, 1],
83 - ['{0}_reqlist_max', 'Maximum Size', 'absolute', 1, 1],
84 - ['{0}_reqlist_overwritten', 'Overwritten Requests', 'absolute', 1, 1],
85 - ['{0}_reqlist_exceeded', 'Overruns', 'absolute', 1, 1],
86 - ['{0}_reqlist_current', 'Current Size', 'absolute', 1, 1],
87 - ['{0}_reqlist_user', 'User Requests', 'absolute', 1, 1]
82 + ['{shortname}_recursive_avg', 'average', 'absolute', 1, PRECISION],
83 + ['{shortname}_recursive_med', 'median', 'absolute', 1, PRECISION]
84 ]
85 },
90 - '_recursion': {
91 - 'options': [None, '{0} Recursion Timings', 'seconds', 'Recursive Timings', 'unbound.threads.recursion', 'line'],
86 + '_reqlist': {
87 + 'options': [None, '{longname} Request List', 'items', 'Request List', 'unbound.threads.reqlist', 'line'],
88 'lines': [
93 - ['{0}_recursive_avg', 'Average', 'absolute', 1, PRECISION],
94 - ['{0}_recursive_med', 'Median', 'absolute', 1, PRECISION]
89 + ['{shortname}_reqlist_avg', 'average_size', 'absolute', 1, 1],
90 + ['{shortname}_reqlist_max', 'maximum_size', 'absolute', 1, 1],
91 + ['{shortname}_reqlist_overwritten', 'overwritten_requests', 'absolute', 1, 1],
92 + ['{shortname}_reqlist_exceeded', 'overruns', 'absolute', 1, 1],
93 + ['{shortname}_reqlist_current', 'current_size', 'absolute', 1, 1],
94 + ['{shortname}_reqlist_user', 'user_requests', 'absolute', 1, 1]
95 ]
96 }
97 }
@@ -123,23 +123,48 @@ STAT_MAP = {
123
124 # Same as above, but for per-thread stats.
125 PER_THREAD_STAT_MAP = {
126 - '{0}.num.queries_ip_ratelimited': ('{0}_ratelimit', 1),
127 - '{0}.num.cachehits': ('{0}_cachehit', 1),
128 - '{0}.num.cachemiss': ('{0}_cachemiss', 1),
129 - '{0}.num.zero_ttl': ('{0}_expired', 1),
130 - '{0}.num.prefetch': ('{0}_prefetch', 1),
131 - '{0}.num.recursivereplies': ('{0}_recursive', 1),
132 - '{0}.requestlist.avg': ('{0}_reqlist_avg', 1),
133 - '{0}.requestlist.max': ('{0}_reqlist_max', 1),
134 - '{0}.requestlist.overwritten': ('{0}_reqlist_overwritten', 1),
135 - '{0}.requestlist.exceeded': ('{0}_reqlist_exceeded', 1),
136 - '{0}.requestlist.current.all': ('{0}_reqlist_current', 1),
137 - '{0}.requestlist.current.user': ('{0}_reqlist_user', 1),
138 - '{0}.recursion.time.avg': ('{0}_recursive_avg', PRECISION),
139 - '{0}.recursion.time.median': ('{0}_recursive_med', PRECISION)
126 + '{shortname}.num.queries_ip_ratelimited': ('{shortname}_ratelimit', 1),
127 + '{shortname}.num.cachehits': ('{shortname}_cachehit', 1),
128 + '{shortname}.num.cachemiss': ('{shortname}_cachemiss', 1),
129 + '{shortname}.num.zero_ttl': ('{shortname}_expired', 1),
130 + '{shortname}.num.prefetch': ('{shortname}_prefetch', 1),
131 + '{shortname}.num.recursivereplies': ('{shortname}_recursive', 1),
132 + '{shortname}.requestlist.avg': ('{shortname}_reqlist_avg', 1),
133 + '{shortname}.requestlist.max': ('{shortname}_reqlist_max', 1),
134 + '{shortname}.requestlist.overwritten': ('{shortname}_reqlist_overwritten', 1),
135 + '{shortname}.requestlist.exceeded': ('{shortname}_reqlist_exceeded', 1),
136 + '{shortname}.requestlist.current.all': ('{shortname}_reqlist_current', 1),
137 + '{shortname}.requestlist.current.user': ('{shortname}_reqlist_user', 1),
138 + '{shortname}.recursion.time.avg': ('{shortname}_recursive_avg', PRECISION),
139 + '{shortname}.recursion.time.median': ('{shortname}_recursive_med', PRECISION)
140 }
141
142
143 +# Used to actually generate per-thread charts.
144 +def _get_perthread_info(thread):
145 + sname = 'thread{0}'.format(thread)
146 + lname = 'Thread {0}'.format(thread)
147 + charts = dict()
148 + order = []
149 + statmap = dict()
150 +
151 + for item in PER_THREAD_CHARTS:
152 + cname = '{0}{1}'.format(sname, item)
153 + chart = deepcopy(PER_THREAD_CHARTS[item])
154 + chart['options'][1] = chart['options'][1].format(longname=lname)
155 +
156 + for index, line in enumerate(chart['lines']):
157 + chart['lines'][index][0] = line[0].format(shortname=sname)
158 +
159 + order.append(cname)
160 + charts[cname] = chart
161 +
162 + for key, value in PER_THREAD_STAT_MAP.items():
163 + statmap[key.format(shortname=sname)] = (value[0].format(shortname=sname), value[1])
164 +
165 + return (charts, order, statmap)
166 +
167 +
168 class Service(SocketService):
169 def __init__(self, configuration=None, name=None):
170 # The unbound control protocol is always TLS encapsulated
@@ -155,6 +180,7 @@ class Service(SocketService):
180 self.order = deepcopy(ORDER)
181 self.definitions = deepcopy(CHARTS)
182 self.request = 'UBCT1 stats\n'
183 + self.statmap = deepcopy(STAT_MAP)
184 self._parse_config()
185 self._auto_config()
186 self.debug('Extended stats: {0}'.format(self.ext))
@@ -193,26 +219,13 @@ class Service(SocketService):
219 self.port = 8953
220
221 def _generate_perthread_charts(self):
196 - # TODO: THis could probably be more efficient, but it's only
197 - # run once, so it probably doesn't really matter.
222 + tmporder = list()
223 for thread in range(0, self.threads):
199 - shortname = 'thread{0}'.format(thread)
200 - longname = 'Thread {0}'.format(thread)
201 - charts = dict()
202 - order = [[], [], []]
203 - count = 0
204 - for item in PER_THREAD_CHARTS:
205 - chartname = '{0}{1}'.format(shortname, item)
206 - order[count].append(chartname)
207 - count += 1
208 - charts[chartname] = deepcopy(PER_THREAD_CHARTS[item])
209 - charts[chartname]['options'][1] = charts[chartname]['options'][1].format(longname)
210 - for line in range(0, len(charts[chartname]['lines'])):
211 - charts[chartname]['lines'][line][0] = charts[chartname]['lines'][line][0].format(shortname)
212 - self.order = self.order + order[0] + order[1] + order[2]
224 + charts, order, statmap = _get_perthread_info(thread)
225 + tmporder.extend(order)
226 self.definitions.update(charts)
214 - for key, value in PER_THREAD_STAT_MAP.items():
215 - STAT_MAP[key.format(shortname)] = (value[0].format(shortname), value[1])
227 + self.statmap.update(statmap)
228 + self.order.extend(sorted(tmporder))
229
230 def check(self):
231 # Check if authentication is working.
@@ -253,7 +266,7 @@ class Service(SocketService):
266 for line in raw.splitlines():
267 stat = line.split('=')
268 tmp[stat[0]] = stat[1]
256 - for item in STAT_MAP:
269 + for item in self.statmap:
270 if item in tmp:
258 - data[STAT_MAP[item][0]] = float(tmp[item]) * STAT_MAP[item][1]
271 + data[self.statmap[item][0]] = float(tmp[item]) * self.statmap[item][1]
272 return data