Merge "Handle driver initialization errors to avoid service crash"
This commit is contained in:
commit
e022fdaa8e
@ -36,9 +36,9 @@ class ElasticsearchDriver(base.Driver):
|
||||
from elasticsearch import Elasticsearch
|
||||
except ImportError:
|
||||
raise exc.CommandError(
|
||||
"To use this command, you should install "
|
||||
"'elasticsearch' manually. Use command:\n "
|
||||
"'pip install elasticsearch'.")
|
||||
"To use OSProfiler with ElasticSearch driver, "
|
||||
"please install `elasticsearch` library. "
|
||||
"To install with pip:\n `pip install elasticsearch`.")
|
||||
|
||||
client_url = parser.urlunparse(parser.urlparse(self.connection_str)
|
||||
._replace(scheme="http"))
|
||||
|
@ -40,8 +40,8 @@ class Jaeger(base.Driver):
|
||||
except ImportError:
|
||||
raise exc.CommandError(
|
||||
"To use OSProfiler with Uber Jaeger tracer, "
|
||||
"you have to install `jaeger-client` manually. "
|
||||
"Install with pip:\n `pip install jaeger-client`."
|
||||
"please install `jaeger-client` library. "
|
||||
"To install with pip:\n `pip install jaeger-client`."
|
||||
)
|
||||
|
||||
parsed_url = parser.urlparse(connection_str)
|
||||
|
@ -28,9 +28,9 @@ class MongoDB(base.Driver):
|
||||
from pymongo import MongoClient
|
||||
except ImportError:
|
||||
raise exc.CommandError(
|
||||
"To use this command, you should install "
|
||||
"'pymongo' manually. Use command:\n "
|
||||
"'pip install pymongo'.")
|
||||
"To use OSProfiler with MongoDB driver, "
|
||||
"please install `pymongo` library. "
|
||||
"To install with pip:\n `pip install pymongo`.")
|
||||
|
||||
client = MongoClient(self.connection_str, connect=False)
|
||||
self.db = client[db_name]
|
||||
|
@ -40,9 +40,9 @@ class Redis(base.Driver):
|
||||
from redis import StrictRedis
|
||||
except ImportError:
|
||||
raise exc.CommandError(
|
||||
"To use this command, you should install "
|
||||
"'redis' manually. Use command:\n "
|
||||
"'pip install redis'.")
|
||||
"To use OSProfiler with Redis driver, "
|
||||
"please install `redis` library. "
|
||||
"To install with pip:\n `pip install redis`.")
|
||||
|
||||
# only connection over network is supported with schema
|
||||
# redis://[:password]@host[:port][/db]
|
||||
|
@ -13,16 +13,21 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import logging
|
||||
|
||||
from osprofiler.drivers import base
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _noop_notifier(info, context=None):
|
||||
"""Do nothing on notify()."""
|
||||
|
||||
|
||||
# NOTE(boris-42): By default we are using noop notifier.
|
||||
__notifier = _noop_notifier
|
||||
__driver_cache = {}
|
||||
__notifier_cache = {} # map: connection-string -> notifier
|
||||
|
||||
|
||||
def notify(info):
|
||||
@ -54,14 +59,24 @@ def create(connection_string, *args, **kwargs):
|
||||
|
||||
:param connection_string: connection string which specifies the storage
|
||||
driver for notifier
|
||||
:param *args: args that will be passed to the driver's __init__ method
|
||||
:param **kwargs: kwargs that will be passed to the driver's __init__ method
|
||||
:param args: args that will be passed to the driver's __init__ method
|
||||
:param kwargs: kwargs that will be passed to the driver's __init__ method
|
||||
:returns: Callable notifier method
|
||||
:raises TypeError: In case of invalid name of plugin raises TypeError
|
||||
"""
|
||||
global __driver_cache
|
||||
if connection_string not in __driver_cache:
|
||||
__driver_cache[connection_string] = base.get_driver(connection_string,
|
||||
*args,
|
||||
**kwargs).notify
|
||||
return __driver_cache[connection_string]
|
||||
global __notifier_cache
|
||||
if connection_string not in __notifier_cache:
|
||||
try:
|
||||
driver = base.get_driver(connection_string, *args, **kwargs)
|
||||
__notifier_cache[connection_string] = driver.notify
|
||||
LOG.info("osprofiler is enabled with connection string: %s",
|
||||
connection_string)
|
||||
except Exception:
|
||||
LOG.exception("Could not initialize driver for connection string "
|
||||
"%s, osprofiler is disabled", connection_string)
|
||||
__notifier_cache[connection_string] = _noop_notifier
|
||||
|
||||
return __notifier_cache[connection_string]
|
||||
|
||||
|
||||
def clear_notifier_cache():
|
||||
__notifier_cache.clear()
|
||||
|
@ -23,6 +23,7 @@ class NotifierTestCase(test.TestCase):
|
||||
|
||||
def tearDown(self):
|
||||
notifier.set(notifier._noop_notifier) # restore defaults
|
||||
notifier.clear_notifier_cache()
|
||||
super(NotifierTestCase, self).tearDown()
|
||||
|
||||
def test_set(self):
|
||||
@ -49,3 +50,11 @@ class NotifierTestCase(test.TestCase):
|
||||
result = notifier.create("test", 10, b=20)
|
||||
mock_factory.assert_called_once_with("test", 10, b=20)
|
||||
self.assertEqual(mock_factory.return_value.notify, result)
|
||||
|
||||
@mock.patch("osprofiler.notifier.base.get_driver")
|
||||
def test_create_driver_init_failure(self, mock_get_driver):
|
||||
mock_get_driver.side_effect = Exception()
|
||||
|
||||
result = notifier.create("test", 10, b=20)
|
||||
mock_get_driver.assert_called_once_with("test", 10, b=20)
|
||||
self.assertEqual(notifier._noop_notifier, result)
|
||||
|
Loading…
Reference in New Issue
Block a user