# # Copyright (C) 2019 Marko Myllynen # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # """PCP netcheck PMDA reverse DNS lookup module""" # pylint: disable=too-many-arguments,too-many-positional-arguments # pylint: disable=invalid-name try: from time import perf_counter as time except ImportError: from time import time import sys import socket from multiprocessing import Manager from pcp.pmapi import pmUnits from cpmapi import PM_TYPE_FLOAT, PM_TYPE_STRING, PM_SEM_INSTANT, PM_SEM_DISCRETE, PM_TIME_MSEC from modules.pcpnetcheck import PCPNetcheckModuleBase # Module constants MODULE = 'dns_reverse' BASENS = 'dns.reverse.' units_none = pmUnits(0, 0, 0, 0, 0, 0) units_msecs = pmUnits(0, 1, 0, 0, PM_TIME_MSEC, 0) class PCPNetcheckModule(PCPNetcheckModuleBase): """PCP netcheck reverse DNS lookup module""" def __init__(self, config, dbg, log, err, params): """Constructor""" PCPNetcheckModuleBase.__init__(self, MODULE, config, dbg, log, err, params) self.prereq_check() for opt in self.config.options(MODULE): if opt not in self.common_opts: self.err("Invalid directive '%s' in %s, aborting." % (opt, MODULE)) sys.exit(1) self.log("Module parameters: timeout: %s." % self.timeout) socket.setdefaulttimeout(self.timeout) for host in self.hosts: self.hosts[host] = "" self.log("Initialized.") @staticmethod def prereq_check(): """Check module prerequisities""" try: socket.gethostbyaddr("127.0.0.1") except Exception: # pylint: disable=broad-except raise RuntimeError("Can't resolve 127.0.0.1!") def metrics(self): """Get metric definitions""" self.items = ( # Name - reserved - type - semantics - units - help (BASENS + 'res', None, PM_TYPE_STRING, PM_SEM_DISCRETE, units_none, 'reverse dns lookup result'), (BASENS + 'time', None, PM_TYPE_FLOAT, PM_SEM_INSTANT, units_msecs, 'reverse dns lookup time'), ) return True, self.items @staticmethod def _do_reverse(hosts, timings, host): """Do reverse DNS lookup""" try: start_time = time() res = socket.gethostbyaddr(host) end_time = time() hosts[host] = res[0] timings[host] = (end_time - start_time) * 1000 except Exception: # pylint: disable=broad-except pass def do_check(self): """Do net check""" hosts = Manager().dict() timings = Manager().dict() self._run_check_methods(self._do_reverse, (hosts, timings)) for host in self.hosts: self.hosts[host] = hosts[host] if host in hosts else self.HOST_FAIL_STR self.timings[host] = timings[host] if host in timings else -2