def _collect(self): if self.metric_info is None: raise Exception( "Could not determine result. Specific metric collector is not defined." ) if self.uri_property_keys is None: raise Exception( "Could not determine result. URL(s) were not defined.") # use the URI lookup keys to get a final URI value to query alert_uri = self._get_uri_from_structure(self.uri_property_keys) logger.debug( "[Alert][{0}] Calculated metric URI to be {1} (ssl={2})".format( self.get_name(), alert_uri.uri, str(alert_uri.is_ssl_enabled))) host = inet_utils.get_host_from_url(alert_uri.uri) if host is None: host = self.host_name port = 80 # probably not very realistic try: port = int(get_port_from_url(alert_uri.uri)) except: pass collect_result = None value_list = [] if isinstance(self.metric_info, JmxMetric): jmx_property_values, http_code = self._load_jmx( alert_uri.is_ssl_enabled, host, port, self.metric_info) if not jmx_property_values and http_code in [200, 307]: collect_result = self.RESULT_UNKNOWN value_list.append( 'HTTP {0} response (metrics unavailable)'.format( str(http_code))) elif not jmx_property_values and http_code not in [200, 307]: raise Exception( "[Alert][{0}] Unable to extract JSON from JMX response". format(self.get_name())) else: value_list.extend(jmx_property_values) check_value = self.metric_info.calculate(value_list) value_list.append(check_value) collect_result = self._get_result( value_list[0] if check_value is None else check_value) if logger.isEnabledFor(logging.DEBUG): logger.debug("[Alert][{0}] Resolved values = {1}".format( self.get_name(), str(value_list))) return (collect_result, value_list)
def _build_web_query(self, alert_uri): """ Builds a URL out of the URI structure. If the URI is already a URL of the form http[s]:// then this will return the URI as the URL; otherwise, it will build the URL from the URI structure's elements """ # shortcut if the supplied URI starts with the information needed string_uri = str(alert_uri.uri) if string_uri.startswith('http://') or string_uri.startswith( 'https://'): return alert_uri.uri uri_path = None if string_uri and string_uri != str(None): uri_path = get_path_from_url(string_uri) # start building the URL manually host = get_host_from_url(alert_uri.uri) if host is None: host = self.host_name # maybe slightly realistic port = 80 if alert_uri.is_ssl_enabled is True: port = 443 # extract the port try: port = int(get_port_from_url(alert_uri.uri)) except: pass scheme = 'http' if alert_uri.is_ssl_enabled is True: scheme = 'https' if OSCheck.is_windows_family(): # on windows 0.0.0.0 is invalid address to connect but on linux it resolved to 127.0.0.1 host = resolve_address(host) if uri_path: return "{0}://{1}:{2}/{3}".format(scheme, host, str(port), uri_path) else: return "{0}://{1}:{2}".format(scheme, host, str(port))
def _collect(self): """ Low level function to collect alert data. The result is a tuple as: res[0] = the result code res[1] = the list of arguments supplied to the reporting text for the result code """ if self.metric_info is None: raise Exception( "Could not determine result. Specific metric collector is not defined." ) if self.uri_property_keys is None: raise Exception( "Could not determine result. URL(s) were not defined.") # use the URI lookup keys to get a final URI value to query alert_uri = self._get_uri_from_structure(self.uri_property_keys) if logger.isEnabledFor(logging.DEBUG): logger.debug( "[Alert][{0}] Calculated metric URI to be {1} (ssl={2})". format(self.get_name(), alert_uri.uri, str(alert_uri.is_ssl_enabled))) host = inet_utils.get_host_from_url(alert_uri.uri) if host is None: host = self.host_name try: port = int(get_port_from_url(alert_uri.uri)) except: port = 6188 collect_result = None value_list = [] if isinstance(self.metric_info, AmsMetric): raw_data_points, http_code = self._load_metric( alert_uri.is_ssl_enabled, host, port, self.metric_info) if not raw_data_points and http_code not in [200, 307]: collect_result = self.RESULT_UNKNOWN value_list.append( 'HTTP {0} response (metrics unavailable)'.format( str(http_code))) elif not raw_data_points and http_code in [200, 307]: raise Exception( "[Alert][{0}] Unable to extract JSON from HTTP response". format(self.get_name())) else: data_points = self.metric_info.calculate_value(raw_data_points) compute_result = self.metric_info.calculate_compute( data_points) value_list.append(compute_result) collect_result = self._get_result( value_list[0] if compute_result is None else compute_result ) if logger.isEnabledFor(logging.DEBUG): logger.debug("[Alert][{0}] Computed result = {1}".format( self.get_name(), str(value_list))) return (collect_result, value_list)
def hostname(self): return inet_utils.get_host_from_url(self.address)
def _collect(self): # can be parameterized or static # if not parameterized, this will return the static value uri_value = self._get_configuration_value(self.uri) host_not_specified = False if uri_value is None: host_not_specified = True uri_value = self.host_name logger.debug( "[Alert][{0}] Setting the URI to this host since it wasn't specified" .format(self.get_name())) # in some cases, a single property is a comma-separated list like # host1:8080,host2:8081,host3:8083 uri_value_array = uri_value.split(',') if len(uri_value_array) > 1: for item in uri_value_array: if self.host_name in item: uri_value = item if logger.isEnabledFor(logging.DEBUG): logger.debug( "[Alert][{0}] Extracted {1} as the host name while parsing the CSV URI {2}" .format(self.get_name(), uri_value, str(uri_value_array))) break host = get_host_from_url(uri_value) if host is None or host == "localhost" or host == "0.0.0.0": host = self.host_name host_not_specified = True hosts = [host] # If host is not specified in the uri, hence we are using current host name # then also add public host name as a fallback. if host_not_specified and host.lower() == self.host_name.lower() \ and self.host_name.lower() != self.public_host_name.lower(): hosts.append(self.public_host_name) if logger.isEnabledFor(logging.DEBUG): logger.debug("[Alert][{0}] List of hosts = {1}".format( self.get_name(), hosts)) try: port = int(get_port_from_url(uri_value)) except: if self.default_port is None: label = 'Unable to determine port from URI {0}'.format( uri_value) return (self.RESULT_UNKNOWN, [label]) port = self.default_port exceptions = [] for host in hosts: if logger.isEnabledFor(logging.DEBUG): logger.debug("[Alert][{0}] Checking {1} on port {2}".format( self.get_name(), host, str(port))) s = None try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(self.critical_timeout) if OSCheck.is_windows_family(): # on windows 0.0.0.0 is invalid address to connect but on linux it resolved to 127.0.0.1 host = resolve_address(host) start_time = time.time() s.connect((host, port)) if self.socket_command is not None: s.sendall(self.socket_command) data = s.recv(1024) if self.socket_command_response is not None and data != self.socket_command_response: raise Exception( "Expected response {0}, Actual response {1}". format(self.socket_command_response, data)) end_time = time.time() milliseconds = end_time - start_time seconds = milliseconds / 1000.0 # not sure why this happens sometimes, but we don't always get a # socket exception if the connect() is > than the critical threshold if seconds >= self.critical_timeout: return (self.RESULT_CRITICAL, ['Socket Timeout', host, port]) result = self.RESULT_OK if seconds >= self.warning_timeout: result = self.RESULT_WARNING return (result, [seconds, port]) except Exception as e: exceptions.append(e) finally: if s is not None: try: s.close() except: # no need to log a close failure pass if exceptions: return (self.RESULT_CRITICAL, [str(exceptions[0]), hosts[0], port])