2 from time import monotonic as time
6 import dns.message, dns.query, dns.name
11 from queue import Queue
13 from Queue import Queue
14 from random import choice
15 from threading import Thread
16 from socket import gethostbyname, gaierror
17 from base import SimpleService
20 # default module values (can be overridden per job in `config`)
26 class Service(SimpleService):
27 def __init__(self, configuration=None, name=None):
28 SimpleService.__init__(self, configuration=configuration, name=name)
30 self.definitions = dict()
31 self.timeout = self.configuration.get('response_timeout', 4)
32 self.aggregate = self.configuration.get('aggregate', True)
33 self.domains = self.configuration.get('domains')
34 self.server_list = self.configuration.get('dns_servers')
38 self.error('\'python-dnspython\' package is needed to use dns_query_time.chart.py')
41 self.timeout = self.timeout if isinstance(self.timeout, int) else 4
42 self.update_every = self.timeout + 1 if self.update_every <= self.timeout else self.update_every
44 if not all([self.domains, self.server_list,
45 isinstance(self.server_list, str), isinstance(self.domains, str)]):
46 self.error('server_list and domain_list can\'t be empty')
49 self.domains, self.server_list = self.domains.split(), self.server_list.split()
51 for ns in self.server_list:
53 self.info('Bad NS: %s' % ns)
54 self.server_list.remove(ns)
55 if not self.server_list:
58 data = self._get_data(timeout=1)
60 down_servers = [s[2:] for s in data if data[s] == -100]
62 self.info('Removed due to non response %s' % down_servers)
63 self.server_list = [s for s in self.server_list if s not in down_servers]
65 self._data_from_check = data
66 self.order, self.definitions = create_charts(aggregate=self.aggregate, server_list=self.server_list)
67 self.info(str({'domains': len(self.domains), 'servers': self.server_list}))
72 def _get_data(self, timeout=None):
73 return dns_request(self.server_list, timeout or self.timeout, self.domains)
76 def dns_request(server_list, timeout, domains):
81 def dns_req(ns, t, q):
82 domain = dns.name.from_text(choice(domains))
83 request = dns.message.make_query(domain, dns.rdatatype.A)
87 dns.query.udp(request, ns, timeout=t)
89 query_time = round((dns_end - dns_start) * 1000)
90 q.put({''.join(['ns', ns]): query_time})
91 except dns.exception.Timeout:
92 q.put({''.join(['ns', ns]): -100})
94 for server in server_list:
95 th = Thread(target=dns_req, args=(server, timeout, que))
101 result.update(que.get())
108 return gethostbyname(ns)
113 def create_charts(aggregate, server_list):
115 order = ['dns_group']
116 definitions = {'dns_group': {'options': [None, "DNS Response Time", "ms", 'name servers',
117 'resp.time', 'line'], 'lines': []}}
118 for ns in server_list:
119 definitions['dns_group']['lines'].append([''.join(['ns', ns]), ns, 'absolute'])
121 return order, definitions
123 order = [''.join(['dns_', ns]) for ns in server_list]
125 for ns in server_list:
126 definitions[''.join(['dns_', ns])] = {'options': [None, "DNS Response Time", "ms", ns,
127 'resp.time', 'area'],
128 'lines': [[''.join(['ns', ns]), ns, 'absolute']]}
129 return order, definitions