def test_getName(self): alert_meta = {'name': 'ambari'} alert_source_meta = {} alert = BaseAlert(alert_meta, alert_source_meta, self.config) name = alert.get_name() self.assertEquals(name, 'ambari')
def test_getUuid(self): alert_meta = {'uuid': '123'} alert_source_meta = {} alert = BaseAlert(alert_meta, alert_source_meta, self.config) uuid = alert.get_uuid() self.assertEquals(uuid, '123')
def test_interval(self): alert_meta = {'interval': 5} alert_source_meta = {} alert = BaseAlert(alert_meta, alert_source_meta, self.config) interval = alert.interval() self.assertEquals(interval, 5)
def test_interval_zero(self): alert_meta = {'interval': 0} alert_source_meta = {} alert = BaseAlert(alert_meta, alert_source_meta) interval = alert.interval() self.assertEquals(interval, 1)
def test_isEnabled(self): alert_meta = {'enabled': 'true'} alert_source_meta = {} alert = BaseAlert(alert_meta, alert_source_meta, self.config) enabled = alert.is_enabled() self.assertEquals(enabled, 'true')
def test_setCluster(self): alert_meta = {} alert_source_meta = {} cluster = 'cluster' host = 'host' alert = BaseAlert(alert_meta, alert_source_meta, self.config) alert.set_cluster(cluster, host) self.assertEquals(alert.cluster_name, cluster) self.assertEquals(alert.host_name, host)
def _collect(self): if self.metric_info is None: raise Exception( "Could not determine result. Specific metric collector is not defined." ) uri = self._lookup_property_value(self.uri) host = BaseAlert.get_host_from_url(uri) if host is None: host = self.host_name port = 80 # probably not very realistic try: port = int(get_port_from_url(uri)) except: pass collect_result = None check_value = None value_list = [] if isinstance(self.metric_info, JmxMetric): value_list.extend( self._load_jmx(False, host, port, self.metric_info)) 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) logger.debug("Resolved value list is: {0}".format(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 # start building the URL manually host = BaseAlert.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) return "{0}://{1}:{2}".format(scheme, host, str(port))
def _collect(self): urivalue = self._lookup_property_value(self.uri) port = self.port host = BaseAlert.get_host_from_url(urivalue) if host is None: host = self.host_name try: port = int(get_port_from_url(urivalue)) except: # if port not found, default port already set to port pass if logger.isEnabledFor(logging.DEBUG): logger.debug("checking {0} listening on port {1}".format(host, str(port))) try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(1.5) t = time.time() s.connect((host, port)) millis = time.time() - t return (self.RESULT_OK, [millis/1000, port]) except Exception as e: return (self.RESULT_CRITICAL, [str(e), host, port]) finally: if s is not None: try: s.close() except: pass
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 = BaseAlert.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 _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) 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 = BaseAlert.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) logger.debug("[Alert][{0}] Computed result = {1}".format(self.get_name(), str(value_list))) return (collect_result, value_list)
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 = BaseAlert.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 check_value = None value_list = [] if isinstance(self.metric_info, JmxMetric): value_list.extend( self._load_jmx(alert_uri.is_ssl_enabled, host, port, self.metric_info)) 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) logger.debug("[Alert][{0}] Resolved values = {1}".format( self.get_name(), str(value_list))) return (collect_result, value_list)
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 = BaseAlert.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) 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 = BaseAlert.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): 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 = BaseAlert.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): value_list.extend(self._load_jmx(alert_uri.is_ssl_enabled, host, port, self.metric_info)) 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) logger.debug("[Alert][{0}] Resolved values = {1}".format( self.get_name(), str(value_list))) return (collect_result, value_list)
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) if uri_value is None: 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 = BaseAlert.get_host_from_url(uri_value) if host is None: host = self.host_name 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 if logger.isEnabledFor(logging.DEBUG): logger.debug("[Alert][{0}] Checking {1} on port {2}".format( self.get_name(), host, str(port))) 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)) 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: return (self.RESULT_CRITICAL, [str(e), host, port]) finally: if s is not None: try: s.close() except: # no need to log a close failure pass
"License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ''' from unittest import TestCase from alerts.base_alert import BaseAlert alert = BaseAlert({}, {}) class TestBaseAlert(TestCase): def test_interval_noData(self): alert_meta = {} alert_source_meta = {} alert = BaseAlert(alert_meta, alert_source_meta) interval = alert.interval() self.assertEquals(interval, 1) def test_interval_zero(self): alert_meta = {'interval': 0} alert_source_meta = {}
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 = BaseAlert.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])
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) 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 = BaseAlert.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 ) logger.debug("[Alert][{0}] Computed result = {1}".format( self.get_name(), str(value_list))) return (collect_result, value_list)