More selective logging
Having the SDK configure the root logger is problematic as it not only enables logging in the SDK but it also enables logging in the users app and logging in other libs unrelated to the SDK as an unintented side-effect. We should only log for the openstack module. We also want to be more selective about what stream to log to so we provide the option to log to stdout or stderr. Change-Id: I82ef867e182ebe4f29e21380268a3691e3b83494
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
# under the License.
|
||||
|
||||
import mock
|
||||
import sys
|
||||
import testtools
|
||||
|
||||
from openstack import utils
|
||||
@@ -18,11 +19,11 @@ from openstack import utils
|
||||
|
||||
class Test_enable_logging(testtools.TestCase):
|
||||
|
||||
def _console_tests(self, fake_logging, level, debug):
|
||||
def _console_tests(self, fake_logging, level, debug, stream):
|
||||
the_logger = mock.MagicMock()
|
||||
fake_logging.getLogger.return_value = the_logger
|
||||
|
||||
utils.enable_logging(debug=debug)
|
||||
utils.enable_logging(debug=debug, stream=stream)
|
||||
|
||||
self.assertEqual(the_logger.addHandler.call_count, 1)
|
||||
the_logger.setLevel.assert_called_with(level)
|
||||
@@ -35,16 +36,33 @@ class Test_enable_logging(testtools.TestCase):
|
||||
utils.enable_logging(debug=debug, path=fake_path)
|
||||
|
||||
fake_logging.FileHandler.assert_called_with(fake_path)
|
||||
self.assertEqual(the_logger.addHandler.call_count, 2)
|
||||
self.assertEqual(the_logger.addHandler.call_count, 1)
|
||||
the_logger.setLevel.assert_called_with(level)
|
||||
|
||||
@mock.patch("openstack.utils.logging")
|
||||
def test_debug_console(self, fake_logging):
|
||||
self._console_tests(fake_logging, fake_logging.DEBUG, True)
|
||||
def test_none(self):
|
||||
self.assertRaises(
|
||||
ValueError, utils.enable_logging,
|
||||
debug=True, path=None, stream=None)
|
||||
|
||||
@mock.patch("openstack.utils.logging")
|
||||
def test_warning_console(self, fake_logging):
|
||||
self._console_tests(fake_logging, fake_logging.WARNING, False)
|
||||
def test_debug_console_stderr(self, fake_logging):
|
||||
self._console_tests(fake_logging,
|
||||
fake_logging.DEBUG, True, sys.stderr)
|
||||
|
||||
@mock.patch("openstack.utils.logging")
|
||||
def test_warning_console_stderr(self, fake_logging):
|
||||
self._console_tests(fake_logging,
|
||||
fake_logging.WARNING, False, sys.stderr)
|
||||
|
||||
@mock.patch("openstack.utils.logging")
|
||||
def test_debug_console_stdout(self, fake_logging):
|
||||
self._console_tests(fake_logging,
|
||||
fake_logging.DEBUG, True, sys.stdout)
|
||||
|
||||
@mock.patch("openstack.utils.logging")
|
||||
def test_warning_console_stdout(self, fake_logging):
|
||||
self._console_tests(fake_logging,
|
||||
fake_logging.WARNING, False, sys.stdout)
|
||||
|
||||
@mock.patch("openstack.utils.logging")
|
||||
def test_debug_file(self, fake_logging):
|
||||
|
@@ -11,11 +11,10 @@
|
||||
# under the License.
|
||||
|
||||
import logging
|
||||
import sys
|
||||
|
||||
|
||||
def enable_logging(debug=False, path=None):
|
||||
"""Enable logging of messages to sys.stderr
|
||||
def enable_logging(debug=False, path=None, stream=None):
|
||||
"""Enable logging to a file at path and/or a console stream.
|
||||
|
||||
This function is available for debugging purposes. If you wish to
|
||||
log this package's message in your application, the standard library
|
||||
@@ -26,27 +25,35 @@ def enable_logging(debug=False, path=None):
|
||||
which includes HTTP requests and responses,
|
||||
or ``False`` for warning messages.
|
||||
:param str path: If a *path* is specified, logging output will
|
||||
written to that file in addition to sys.stderr.
|
||||
written to that file in addition to sys.stderr.
|
||||
The path is passed to logging.FileHandler,
|
||||
which will append messages the file (and create
|
||||
it if needed). *Default: None*
|
||||
it if needed).
|
||||
:param stream: One of ``None `` or ``sys.stdout`` or ``sys.stderr``.
|
||||
If it is ``None``, nothing is logged to a stream.
|
||||
If it isn't ``None``, console output is logged
|
||||
to this stream.
|
||||
|
||||
:rtype: None
|
||||
"""
|
||||
root_logger = logging.getLogger('')
|
||||
if path is None and stream is None:
|
||||
raise ValueError("path and/or stream must be set")
|
||||
|
||||
logger = logging.getLogger('openstack')
|
||||
formatter = logging.Formatter(
|
||||
'%(asctime)s %(levelname)s: %(name)s %(message)s')
|
||||
|
||||
console = logging.StreamHandler(sys.stderr)
|
||||
console.setFormatter(formatter)
|
||||
root_logger.addHandler(console)
|
||||
if stream is not None:
|
||||
console = logging.StreamHandler(stream)
|
||||
console.setFormatter(formatter)
|
||||
logger.addHandler(console)
|
||||
|
||||
if path is not None:
|
||||
file_handler = logging.FileHandler(path)
|
||||
file_handler.setFormatter(formatter)
|
||||
root_logger.addHandler(file_handler)
|
||||
logger.addHandler(file_handler)
|
||||
|
||||
root_logger.setLevel(logging.DEBUG if debug else logging.WARNING)
|
||||
logger.setLevel(logging.DEBUG if debug else logging.WARNING)
|
||||
|
||||
|
||||
def urljoin(*args):
|
||||
|
Reference in New Issue
Block a user