Пример #1
0
    def _send_command(self, host, port, timeout, command, tags):
        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.settimeout(timeout)
            s.connect((host, port))

            s.sendall(ensure_bytes("{0}\n".format(command)))

            buf = BytesIO()

            chunk = s.recv(1024)
            buf.write(ensure_bytes(chunk))
            while chunk:
                if ENDER.search(chunk):
                    break
                if BAD_ENDER.search(chunk):
                    raise Exception(
                        "Got an error issuing command: {0}".format(command))
                chunk = s.recv(1024)
                buf.write(chunk)
            return buf
        except Exception as e:
            self.service_check(SERVICE_CHECK_NAME, AgentCheck.CRITICAL, tags)
            raise Exception("Failed connection {0}".format(str(e)))
        finally:
            s.close()
    def _submit_channel_status(self, queue_manager, search_channel_name, tags,
                               config):
        """Submit channel status
        :param search_channel_name might contain wildcard characters
        """
        search_channel_tags = tags + ["channel:{}".format(search_channel_name)]
        try:
            args = {
                pymqi.CMQCFC.MQCACH_CHANNEL_NAME:
                ensure_bytes(search_channel_name)
            }
            pcf = pymqi.PCFExecute(queue_manager)
            response = pcf.MQCMD_INQUIRE_CHANNEL_STATUS(args)
            self.service_check(self.CHANNEL_SERVICE_CHECK, AgentCheck.OK,
                               search_channel_tags)
        except pymqi.MQMIError as e:
            self.log.warning("Error getting CHANNEL stats {}".format(e))
            self.service_check(self.CHANNEL_SERVICE_CHECK, AgentCheck.CRITICAL,
                               search_channel_tags)
        else:
            for channel_info in response:
                channel_name = ensure_unicode(
                    channel_info[pymqi.CMQCFC.MQCACH_CHANNEL_NAME]).strip()
                channel_tags = tags + ["channel:{}".format(channel_name)]

                channel_status = channel_info[
                    pymqi.CMQCFC.MQIACH_CHANNEL_STATUS]

                self._submit_channel_count(channel_name, channel_status,
                                           channel_tags)
                self._submit_status_check(channel_name, channel_status,
                                          channel_tags, config)
def get_config(nagios_conf,
               events=False,
               service_perf=False,
               host_perf=False,
               tags=None):
    """
    Helper to generate a valid Nagios configuration
    """
    nagios_conf = ensure_bytes(nagios_conf)
    tags = [] if tags is None else tags

    NAGIOS_CFG = tempfile.NamedTemporaryFile(mode="a+b")
    NAGIOS_CFG.write(nagios_conf)
    NAGIOS_CFG.flush()

    CONFIG = {
        'instances': [{
            'nagios_conf': NAGIOS_CFG.name,
            'collect_events': events,
            'collect_service_performance_data': service_perf,
            'collect_host_performance_data': host_perf,
            'tags': list(tags),
        }]
    }

    return CONFIG, NAGIOS_CFG
Пример #4
0
    def _send_command(command, host, port, timeout):
        sock = socket.socket()
        sock.settimeout(timeout)
        buf = StringIO()
        chunk_size = 1024
        # try-finally and try-except to stay compatible with python 2.4
        try:
            try:
                # Connect to the zk client port and send the stat command
                sock.connect((host, port))
                sock.sendall(ensure_bytes(command))

                # Read the response into a StringIO buffer
                chunk = ensure_unicode(sock.recv(chunk_size))
                buf.write(chunk)
                num_reads = 1
                max_reads = 10000
                while chunk:
                    if num_reads > max_reads:
                        # Safeguard against an infinite loop
                        raise Exception(
                            "Read %s bytes before exceeding max reads of %s. "
                            % (buf.tell(), max_reads))
                    chunk = ensure_unicode(sock.recv(chunk_size))
                    buf.write(chunk)
                    num_reads += 1
            except (socket.timeout, socket.error):
                raise ZKConnectionFailure()
        finally:
            sock.close()
        return buf
Пример #5
0
    def make_request(self, path):
        url = "{}{}".format(self.aci_url, path)

        if self.apic_cookie:
            cookie = self.apic_cookie
        elif self.cert_key:
            payload = 'GET{}'.format(path)
            signature = self.cert_key.sign(ensure_bytes(payload), padding.PKCS1v15(), hashes.SHA256())

            signature = base64.b64encode(signature)
            cookie = (
                'APIC-Request-Signature={}; '
                'APIC-Certificate-Algorithm=v1.0; '
                'APIC-Certificate-Fingerprint=fingerprint; '
                'APIC-Certificate-DN={}'
            ).format(signature, self.certDn)
            cookie = cookie
        else:
            self.log.warning("The Cisco ACI Integration requires either a cert or a username and password")
            raise ConfigurationError("The Cisco ACI Integration requires either a cert or a username and password")

        response = self.http.get(url, headers={'Cookie': cookie}, persist=True)
        if response.status_code == 403:
            raise APIAuthException("Received 403 when making request: %s", response.text)
        try:
            response.raise_for_status()
        except Exception as e:
            self.log.warning("Error making request: exception='%s' response.content='%s'", e, response.content)
            raise APIConnectionException("Error making request: {}".format(e))
        try:
            return response.json()
        except Exception as e:
            self.log.warning("Exception in json parsing, returning nothing: %s", e)
            raise APIParsingException("Error parsing request: {}".format(e))
    def check(self, instance):
        try:
            auth_token = base64.b64encode(
                ensure_bytes(instance['username'] + ":" +
                             instance['password']))
            response = requests.get(
                instance['stardog_url'] + '/admin/status',
                headers={'Authorization': 'Basic {}'.format(auth_token)})
        except KeyError:
            raise Exception(
                'The Stardog check instance is not properly configured')

        if response.status_code != 200:
            response.raise_for_status()
        json_doc = response.json()
        try:
            tags = instance['tags']
            if type(tags) != list:
                self.log.warn(
                    'The tags list in the Stardog check is not configured properly'
                )
                tags = []
        except KeyError:
            tags = []

        tags.append("stardog_url:%s" % instance['stardog_url'])
        self._process_doc(json_doc, _g_metrics_map, tags)
        self._process_doc(json_doc, _g_bd_specific_map, tags, add_db_tags=True)
Пример #7
0
    def get_pcf_queue_status_metrics(self, queue_manager, queue_name, tags):
        try:
            args = {
                pymqi.CMQC.MQCA_Q_NAME: ensure_bytes(queue_name),
                pymqi.CMQC.MQIA_Q_TYPE: pymqi.CMQC.MQQT_ALL,
                pymqi.CMQCFC.MQIACF_Q_STATUS_ATTRS: pymqi.CMQCFC.MQIACF_ALL,
            }
            pcf = pymqi.PCFExecute(queue_manager)
            response = pcf.MQCMD_INQUIRE_Q_STATUS(args)
        except pymqi.MQMIError as e:
            self.warning("Error getting pcf queue stats for %s: %s", queue_name, e)
        else:
            # Response is a list. It likely has only one member in it.
            for queue_info in response:
                for mname, values in iteritems(metrics.pcf_metrics()):
                    failure_value = values['failure']
                    pymqi_value = values['pymqi_value']
                    mname = '{}.queue.{}'.format(self.METRIC_PREFIX, mname)
                    m = int(queue_info[pymqi_value])

                    if m > failure_value:
                        self.gauge(mname, m, tags=tags)
                    else:
                        msg = "Unable to get {}, turn on queue level monitoring to access these metrics for {}"
                        msg = msg.format(mname, queue_name)
                        log.debug(msg)
Пример #8
0
    def get_pcf_channel_metrics(self, queue_manager, tags, config):
        args = {pymqi.CMQCFC.MQCACH_CHANNEL_NAME: ensure_bytes('*')}

        try:
            pcf = pymqi.PCFExecute(queue_manager)
            response = pcf.MQCMD_INQUIRE_CHANNEL(args)
        except pymqi.MQMIError as e:
            self.log.warning("Error getting CHANNEL stats %s", e)
        else:
            channels = len(response)
            mname = '{}.channel.channels'.format(self.METRIC_PREFIX)
            self.gauge(mname, channels, tags=tags)

            for channel_info in response:
                channel_name = ensure_unicode(channel_info[pymqi.CMQCFC.MQCACH_CHANNEL_NAME]).strip()
                channel_tags = tags + ["channel:{}".format(channel_name)]

                self._submit_metrics_from_properties(channel_info, metrics.channel_metrics(), channel_tags)

        # Check specific channels
        # If a channel is not discoverable, a user may want to check it specifically.
        # Specific channels are checked first to send channel metrics and `ibm_mq.channel` service checks
        # at the same time, but the end result is the same in any order.
        for channel in config.channels:
            self._submit_channel_status(queue_manager, channel, tags, config)

        # Grab all the discoverable channels
        self._submit_channel_status(queue_manager, '*', tags, config, config.channels)
Пример #9
0
    def _submit_channel_status(self, queue_manager, search_channel_name, tags, config, channels_to_skip=None):
        """Submit channel status

        Note: Error 3065 (MQRCCF_CHL_STATUS_NOT_FOUND) might indicate that the channel has not been used.
        More info: https://www.ibm.com/support/knowledgecenter/SSFKSJ_7.1.0/com.ibm.mq.doc/fm16690_.htm

        :param search_channel_name might contain wildcard characters
        """
        channels_to_skip = channels_to_skip or []
        search_channel_tags = tags + ["channel:{}".format(search_channel_name)]
        try:
            args = {pymqi.CMQCFC.MQCACH_CHANNEL_NAME: ensure_bytes(search_channel_name)}
            pcf = pymqi.PCFExecute(queue_manager)
            response = pcf.MQCMD_INQUIRE_CHANNEL_STATUS(args)
            self.service_check(self.CHANNEL_SERVICE_CHECK, AgentCheck.OK, search_channel_tags)
        except pymqi.MQMIError as e:
            self.service_check(self.CHANNEL_SERVICE_CHECK, AgentCheck.CRITICAL, search_channel_tags)
            if e.comp == pymqi.CMQC.MQCC_FAILED and e.reason == pymqi.CMQCFC.MQRCCF_CHL_STATUS_NOT_FOUND:
                self.log.debug("Channel status not found for channel %s: %s", search_channel_name, e)
            else:
                self.log.warning("Error getting CHANNEL status for channel %s: %s", search_channel_name, e)
        else:
            for channel_info in response:
                channel_name = ensure_unicode(channel_info[pymqi.CMQCFC.MQCACH_CHANNEL_NAME]).strip()
                if channel_name in channels_to_skip:
                    continue
                channel_tags = tags + ["channel:{}".format(channel_name)]

                self._submit_metrics_from_properties(channel_info, metrics.channel_status_metrics(), channel_tags)

                channel_status = channel_info[pymqi.CMQCFC.MQIACH_CHANNEL_STATUS]
                self._submit_channel_count(channel_name, channel_status, channel_tags)
                self._submit_status_check(channel_name, channel_status, channel_tags, config)
Пример #10
0
 def do_GET(self):
     if self.path != '/admin/status':
         self.send_response(404)
         return
     self.send_response(200)
     self.send_header('Content-type', 'application/json')
     self.end_headers()
     # json.dumps always outputs a str, wfile.write requires bytes
     self.wfile.write(ensure_bytes(json.dumps(DATA)))
Пример #11
0
def compute_sql_signature(normalized_query):
    """
    Given an already obfuscated & normalized SQL query, generate its 64-bit hex signature.
    """
    if not normalized_query:
        return None
    # Note: please be cautious when changing this function as some features rely on this
    # hash matching the APM resource hash generated on our backend.
    return format(
        mmh3.hash64(ensure_bytes(normalized_query), signed=False)[0], 'x')
 def do_GET(self):
     if self.path == '/config/v1/project/channels':
         self.send_response(200)
         self.send_header('Content-type', 'application/json')
         self.end_headers()
         # json.dumps always outputs a str, wfile.write requires bytes
         self.wfile.write(ensure_bytes(json.dumps(CHANNEL_DATA)))
     else:
         self.send_response(404)
         return
Пример #13
0
 def do_GET(self):
     if self.path != "/admin/status":
         self.send_response(404)
         return
     if self.headers["Authorization"] != "Basic YWRtaW46YWRtaW4=":
         self.send_response(401)
         return
     self.send_response(200)
     self.send_header("Content-type", "application/json")
     self.end_headers()
     # json.dumps always outputs a str, wfile.write requires bytes
     self.wfile.write(ensure_bytes(json.dumps(DATA)))
Пример #14
0
    def check(self, instance):
        config = IBMMQConfig(instance)
        config.check_properly_configured()

        if not pymqi:
            log.error("You need to install pymqi: {}".format(pymqiException))
            raise errors.PymqiException(
                "You need to install pymqi: {}".format(pymqiException))

        try:
            queue_manager = connection.get_queue_manager_connection(config)
            self.service_check(self.SERVICE_CHECK, AgentCheck.OK, config.tags)
        except Exception as e:
            self.warning("cannot connect to queue manager: {}".format(e))
            self.service_check(self.SERVICE_CHECK, AgentCheck.CRITICAL,
                               config.tags)
            return

        self.get_pcf_channel_metrics(queue_manager, config.tags_no_channel,
                                     config)

        self.discover_queues(queue_manager, config)

        try:
            self.queue_manager_stats(queue_manager, config.tags)

            for queue_name in config.queues:
                queue_tags = config.tags + ["queue:{}".format(queue_name)]

                for regex, q_tags in config.queue_tag_re:
                    if regex.match(queue_name):
                        queue_tags.extend(q_tags)

                try:
                    queue = pymqi.Queue(queue_manager,
                                        ensure_bytes(queue_name))
                    self.queue_stats(queue, queue_name, queue_tags)
                    # some system queues don't have PCF metrics
                    # so we don't collect those metrics from those queues
                    if queue_name not in config.DISALLOWED_QUEUES:
                        self.get_pcf_queue_metrics(queue_manager, queue_name,
                                                   queue_tags)
                    self.service_check(self.QUEUE_SERVICE_CHECK, AgentCheck.OK,
                                       queue_tags)
                    queue.close()
                except Exception as e:
                    self.warning('Cannot connect to queue {}: {}'.format(
                        queue_name, e))
                    self.service_check(self.QUEUE_SERVICE_CHECK,
                                       AgentCheck.CRITICAL, queue_tags)
        finally:
            queue_manager.disconnect()
Пример #15
0
 def get_pcf_queue_reset_metrics(self, queue_manager, queue_name, tags):
     try:
         args = {pymqi.CMQC.MQCA_Q_NAME: ensure_bytes(queue_name)}
         pcf = pymqi.PCFExecute(queue_manager)
         response = pcf.MQCMD_RESET_Q_STATS(args)
     except pymqi.MQMIError as e:
         self.warning("Error getting pcf queue stats for %s: %s", queue_name, e)
     else:
         # Response is a list. It likely has only one member in it.
         for queue_info in response:
             for metric_name, (pymqi_type, metric_type) in iteritems(metrics.pcf_status_reset_metrics()):
                 metric_full_name = '{}.queue.{}'.format(self.METRIC_PREFIX, metric_name)
                 metric_value = int(queue_info[pymqi_type])
                 self._send_metric(metric_type, metric_full_name, metric_value, tags)
Пример #16
0
 def queue_stats(self, queue_manager, queue_name, tags):
     """
     Grab stats from queues
     """
     try:
         args = {pymqi.CMQC.MQCA_Q_NAME: ensure_bytes(queue_name), pymqi.CMQC.MQIA_Q_TYPE: pymqi.CMQC.MQQT_ALL}
         pcf = pymqi.PCFExecute(queue_manager)
         response = pcf.MQCMD_INQUIRE_Q(args)
     except pymqi.MQMIError as e:
         self.warning("Error getting queue stats for %s: %s", queue_name, e)
     else:
         # Response is a list. It likely has only one member in it.
         for queue_info in response:
             self._submit_queue_stats(queue_info, queue_name, tags)
Пример #17
0
    def test_alt_host_perfdata(self, aggregator):
        """
        Collect Nagios Host PerfData metrics - alternative template
        """
        self.log_file = tempfile.NamedTemporaryFile()
        perfdata_file = tempfile.NamedTemporaryFile()

        # Get the config
        config, _ = get_config(
            "host_perfdata_file={}\n"
            "host_perfdata_file_template={}".format(perfdata_file.name, NAGIOS_TEST_ALT_HOST_TEMPLATE),
            host_perf=True,
        )

        # Set up the check
        nagios = NagiosCheck(CHECK_NAME, {}, config['instances'])

        # Run the check once
        nagios.check(config['instances'][0])

        with open(NAGIOS_TEST_HOST, "r") as f:
            nagios_perf = ensure_bytes(f.read())

        perfdata_file.write(nagios_perf)
        perfdata_file.flush()

        nagios.check(config['instances'][0])

        # Test metrics
        expected_metrics = [
            {
                'name': 'nagios.host.pl',
                'timestamp': 1339511440,
                'value': 0.0,
                'hostname': 'localhost',
                'tags': ['unit:%', 'warn:80', 'crit:100', 'min:0'],
            },
            {
                'name': 'nagios.host.rta',
                'timestamp': 1339511440,
                'value': 0.048,
                'hostname': 'localhost',
                'tags': ['unit:ms', 'warn:3000.000000', 'crit:5000.000000', 'min:0.000000'],
            },
        ]

        for metric in expected_metrics:
            aggregator.assert_metric(metric['name'], metric['value'], tags=metric['tags'], hostname=metric['hostname'])

        aggregator.assert_all_metrics_covered()
Пример #18
0
    def _discover_queues(self, queue_manager, mq_pattern_filter):
        queues = []

        for queue_type in SUPPORTED_QUEUE_TYPES:
            args = {pymqi.CMQC.MQCA_Q_NAME: ensure_bytes(mq_pattern_filter), pymqi.CMQC.MQIA_Q_TYPE: queue_type}
            try:
                pcf = pymqi.PCFExecute(queue_manager)
                response = pcf.MQCMD_INQUIRE_Q(args)
            except pymqi.MQMIError as e:
                self.warning("Error discovering queue: %s", e)
            else:
                for queue_info in response:
                    queue = queue_info[pymqi.CMQC.MQCA_Q_NAME]
                    queues.append(ensure_unicode(queue).strip())

        return queues
Пример #19
0
    def read_key(self):
        if self._config.private_key_path:
            self.log.debug("Reading Snowflake client key for key pair authentication")
            # https://docs.snowflake.com/en/user-guide/python-connector-example.html#using-key-pair-authentication-key-pair-rotation
            with open(self._config.private_key_path, "rb") as key:
                p_key = serialization.load_pem_private_key(
                    key.read(), password=ensure_bytes(self._config.private_key_password), backend=default_backend()
                )

                pkb = p_key.private_bytes(
                    encoding=serialization.Encoding.DER,
                    format=serialization.PrivateFormat.PKCS8,
                    encryption_algorithm=serialization.NoEncryption(),
                )

                return pkb

        return None
Пример #20
0
    def _discover_queues(self, queue_manager, regex):
        args = {
            pymqi.CMQC.MQCA_Q_NAME: ensure_bytes(regex),
            pymqi.CMQC.MQIA_Q_TYPE: pymqi.CMQC.MQQT_MODEL
        }
        queues = []

        try:
            pcf = pymqi.PCFExecute(queue_manager)
            response = pcf.MQCMD_INQUIRE_Q(args)
        except pymqi.MQMIError as e:
            self.warning("Error getting queue stats: {}".format(e))
        else:
            for queue_info in response:
                queue = queue_info[pymqi.CMQC.MQCA_Q_NAME]
                queue = queue.strip()
                queues.append(queue)

        return queues
Пример #21
0
    def _get_data(sock, command):
        chunk_size = 1024
        max_reads = 10000
        buf = StringIO()
        sock.sendall(ensure_bytes(command))
        # Read the response into a StringIO buffer
        chunk = ensure_unicode(sock.recv(chunk_size))
        buf.write(chunk)
        num_reads = 1

        while chunk:
            if num_reads > max_reads:
                # Safeguard against an infinite loop
                raise Exception(
                    "Read %s bytes before exceeding max reads of %s. " %
                    (buf.tell(), max_reads))
            chunk = ensure_unicode(sock.recv(chunk_size))
            buf.write(chunk)
            num_reads += 1
        return buf
Пример #22
0
    def test_continuous_bulk_parsing(self, aggregator):
        """
        Make sure the tailer continues to parse nagios as the file grows
        """
        test_data = ensure_bytes(open(NAGIOS_TEST_LOG).read())
        ITERATIONS = 10
        log_file = tempfile.NamedTemporaryFile(mode="a+b")

        # Get the config
        config, nagios_cfg = get_config("log_file={}\n".format(log_file.name), events=True)

        # Set up the check
        nagios = NagiosCheck(CHECK_NAME, {}, config['instances'])

        for _ in range(ITERATIONS):
            log_file.write(test_data)
            log_file.flush()
            nagios.check(config['instances'][0])

        log_file.close()
        assert len(aggregator.events) == ITERATIONS * 503
Пример #23
0
    def get_pcf_channel_metrics(self, queue_manager, tags, config):
        args = {pymqi.CMQCFC.MQCACH_CHANNEL_NAME: ensure_bytes('*')}

        try:
            pcf = pymqi.PCFExecute(queue_manager)
            response = pcf.MQCMD_INQUIRE_CHANNEL(args)
        except pymqi.MQMIError as e:
            self.log.warning("Error getting CHANNEL stats {}".format(e))
        else:
            channels = len(response)
            mname = '{}.channel.channels'.format(self.METRIC_PREFIX)
            self.gauge(mname, channels, tags=tags)

        # grab all the discoverable channels
        self._get_channel_status(queue_manager, '*', tags, config)

        # check specific channels as well
        # if a channel is not listed in the above one, a user may want to check it specifically,
        # in this case it'll fail
        for channel in config.channels:
            self._get_channel_status(queue_manager, channel, tags, config)
Пример #24
0
    def _get_channel_status(self, queue_manager, channel, tags, config):
        channel_tags = tags + ["channel:{}".format(channel)]
        try:
            args = {pymqi.CMQCFC.MQCACH_CHANNEL_NAME: ensure_bytes(channel)}
            pcf = pymqi.PCFExecute(queue_manager)
            response = pcf.MQCMD_INQUIRE_CHANNEL_STATUS(args)
        except pymqi.MQMIError as e:
            self.log.warning("Error getting CHANNEL stats {}".format(e))
            self.service_check(self.CHANNEL_SERVICE_CHECK, AgentCheck.CRITICAL,
                               channel_tags)
        else:
            for channel_info in response:
                name = channel_info[pymqi.CMQCFC.MQCACH_CHANNEL_NAME]
                name = name.strip()

                # running = 3, stopped = 4
                status = channel_info[pymqi.CMQCFC.MQIACH_CHANNEL_STATUS]
                if status == 3:
                    self.service_check(self.CHANNEL_SERVICE_CHECK,
                                       AgentCheck.OK, channel_tags)
                elif status == 4:
                    self.service_check(self.CHANNEL_SERVICE_CHECK,
                                       AgentCheck.WARNING, channel_tags)
Пример #25
0
    def test_recovers_from_deleted_file(self, aggregator):
        """
        Make sure the tailer continues to parse nagios as the file grows
        """
        test_data = ensure_bytes(open(NAGIOS_TEST_LOG).read())
        log_file = tempfile.NamedTemporaryFile(mode="a+b")

        # Get the config
        config, nagios_cfg = get_config("log_file={}\n".format(log_file.name), events=True)

        # Set up the check
        nagios = NagiosCheck(CHECK_NAME, {}, config['instances'])

        def write_and_check():
            log_file.write(test_data)
            log_file.flush()
            nagios.check(config['instances'][0])

        # First call, will create events
        write_and_check()
        assert len(aggregator.events) == 503
        os.rename(log_file.name, log_file.name + "_renamed")
        # File has been renamed, the check will fail but should recover later.
        write_and_check()
        assert len(aggregator.events) == 503
        os.rename(log_file.name + "_renamed", log_file.name)

        # Check recovers but start from the EOF
        write_and_check()
        assert len(aggregator.events) == 503

        # Check has fully recovered and submit events again
        write_and_check()
        assert len(aggregator.events) == 2 * 503

        log_file.close()
Пример #26
0
 def send_status_up(logMsg):
     # TODO: A6 log needs bytes and cannot handle unicode
     self.log.debug(ensure_bytes(logMsg))
     service_checks.append((self.SC_STATUS, Status.UP, "UP"))
 def _write_log(self, log_data):
     """
     Write log data to log file
     """
     self.log_file.write(ensure_bytes(log_data + "\n"))
     self.log_file.flush()
    def test_alt_service_perfdata(self, aggregator):
        """
        Collect Nagios Service PerfData metrics - alternative template
        """
        self.log_file = tempfile.NamedTemporaryFile()
        perfdata_file = tempfile.NamedTemporaryFile()

        # Get the config
        config, _ = get_config(
            "service_perfdata_file={}\n"
            "service_perfdata_file_template={}".format(
                perfdata_file.name, NAGIOS_TEST_ALT_SVC_TEMPLATE),
            service_perf=True,
        )

        # Set up the check
        nagios = NagiosCheck(CHECK_NAME, {}, config['instances'])

        # Run the check once
        nagios.check(config['instances'][0])

        with open(NAGIOS_TEST_SVC, "r") as f:
            nagios_perf = ensure_bytes(f.read())

        perfdata_file.write(nagios_perf)
        perfdata_file.flush()

        nagios.check(config['instances'][0])

        # Test metrics
        expected_metrics = [
            {
                'name': 'nagios.current_users.users',
                'timestamp': 1339511440,
                'value': 1.0,
                'hostname': 'localhost',
                'tags': ['warn:20', 'crit:50', 'min:0'],
            },
            {
                'name': 'nagios.ping.pl',
                'timestamp': 1339511500,
                'value': 0.0,
                'hostname': 'localhost',
                'tags': ['unit:%', 'warn:20', 'crit:60', 'min:0'],
            },
            {
                'name':
                'nagios.ping.rta',
                'timestamp':
                1339511500,
                'value':
                0.065,
                'hostname':
                'localhost',
                'tags': [
                    'unit:ms', 'warn:100.000000', 'crit:500.000000',
                    'min:0.000000'
                ],
            },
            {
                'name':
                'nagios.root_partition',
                'timestamp':
                1339511560,
                'value':
                2470.0,
                'hostname':
                'localhost',
                'tags': [
                    'unit:MB', 'warn:5852', 'crit:6583', 'min:0', 'max:7315',
                    'device:/'
                ],
            },
        ]

        for metric in expected_metrics:
            aggregator.assert_metric(metric['name'],
                                     metric['value'],
                                     tags=metric['tags'],
                                     hostname=metric['hostname'])

        aggregator.assert_all_metrics_covered()
    def test_line_parser(self, aggregator):
        """
        Parse lines
        """

        # Get the config
        config, nagios_cfg = get_config(ensure_bytes(
            "log_file={}\n".format(NAGIOS_TEST_LOG)),
                                        events=True,
                                        tags=CUSTOM_TAGS)

        # Set up the check
        nagios = NagiosCheck(CHECK_NAME, {}, config['instances'])

        # Run the check once
        nagios.check(config['instances'][0])

        nagios_tailer = nagios.nagios_tails[nagios_cfg.name][0]
        counters = {}

        for line in open(NAGIOS_TEST_LOG).readlines():
            parsed = nagios_tailer._parse_line(line)
            if parsed:
                event = aggregator.events[-1]
                t = event["event_type"]
                assert t in line
                assert int(event["timestamp"]) > 0, line
                assert event["host"] is not None, line
                counters[t] = counters.get(t, 0) + 1
                event['msg_text'] = json.loads(event['msg_text'])

                if t == "SERVICE ALERT":
                    assert event['msg_text']["event_soft_hard"] in (
                        "SOFT", "HARD"), line
                    assert event['msg_text']["event_state"] in ("CRITICAL",
                                                                "WARNING",
                                                                "UNKNOWN",
                                                                "OK"), line
                    assert event['msg_text']["check_name"] is not None
                elif t == "SERVICE NOTIFICATION":
                    assert event['msg_text']["event_state"] in (
                        "ACKNOWLEDGEMENT",
                        "OK",
                        "CRITICAL",
                        "WARNING",
                        "ACKNOWLEDGEMENT (CRITICAL)",
                    ), line
                elif t == "SERVICE FLAPPING ALERT":
                    assert event["flap_start_stop"] in ("STARTED",
                                                        "STOPPED"), line
                    assert event['msg_text']["check_name"] is not None
                elif t == "ACKNOWLEDGE_SVC_PROBLEM":
                    assert event['msg_text']["check_name"] is not None
                    assert event['msg_text']["ack_author"] is not None
                    assert int(event["sticky_ack"]) >= 0
                    assert int(event["notify_ack"]) >= 0
                elif t == "ACKNOWLEDGE_HOST_PROBLEM":
                    assert event['msg_text']["ack_author"] is not None
                    assert int(event["sticky_ack"]) >= 0
                    assert int(event["notify_ack"]) >= 0
                elif t == "HOST DOWNTIME ALERT":
                    assert event["host"] is not None
                    assert event["downtime_start_stop"] in ("STARTED",
                                                            "STOPPED")
                assert CUSTOM_TAGS == event['tags']

        assert counters["SERVICE ALERT"] == 301
        assert counters["SERVICE NOTIFICATION"] == 120
        assert counters["HOST ALERT"] == 3
        assert counters["SERVICE FLAPPING ALERT"] == 7
        assert counters["CURRENT HOST STATE"] == 8
        assert counters["CURRENT SERVICE STATE"] == 52
        assert counters["SERVICE DOWNTIME ALERT"] == 3
        assert counters["HOST DOWNTIME ALERT"] == 5
        assert counters["ACKNOWLEDGE_SVC_PROBLEM"] == 4
        assert "ACKNOWLEDGE_HOST_PROBLEM" not in counters
Пример #30
0
 def send_status_down(loginfo, down_msg):
     # TODO: A6 log needs bytes and cannot handle unicode
     self.log.info(ensure_bytes(loginfo))
     if include_content:
         down_msg += '\nContent: {}'.format(content[:CONTENT_LENGTH])
     service_checks.append((self.SC_STATUS, Status.DOWN, down_msg))