From e5884a963bf7239d6a0c580ef8f101834e7f3242 Mon Sep 17 00:00:00 2001 From: licanwei Date: Thu, 10 Oct 2019 20:21:28 -0700 Subject: [PATCH] Don't throw exception when missing metrics When querying data from datasource, it's possible to miss some data. In this case if we throw an exception, Audit will failed because of the exception. We should remove the exception and give the decision to the strategy. Change-Id: I1b0e6b78b3bba4df9ba16e093b3910aab1de922e Closes-Bug: #1847434 (cherry picked from commit f685bf62abf5c37765d8bc48b4cdb38df2147190) --- watcher/decision_engine/datasources/base.py | 3 --- .../decision_engine/datasources/ceilometer.py | 13 ++++++------ .../decision_engine/datasources/gnocchi.py | 21 ++++++++++--------- .../decision_engine/datasources/grafana.py | 3 +++ .../decision_engine/datasources/monasca.py | 8 +++---- .../decision_engine/datasources/test_base.py | 6 ++---- .../datasources/test_grafana_helper.py | 6 +----- 7 files changed, 27 insertions(+), 33 deletions(-) diff --git a/watcher/decision_engine/datasources/base.py b/watcher/decision_engine/datasources/base.py index 6656afef7..414ecffd0 100644 --- a/watcher/decision_engine/datasources/base.py +++ b/watcher/decision_engine/datasources/base.py @@ -19,8 +19,6 @@ import time from oslo_config import cfg from oslo_log import log -from watcher.common import exception - CONF = cfg.CONF LOG = log.getLogger(__name__) @@ -79,7 +77,6 @@ class DataSourceBase(object): LOG.warning("Retry {0} of {1} while retrieving metrics retry " "in {2} seconds".format(i+1, num_retries, timeout)) time.sleep(timeout) - raise exception.DataSourceNotAvailable(datasource=self.NAME) @abc.abstractmethod def query_retry_reset(self, exception_instance): diff --git a/watcher/decision_engine/datasources/ceilometer.py b/watcher/decision_engine/datasources/ceilometer.py index c1a041db1..d6f294aae 100644 --- a/watcher/decision_engine/datasources/ceilometer.py +++ b/watcher/decision_engine/datasources/ceilometer.py @@ -136,19 +136,18 @@ class CeilometerHelper(base.DataSourceBase): def list_metrics(self): """List the user's meters.""" - try: - meters = self.query_retry(f=self.ceilometer.meters.list) - except Exception: + meters = self.query_retry(f=self.ceilometer.meters.list) + if not meters: return set() else: return meters def check_availability(self): - try: - self.query_retry(self.ceilometer.resources.list) - except Exception: + status = self.query_retry(self.ceilometer.resources.list) + if status: + return 'available' + else: return 'not available' - return 'available' def query_sample(self, meter_name, query, limit=1): return self.query_retry(f=self.ceilometer.samples.list, diff --git a/watcher/decision_engine/datasources/gnocchi.py b/watcher/decision_engine/datasources/gnocchi.py index 54541f1a1..26e275432 100644 --- a/watcher/decision_engine/datasources/gnocchi.py +++ b/watcher/decision_engine/datasources/gnocchi.py @@ -52,17 +52,16 @@ class GnocchiHelper(base.DataSourceBase): self.gnocchi = self.osc.gnocchi() def check_availability(self): - try: - self.query_retry(self.gnocchi.status.get) - except Exception: + status = self.query_retry(self.gnocchi.status.get) + if status: + return 'available' + else: return 'not available' - return 'available' def list_metrics(self): """List the user's meters.""" - try: - response = self.query_retry(f=self.gnocchi.metric.list) - except Exception: + response = self.query_retry(f=self.gnocchi.metric.list) + if not response: return set() else: return set([metric['name'] for metric in response]) @@ -91,8 +90,9 @@ class GnocchiHelper(base.DataSourceBase): f=self.gnocchi.resource.search, **kwargs) if not resources: - raise exception.ResourceNotFound(name='gnocchi', - id=resource_id) + LOG.warning("The {0} resource {1} could not be " + "found".format(self.NAME, resource_id)) + return resource_id = resources[0]['id'] @@ -110,6 +110,7 @@ class GnocchiHelper(base.DataSourceBase): statistics = self.query_retry( f=self.gnocchi.metric.get_measures, **kwargs) + return_value = None if statistics: # return value of latest measure # measure has structure [time, granularity, value] @@ -120,7 +121,7 @@ class GnocchiHelper(base.DataSourceBase): # 1/10 th of actual CFM return_value *= 10 - return return_value + return return_value def get_host_cpu_usage(self, resource, period, aggregate, granularity=300): diff --git a/watcher/decision_engine/datasources/grafana.py b/watcher/decision_engine/datasources/grafana.py index e384d18f4..af301ae7a 100644 --- a/watcher/decision_engine/datasources/grafana.py +++ b/watcher/decision_engine/datasources/grafana.py @@ -179,6 +179,9 @@ class GrafanaHelper(base.DataSourceBase): kwargs = {k: v for k, v in raw_kwargs.items() if k and v} resp = self.query_retry(self._request, **kwargs) + if not resp: + LOG.warning("Datasource {0} is not available.".format(self.NAME)) + return result = translator.extract_result(resp.content) diff --git a/watcher/decision_engine/datasources/monasca.py b/watcher/decision_engine/datasources/monasca.py index 7600c7e69..bd141eea3 100644 --- a/watcher/decision_engine/datasources/monasca.py +++ b/watcher/decision_engine/datasources/monasca.py @@ -73,11 +73,11 @@ class MonascaHelper(base.DataSourceBase): self.monasca = self.osc.monasca() def check_availability(self): - try: - self.query_retry(self.monasca.metrics.list) - except Exception: + result = self.query_retry(self.monasca.metrics.list) + if result: + return 'available' + else: return 'not available' - return 'available' def list_metrics(self): # TODO(alexchadin): this method should be implemented in accordance to diff --git a/watcher/tests/decision_engine/datasources/test_base.py b/watcher/tests/decision_engine/datasources/test_base.py index 1ce495c64..ac73c42a6 100644 --- a/watcher/tests/decision_engine/datasources/test_base.py +++ b/watcher/tests/decision_engine/datasources/test_base.py @@ -19,7 +19,6 @@ import mock from oslo_config import cfg -from watcher.common import exception from watcher.decision_engine.datasources import base as datasource from watcher.tests import base @@ -61,9 +60,8 @@ class TestBaseDatasourceHelper(base.BaseTestCase): helper = datasource.DataSourceBase() helper.query_retry_reset = mock.Mock() - # Maximum number of retries exceeded query_retry should raise error - self.assertRaises(exception.DataSourceNotAvailable, - helper.query_retry, f=method) + # Maximum number of retries exceeded query_retry should return None + self.assertIsNone(helper.query_retry(f=method)) # query_retry_reset should be called twice helper.query_retry_reset.assert_has_calls( [mock.call(exc), mock.call(exc)]) diff --git a/watcher/tests/decision_engine/datasources/test_grafana_helper.py b/watcher/tests/decision_engine/datasources/test_grafana_helper.py index ee80358a9..a0204ded2 100644 --- a/watcher/tests/decision_engine/datasources/test_grafana_helper.py +++ b/watcher/tests/decision_engine/datasources/test_grafana_helper.py @@ -132,11 +132,7 @@ class TestGrafana(base.BaseTestCase): t_grafana = grafana.GrafanaHelper(osc=mock.Mock()) - self.assertRaises( - exception.DataSourceNotAvailable, - t_grafana.get_host_cpu_usage, - self.m_compute_node - ) + self.assertIsNone(t_grafana.get_host_cpu_usage(self.m_compute_node)) def test_no_metric_raise_error(self): """Test raising error when specified meter does not exist"""