Example #1
0
 def get_ingestions(self, num=None, filter_opts=None):
     log.info('getting ingestion history')
     if num:
         chunk_size = num
         log.info('explicit number of results requested: %s', chunk_size)
     elif filter_opts:
         chunk_size = 10
         log.info('filters detected, defaulting number of results to %s', chunk_size)
     else:
         chunk_size = 100
         log.info('using catch all default result limit of %s', chunk_size)
     settings = {'chunkSize': chunk_size, 'currentPage': 1}
     if filter_opts is not None:
         if not isDict(filter_opts):
             code_error('passed non-dictionary for filter opts to get_ingestions')
         for key, value in sorted(filter_opts.items()):
             log.info("filter: '%s' = '%s'", key, value)
         settings = merge_dicts(settings, filter_opts)
     log.info('settings: %s', settings)
     log.info('querying Zaloni for ingestion history')
     (req, self.query_time) = self.req(url='{url_base}/ingestion/publish/getFileIndex'
                                       .format(url_base=self.url_base),
                                       # orders by newest first, but seems to return last 10 anyway
                                       body=json.dumps(settings))
     try:
         log.info('parsing JSON response')
         json_dict = json.loads(req.content)
     except ValueError as _:
         qquit('UNKNOWN', 'error parsing json returned by Zaloni: {0}'.format(_))
     return json_dict
Example #2
0
 def run(self):
     log.info('querying %s', self.software)
     url = '{protocol}://{host}:{port}/PolicyManagement/{api_version}/resources'\
           .format(host=self.host, port=self.port, api_version=self.api_version, protocol=self.protocol)
     log.debug('GET %s', url)
     try:
         req = requests.get(url,
                            auth=HTTPBasicAuth(self.user, self.password))
     except requests.exceptions.RequestException as _:
         errhint = ''
         if 'BadStatusLine' in str(_.message):
             errhint = ' (possibly connecting to an SSL secured port without using --ssl?)'
         elif self.protocol == 'https' and 'unknown protocol' in str(
                 _.message):
             errhint = ' (possibly connecting to a plain HTTP port with the -S / --ssl switch enabled?)'
         qquit('CRITICAL', str(_) + errhint)
     log.debug("response: %s %s", req.status_code, req.reason)
     log.debug("content:\n%s\n%s\n%s", '=' * 80, req.content.strip(),
               '=' * 80)
     if req.status_code != 200:
         qquit('CRITICAL', '{0}: {1}'.format(req.status_code, req.reason))
     try:
         json_dict = json.loads(req.content)
         if log.isEnabledFor(logging.DEBUG):
             print(jsonpp(json_dict))
             print('=' * 80)
         if not isDict(json_dict):
             raise ValueError(
                 "non-dict returned by Blue Talon API (got type '{0}')".
                 format(type(json_dict)))
         resource_domains_list = json_dict['resource_domains']
         if not isList(resource_domains_list):
             raise ValueError("non-list returned for 'resource_domains' key by Blue Talon API (got type '{0}')"\
                              .format(type(resource_domains_list)))
         num_resource_domains = len(resource_domains_list)
         num_resources = 0
         for resource_domain in resource_domains_list:
             resources = resource_domain['resources']
             if not isList(resources):
                 raise ValueError("non-list found for resources in resource_domain '{0}' (got type '{1}'"\
                                  .format(resource_domain['resource_domain_name'], type(resources)))
             num_resources += len(resources)
         self.msg += '{num_resources} resources'.format(
             num_resources=num_resources)
         self.check_thresholds(num_resources)
         self.msg += ' across {num_resource_domains} resource domains'\
                     .format(num_resource_domains=num_resource_domains)
         self.msg += ' | num_resources={num_resources}{perf} num_resource_domains={num_resource_domains}'\
                     .format(num_resources=num_resources,
                             num_resource_domains=num_resource_domains,
                             perf=self.get_perf_thresholds())
     except (KeyError, ValueError) as _:
         qquit('UNKNOWN', 'error parsing output from {software}: {exception}: {error}. {support_msg}'\
                          .format(software=self.software,
                                  exception=type(_).__name__,
                                  error=_,
                                  support_msg=support_msg_api()))
 def run(self):
     content = self.get()
     try:
         json_dict = json.loads(content)
         if log.isEnabledFor(logging.DEBUG):
             print(jsonpp(json_dict))
             print('=' * 80)
         if not isDict(json_dict):
             raise ValueError('returned content is not a dict')
         status = json_dict['status']
         if status != 'success':
             qquit(
                 'CRITICAL',
                 "request status = '{0}' (expected 'success')".format(
                     status))
         status_code = json_dict['statusCode']
         if status_code != 200:
             qquit(
                 'CRITICAL',
                 "request status code = '{0}' (expected '200')".format(
                     status_code))
         message = json_dict['message']
         data = json_dict['data']
         if not data:
             num_endpoints = 0
         elif not isList(data):
             qquit('CRITICAL',
                   'non-list returned for policy end points data')
         else:
             num_endpoints = len(data)
         match = re.match(
             message, r'Total [(\d+)] policy engine end point\(s\) found',
             re.I)
         if not match:
             raise ValueError(
                 'failed to parse message for confirmation of number of endpoints'
             )
         message_num_endpoints = int(match.group(1))
         if num_endpoints != message_num_endpoints:
             raise ValueError(
                 'num endpoints does not match parsed value from returned message'
             )
     except (KeyError, ValueError) as _:
         qquit('UNKNOWN', 'error parsing output from {software}: {exception}: {error}. {support_msg}'\
                          .format(software=self.software,
                                  exception=type(_).__name__,
                                  error=_,
                                  support_msg=support_msg_api()))
     self.msg = "{software} number of policy end points = {num_endpoints}"\
                .format(software=self.software, num_endpoints=num_endpoints)
     self.check_thresholds(num_endpoints)
     self.msg += ' | num_endpoints={num_endpoints}'.format(
         num_endpoints=num_endpoints) + self.get_perf_thresholds()
Example #4
0
 def parse_results(self, content):
     try:
         json_dict = json.loads(content)
         if log.isEnabledFor(logging.DEBUG):
             print(jsonpp(content))
             print('=' * 80)
         # looks like syshealthok child div is only there in browser, but give syshealthspin in code
         #if soup.find('div', id='syshealthstatus').find('div', id='syshealthok'):
         if not isDict(json_dict):
             raise ValueError("non-dict returned by Attivio AIE server response (type was '{0}')"\
                              .format(type(json_dict)))
         # if this is true from warnings would ruin the more appropriate warnings check
         #if json_dict['haserrors']:
         #    self.critical()
         #    self.msg += 'errors detected, '
         nodes_down = json_dict['nodesdown']
         warnings = json_dict['warnings']
         fatals = json_dict['fatals']
         acknowledged = json_dict['acknowledged']
         if not isInt(nodes_down):
             raise ValueError(
                 'non-integer returned for nodes down count by Attivio AIE')
         if not isInt(warnings):
             raise ValueError(
                 'non-integer returned for warnings count by Attivio AIE')
         if not isInt(fatals):
             raise ValueError(
                 'non-integer returned for fatals count by Attivio AIE')
         if not isInt(acknowledged):
             raise ValueError(
                 'non-integer returned for acknowledged count by Attivio AIE'
             )
         nodes_down = int(nodes_down)
         warnings = int(warnings)
         fatals = int(fatals)
         acknowledged = int(acknowledged)
         if nodes_down > 0 or fatals > 0:
             self.critical()
         elif warnings > 0:
             self.warning()
         self.msg += '{nodes_down} nodes down, {fatals} fatals, {warnings} warnings, {acknowledged} acknowledged'\
                     .format(nodes_down=nodes_down, fatals=fatals, warnings=warnings, acknowledged=acknowledged)
         if json_dict['perfmondown']:
             self.warning()
             self.msg += ', warning: performance monitoring down'
         self.msg += ' | nodes_down={nodes_down} fatals={fatals} warnings={warnings} acknowledged={acknowledged}'\
                     .format(nodes_down=nodes_down, fatals=fatals, warnings=warnings, acknowledged=acknowledged)
     except (KeyError, ValueError) as _:
         qquit('UNKNOWN', 'error parsing output from {software}: {exception}: {error}. {support_msg}'\
                          .format(software=self.software,
                                  exception=type(_).__name__,
                                  error=_,
                                  support_msg=support_msg_api()))
    def check_table(self):
        log.info('checking table \'%s\'', self.table)
        is_enabled = None
        families = None
        try:
            is_enabled = self.conn.is_table_enabled(self.table)
            log.info('enabled: %s', is_enabled)
            table = self.conn.table(self.table)
            families = table.families()
        except HBaseIOError as _:
            #if 'org.apache.hadoop.hbase.TableNotFoundException' in _.message:
            if 'TableNotFoundException' in _.message:
                qquit('CRITICAL',
                      'table \'{0}\' does not exist'.format(self.table))
            else:
                qquit('CRITICAL', _)
        except (socket.timeout, ThriftException) as _:
            qquit('CRITICAL', _)

        if log.isEnabledFor(logging.DEBUG):
            log.debug('column families:\n' + jsonpp(families))
        if not families:
            qquit(
                'CRITICAL',
                'failed to get column families for table \'{0}\''.format(
                    self.table))
        if not isDict(families):
            qquit(
                'UNKNOWN',
                'column family info returned was not a dictionary! ' +
                support_msg_api())
        num_families = len(families)
        log.info('num families: %s', num_families)

        self.msg = 'HBase table \'{0}\' is '.format(self.table)
        if is_enabled:
            self.msg += 'enabled, '
        else:
            self.critical()
            self.msg += 'disabled! '

        self.msg += '{0} column '.format(num_families)
        if num_families == 1:
            self.msg += 'family'
        else:
            self.msg += 'families'
        self.check_thresholds(num_families)

        self.msg += ' | num_column_families={0}'.format(
            num_families) + self.get_perf_thresholds(boundary='lower')
        log.info('finished, closing connection')
        self.conn.close()
 def run(self):
     log.info('querying %s', self.software)
     url = '{protocol}://{host}:{port}/PolicyManagement/{api_version}/resources'\
           .format(host=self.host, port=self.port, api_version=self.api_version, protocol=self.protocol)
     log.debug('GET %s', url)
     try:
         req = requests.get(url, auth=HTTPBasicAuth(self.user, self.password))
     except requests.exceptions.RequestException as _:
         errhint = ''
         if 'BadStatusLine' in str(_.message):
             errhint = ' (possibly connecting to an SSL secured port without using --ssl?)'
         elif self.protocol == 'https' and 'unknown protocol' in str(_.message):
             errhint = ' (possibly connecting to a plain HTTP port with the -S / --ssl switch enabled?)'
         qquit('CRITICAL', str(_) + errhint)
     log.debug("response: %s %s", req.status_code, req.reason)
     log.debug("content:\n%s\n%s\n%s", '='*80, req.content.strip(), '='*80)
     if req.status_code != 200:
         qquit('CRITICAL', '{0}: {1}'.format(req.status_code, req.reason))
     try:
         json_dict = json.loads(req.content)
         if log.isEnabledFor(logging.DEBUG):
             print(jsonpp(json_dict))
             print('='*80)
         if not isDict(json_dict):
             raise ValueError("non-dict returned by Blue Talon API (got type '{0}')".format(type(json_dict)))
         resource_domains_list = json_dict['resource_domains']
         if not isList(resource_domains_list):
             raise ValueError("non-list returned for 'resource_domains' key by Blue Talon API (got type '{0}')"\
                              .format(type(resource_domains_list)))
         num_resource_domains = len(resource_domains_list)
         num_resources = 0
         for resource_domain in resource_domains_list:
             resources = resource_domain['resources']
             if not isList(resources):
                 raise ValueError("non-list found for resources in resource_domain '{0}' (got type '{1}'"\
                                  .format(resource_domain['resource_domain_name'], type(resources)))
             num_resources += len(resources)
         self.msg += '{num_resources} resources'.format(num_resources=num_resources)
         self.check_thresholds(num_resources)
         self.msg += ' across {num_resource_domains} resource domains'\
                     .format(num_resource_domains=num_resource_domains)
         self.msg += ' | num_resources={num_resources}{perf} num_resource_domains={num_resource_domains}'\
                     .format(num_resources=num_resources,
                             num_resource_domains=num_resource_domains,
                             perf=self.get_perf_thresholds())
     except (KeyError, ValueError) as _:
         qquit('UNKNOWN', 'error parsing output from {software}: {exception}: {error}. {support_msg}'\
                          .format(software=self.software,
                                  exception=type(_).__name__,
                                  error=_,
                                  support_msg=support_msg_api()))
 def get_version(self):
     content = self.get()
     try:
         json_list = json.loads(content)
         if log.isEnabledFor(logging.DEBUG):
             print(jsonpp(json_list))
             print('=' * 80)
         if not isList(json_list):
             raise ValueError(
                 "non-list returned by API (is type '{0}')".format(
                     type(json_list)))
         json_dict = json_list[0]
         if not isDict(json_dict):
             raise ValueError(
                 "non-dict found inside returned list (is type '{0}')".
                 format(type(json_dict)))
         company_name = json_dict['company_name']
         company_website = json_dict['company_website']
         regex = re.compile(r'Blue\s*Talon', re.I)
         if not regex.match(company_name) and \
            not regex.match(company_website):
             qquit('UNKNOWN', 'Blue Talon name was not found in either company_name or company_website fields' \
                            + ', are you definitely querying a Blue Talon server?')
         build_version = json_dict['build_version']
         update_date = json_dict['update_date']
         api_version = json_dict['api_version']
         if not isVersion(api_version):
             qquit('UNKNOWN', '{0} api version unrecognized \'{1}\'. {2}'\
                              .format(self.software, api_version, support_msg_api()))
         if api_version != self.api_version:
             qquit('UNKNOWN', "unexpected API version '{0}' returned (expected '{1}')"\
                              .format(api_version, self.api_version))
         if self.verbose:
             extra_info = ' revision {revision} build {build}, schema revision = {schema_revision}'\
                           .format(revision=json_dict['revision_no'],
                                   build=json_dict['build_no'],
                                   schema_revision=json_dict['schema_revision'])
             extra_info += ', api version = {api_version}, update date = {update_date}'\
                           .format(api_version=api_version, update_date=update_date)
         else:
             extra_info = ', update date = {update_date}'.format(
                 update_date=update_date)
     except (KeyError, ValueError) as _:
         qquit('UNKNOWN', 'error parsing output from {software}: {exception}: {error}. {support_msg}'\
                          .format(software=self.software,
                                  exception=type(_).__name__,
                                  error=_,
                                  support_msg=support_msg_api()))
     return (build_version, extra_info)
 def parse_results(self, content):
     try:
         json_dict = json.loads(content)
         if log.isEnabledFor(logging.DEBUG):
             print(jsonpp(content))
             print('='*80)
         # looks like syshealthok child div is only there in browser, but give syshealthspin in code
         #if soup.find('div', id='syshealthstatus').find('div', id='syshealthok'):
         if not isDict(json_dict):
             raise ValueError("non-dict returned by Attivio AIE server response (type was '{0}')"\
                              .format(type(json_dict)))
         # if this is true from warnings would ruin the more appropriate warnings check
         #if json_dict['haserrors']:
         #    self.critical()
         #    self.msg += 'errors detected, '
         nodes_down = json_dict['nodesdown']
         warnings = json_dict['warnings']
         fatals = json_dict['fatals']
         acknowledged = json_dict['acknowledged']
         if not isInt(nodes_down):
             raise ValueError('non-integer returned for nodes down count by Attivio AIE')
         if not isInt(warnings):
             raise ValueError('non-integer returned for warnings count by Attivio AIE')
         if not isInt(fatals):
             raise ValueError('non-integer returned for fatals count by Attivio AIE')
         if not isInt(acknowledged):
             raise ValueError('non-integer returned for acknowledged count by Attivio AIE')
         nodes_down = int(nodes_down)
         warnings = int(warnings)
         fatals = int(fatals)
         acknowledged = int(acknowledged)
         if nodes_down > 0 or fatals > 0:
             self.critical()
         elif warnings > 0:
             self.warning()
         self.msg += '{nodes_down} nodes down, {fatals} fatals, {warnings} warnings, {acknowledged} acknowledged'\
                     .format(nodes_down=nodes_down, fatals=fatals, warnings=warnings, acknowledged=acknowledged)
         if json_dict['perfmondown']:
             self.warning()
             self.msg += ', warning: performance monitoring down'
         self.msg += ' | nodes_down={nodes_down} fatals={fatals} warnings={warnings} acknowledged={acknowledged}'\
                     .format(nodes_down=nodes_down, fatals=fatals, warnings=warnings, acknowledged=acknowledged)
     except (KeyError, ValueError) as _:
         qquit('UNKNOWN', 'error parsing output from {software}: {exception}: {error}. {support_msg}'\
                          .format(software=self.software,
                                  exception=type(_).__name__,
                                  error=_,
                                  support_msg=support_msg_api()))
 def check_queue(self, json_data):
     if not isDict(json_data):
         raise UnknownError("non-dict passed to check_queue(), got type '{0}".format(type(json_data)))
     if json_data['name'] != self.queue:
         raise CriticalError("queue name returned '{0}' does not match expected queue '{1}'"\
                             .format(json_data['name'], self.queue))
     self.msg += 'exists'
     state = json_data['state']
     self.msg += ", state = '{0}'".format(state)
     if state != self.expected_queue_state:
         self.msg += " (expected '{0}')".format(self.expected_queue_state)
     queue_durable = str(json_data['durable']).lower()
     self.msg += ', durable = {0}'.format(queue_durable)
     if self.expected_durable and self.expected_durable != queue_durable:
         self.critical()
         self.msg += " (expected '{0}')".format(self.expected_durable)
Example #10
0
 def check_exchange(self, json_data):
     if not isDict(json_data):
         raise UnknownError("non-dict passed to check_exchange), got type '{0}".format(type(json_data)))
     if json_data['name'] != self.exchange:
         raise CriticalError("exchange name returned '{0}' does not match expected exchange '{1}'"\
                             .format(json_data['name'], self.exchange))
     self.msg += 'exists'
     exchange_type = str(json_data['type']).lower()
     self.msg += ', type = {0}'.format(exchange_type)
     if self.expected_type and self.expected_type != exchange_type:
         self.critical()
         self.msg += " (expected '{0}')".format(self.expected_type)
     exchange_durable = str(json_data['durable']).lower()
     self.msg += ', durable = {0}'.format(exchange_durable)
     if self.expected_durable and self.expected_durable != exchange_durable:
         self.critical()
         self.msg += " (expected '{0}')".format(self.expected_durable)
Example #11
0
 def parse_json(self, json_data):
     if not isDict(json_data):
         raise UnknownError('non-dict returned for hot threads. {}'.format(support_msg_api()))
     hot_threads = json_data['hot_threads']['threads']
     top_3 = self.get_opt('top_3')
     sum_percent = 0
     last_percent = None
     for thread in hot_threads:
         thread_percent = thread['percent_of_cpu_time']
         if last_percent is None:
             last_percent = thread_percent
         if thread_percent > last_percent:
             raise UnknownError('assertion failure - subsequent thread percent is unexpectedly higher' + \
                                ', out of expected order. {}'.format(support_msg_api()))
         sum_percent += thread_percent
     self.msg = 'Logstash '
     if top_3:
         self.msg += 'top 3 hot threads cpu percentage = {}%'.format(sum_percent)
         self.check_thresholds(sum_percent)
         self.msg += ', '
     # they come sorted with highest at top
     top_thread = hot_threads[0]
     name = top_thread['name']
     percent = top_thread['percent_of_cpu_time']
     state = top_thread['state']
     # not available in 5.0, only later versions such as 6.0
     #thread_id = top_thread['thread_id']
     self.msg += 'top hot thread \'{}\' cpu percentage = {}%'.format(name, percent)
     if not top_3:
         self.check_thresholds(percent)
     self.msg += ', state = \'{}\''.format(state)
     #self.msg += ', id = {}'.format(state, thread_id)
     if self.verbose:
         if not isList(top_thread['traces']):
             raise UnknownError('hot thread\'s trace field is not a list. {}'.format(support_msg_api()))
         traces = '\\n'.join(top_thread['traces'])
         self.msg += ', traces: {}'.format(traces)
     if not top_3:
         self.msg += ', top 3 hot threads cpu percentage = {}%'.format(sum_percent)
     self.msg += ' | top_hot_thread_cpu_percentage={}%'.format(percent)
     if not top_3:
         self.msg += '{}'.format(self.get_perf_thresholds())
     self.msg += ' top_three_hot_thread_cpu_percentage={}%'.format(sum_percent)
     if top_3:
         self.msg += '{}'.format(self.get_perf_thresholds())
Example #12
0
 def check_queue(self, json_data):
     if not isDict(json_data):
         raise UnknownError(
             "non-dict passed to check_queue(), got type '{0}".format(
                 type(json_data)))
     if json_data['name'] != self.queue:
         raise CriticalError("queue name returned '{0}' does not match expected queue '{1}'"\
                             .format(json_data['name'], self.queue))
     self.msg += 'exists'
     state = json_data['state']
     self.msg += ", state = '{0}'".format(state)
     if state != self.expected_queue_state:
         self.msg += " (expected '{0}')".format(self.expected_queue_state)
     queue_durable = str(json_data['durable']).lower()
     self.msg += ', durable = {0}'.format(queue_durable)
     if self.expected_durable and self.expected_durable != queue_durable:
         self.critical()
         self.msg += " (expected '{0}')".format(self.expected_durable)
    def check_table(self):
        log.info('checking table \'%s\'', self.table)
        is_enabled = None
        families = None
        try:
            is_enabled = self.conn.is_table_enabled(self.table)
            log.info('enabled: %s', is_enabled)
            table = self.conn.table(self.table)
            families = table.families()
        except HBaseIOError as _:
            #if 'org.apache.hadoop.hbase.TableNotFoundException' in _.message:
            if 'TableNotFoundException' in _.message:
                qquit('CRITICAL', 'table \'{0}\' does not exist'.format(self.table))
            else:
                qquit('CRITICAL', _)
        except (socket.error, socket.timeout, ThriftException) as _:
            qquit('CRITICAL', _)

        if log.isEnabledFor(logging.DEBUG):
            log.debug('column families:\n%s', jsonpp(families))
        if not families:
            qquit('CRITICAL', 'failed to get column families for table \'{0}\''.format(self.table))
        if not isDict(families):
            qquit('UNKNOWN', 'column family info returned was not a dictionary! ' + support_msg_api())
        num_families = len(families)
        log.info('num families: %s', num_families)

        self.msg = 'HBase table \'{0}\' is '.format(self.table)
        if is_enabled:
            self.msg += 'enabled, '
        else:
            self.critical()
            self.msg += 'disabled! '

        self.msg += '{0} column '.format(num_families)
        if num_families == 1:
            self.msg += 'family'
        else:
            self.msg += 'families'
        self.check_thresholds(num_families)

        self.msg += ' | num_column_families={0}'.format(num_families) + self.get_perf_thresholds(boundary='lower')
        log.info('finished, closing connection')
        self.conn.close()
 def get_version(self):
     content = self.get()
     try:
         json_list = json.loads(content)
         if log.isEnabledFor(logging.DEBUG):
             print(jsonpp(json_list))
             print('='*80)
         if not isList(json_list):
             raise ValueError("non-list returned by API (is type '{0}')".format(type(json_list)))
         json_dict = json_list[0]
         if not isDict(json_dict):
             raise ValueError("non-dict found inside returned list (is type '{0}')".format(type(json_dict)))
         company_name = json_dict['company_name']
         company_website = json_dict['company_website']
         regex = re.compile(r'Blue\s*Talon', re.I)
         if not regex.match(company_name) and \
            not regex.match(company_website):
             qquit('UNKNOWN', 'Blue Talon name was not found in either company_name or company_website fields' \
                            + ', are you definitely querying a Blue Talon server?')
         build_version = json_dict['build_version']
         update_date = json_dict['update_date']
         api_version = json_dict['api_version']
         if not isVersion(api_version):
             qquit('UNKNOWN', '{0} api version unrecognized \'{1}\'. {2}'\
                              .format(self.software, api_version, support_msg_api()))
         if api_version != self.api_version:
             qquit('UNKNOWN', "unexpected API version '{0}' returned (expected '{1}')"\
                              .format(api_version, self.api_version))
         if self.verbose:
             extra_info = ' revision {revision} build {build}, schema revision = {schema_revision}'\
                           .format(revision=json_dict['revision_no'],
                                   build=json_dict['build_no'],
                                   schema_revision=json_dict['schema_revision'])
             extra_info += ', api version = {api_version}, update date = {update_date}'\
                           .format(api_version=api_version, update_date=update_date)
         else:
             extra_info = ', update date = {update_date}'.format(update_date=update_date)
     except (KeyError, ValueError) as _:
         qquit('UNKNOWN', 'error parsing output from {software}: {exception}: {error}. {support_msg}'\
                          .format(software=self.software,
                                  exception=type(_).__name__,
                                  error=_,
                                  support_msg=support_msg_api()))
     return (build_version, extra_info)
 def parse_metrics(self, json_struct):
     if not isList(json_struct):
         raise ValueError("non-list returned by Attivio AIE Perfmon metrics API (got type '{0}')"\
                          .format(type(json_struct)))
     metrics = {}
     if not json_struct:
         qquit('UNKNOWN', "no matching metrics found for '{0}'".format(self.metrics) + \
                          ", use --list-metrics to check you've specified a correct metric")
     for item in json_struct:
         if not isDict(item):
             raise ValueError("non-dict item found in list returned by Attivio AIE Perfmon API (got type '{0}')"\
                              .format(type(item)))
         if not isList(item['values']):
             raise ValueError("non-list returned for metric value by Attivio AIE Perfmon API (got type '{0}')"\
                              .format(type(item['values'])))
         metric = item['metric']
         log.info('metric = %s', metric)
         if self.skip_metric(item):
             log.info('skipping metric %s due to filters', metric)
             continue
         for key in ('nodeset', 'hostname', 'workflowType', 'workflow',
                     'component', 'path', 'networkInterface'):
             if key in item:
                 val = item[key]
                 log.info('%s = %s', key, val)
                 # Attivio returns network interfaces in form "lo - 127.0.0.1"
                 if key == 'networkInterface':
                     val = val.split()[0]
                 metric += '.{0}'.format(val)
         value = item['values'][0]
         log.info('value = %s\n', value)
         if self.precision and isFloat(value):
             # leaving as string will result in lots of trailing zeros
             value = float('{value:.{precision}f}'.format(
                 value=value, precision=self.precision))
         if metric in metrics:
             qquit('UNKNOWN', "duplicate metric '{metric}' discovered! {support_msg}"\
                              .format(metric=metric, support_msg=support_msg_api()))
         metrics[metric] = value
     return metrics
 def run(self):
     content = self.get()
     try:
         json_dict = json.loads(content)
         if log.isEnabledFor(logging.DEBUG):
             print(jsonpp(json_dict))
             print('='*80)
         if not isDict(json_dict):
             raise ValueError('returned content is not a dict')
         status = json_dict['status']
         if status != 'success':
             qquit('CRITICAL', "request status = '{0}' (expected 'success')".format(status))
         status_code = json_dict['statusCode']
         if status_code != 200:
             qquit('CRITICAL', "request status code = '{0}' (expected '200')".format(status_code))
         message = json_dict['message']
         data = json_dict['data']
         if not data:
             num_endpoints = 0
         elif not isList(data):
             qquit('CRITICAL', 'non-list returned for policy end points data')
         else:
             num_endpoints = len(data)
         match = re.match(message, r'Total [(\d+)] policy engine end point\(s\) found', re.I)
         if not match:
             raise ValueError('failed to parse message for confirmation of number of endpoints')
         message_num_endpoints = int(match.group(1))
         if num_endpoints != message_num_endpoints:
             raise ValueError('num endpoints does not match parsed value from returned message')
     except (KeyError, ValueError) as _:
         qquit('UNKNOWN', 'error parsing output from {software}: {exception}: {error}. {support_msg}'\
                          .format(software=self.software,
                                  exception=type(_).__name__,
                                  error=_,
                                  support_msg=support_msg_api()))
     self.msg = "{software} number of policy end points = {num_endpoints}"\
                .format(software=self.software, num_endpoints=num_endpoints)
     self.check_thresholds(num_endpoints)
     self.msg += ' | num_endpoints={num_endpoints}'.format(num_endpoints=num_endpoints) + self.get_perf_thresholds()
 def parse_metrics(self, json_struct):
     if not isList(json_struct):
         raise ValueError("non-list returned by Attivio AIE Perfmon metrics API (got type '{0}')"\
                          .format(type(json_struct)))
     metrics = {}
     if not json_struct:
         qquit('UNKNOWN', "no matching metrics found for '{0}'".format(self.metrics) + \
                          ", use --list-metrics to check you've specified a correct metric")
     for item in json_struct:
         if not isDict(item):
             raise ValueError("non-dict item found in list returned by Attivio AIE Perfmon API (got type '{0}')"\
                              .format(type(item)))
         if not isList(item['values']):
             raise ValueError("non-list returned for metric value by Attivio AIE Perfmon API (got type '{0}')"\
                              .format(type(item['values'])))
         metric = item['metric']
         log.info('metric = %s', metric)
         if self.skip_metric(item):
             log.info('skipping metric %s due to filters', metric)
             continue
         for key in ('nodeset', 'hostname', 'workflowType', 'workflow', 'component', 'path', 'networkInterface'):
             if key in item:
                 val = item[key]
                 log.info('%s = %s', key, val)
                 # Attivio returns network interfaces in form "lo - 127.0.0.1"
                 if key == 'networkInterface':
                     val = val.split()[0]
                 metric += '.{0}'.format(val)
         value = item['values'][0]
         log.info('value = %s\n', value)
         if self.precision and isFloat(value):
             # leaving as string will result in lots of trailing zeros
             value = float('{value:.{precision}f}'.format(value=value, precision=self.precision))
         if metric in metrics:
             qquit('UNKNOWN', "duplicate metric '{metric}' discovered! {support_msg}"\
                              .format(metric=metric, support_msg=support_msg_api()))
         metrics[metric] = value
     return metrics