DNS Masq-1597667047637.png
On Dashboard:
- Internal dnsmasq stats (evictions, hits, auth, insections and misses queries)
- Upstream queries
- Upstream errors
Requirement: python-dnspython
grafana->graphite->collectd
Collector Configuration Details
LoadPlugin python
<Plugin python>
ModulePath "/opt/collectd/python"
Import "dns_masq"
<Module dns_masq>
# Verbose true
Interval 60
Address "<dnsmasq_address>"
Timeout 1
</Module>
</Plugin>
/opt/collectd/python/dns_masq.py
import collectd
import dns.resolver
class dns_masq(object):
def __init__(self):
self.plugin_name = 'dns_masq'
self.verbose_logging = False
self.address = '127.0.0.1'
self.timeout = 0.5
def log_verbose(self, msg):
if not self.verbose_logging:
return
collectd.info('%s plugin [verbose]: %s' % (self.plugin_name, msg))
def store(self, key, val):
val = collectd.Values(type='gauge', plugin=self.plugin_name, type_instance=key, values=[val])
val.dispatch()
self.log_verbose('Sending value: %s:%s' % (key, val))
def read(self):
# init
self.resolver = dns.resolver.Resolver(configure=False)
self.resolver.lifetime = self.timeout
self.resolver.nameservers = [self.address]
#dig +short chaos txt *.bind. @address
for name_metric in ['insertions','evictions','misses','hits','auth']:
answer = self.resolver.query('%s.bind' % name_metric, 'TXT', 'CHAOS')
self.store(name_metric, str(answer.rrset[0])[1:-1])
#dig +short chaos txt servers.bind. @address
answer = self.resolver.query('servers.bind', 'TXT', 'CHAOS')
for uplink in str(answer.rrset[0]).split('"'):
raw = uplink.split(" ")
if isinstance(raw, list) and len(raw) == 3:
name = raw[0].replace('.','_')
queries = raw[1]
errors = raw[2]
self.store('upstream_%s_queries' % name, queries)
self.store('upstream_%s_errors' % name, errors)
def configure_callback(self, conf):
for node in conf.children:
vals = [str(v) for v in node.values]
if node.key == 'Verbose':
self.verbose_logging = (vals[0].lower() == 'true')
elif node.key == 'Interval':
self.interval = float(vals[0])
elif node.key == 'Address':
self.address = str(vals[0])
elif node.key == 'Timeout':
self.timeout = float(vals[0])
else:
raise ValueError('%s plugin: Unknown config key: %s' % (self.plugin_name, node.key))
collectd.register_read(self.read, self.interval)
self.log_verbose('configured with interval=%s' % self.interval)
app_dns_masq = dns_masq()
collectd.register_config(app_dns_masq.configure_callback)