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
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
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)
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)
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)
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)
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)))
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
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)))
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()
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)
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)
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()
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
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
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
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
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
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)
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)
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()
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
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))