Add logging functionality to openstack.utils
This change moves the ability to enable logging out of the examples.common module and into the openstack.utils since it is generally useful. This is intended to give users a short-term solution to receive debugging messages. If they want to always have our messages logged in their application they should create their own logging handler(s) with their own format, and that will cause our messages to be sent to their handlers as they wish. https://bugs.launchpad.net/python-openstacksdk/+bug/1418307 is open to track the documentation aspect of this. Change-Id: Ic8768d529d0389b9b04bd4ea31453a82f30faf33
This commit is contained in:
parent
005f211f28
commit
8dcff5a621
@ -96,3 +96,4 @@ can be customized.
|
||||
identity_v3
|
||||
resource
|
||||
service_filter
|
||||
utils
|
||||
|
4
doc/source/users/utils.rst
Normal file
4
doc/source/users/utils.rst
Normal file
@ -0,0 +1,4 @@
|
||||
Utilities
|
||||
=========
|
||||
.. automodule:: openstack.utils
|
||||
:members: enable_logging
|
@ -42,8 +42,8 @@ import traceback
|
||||
import uuid
|
||||
|
||||
from openstack import user_preference
|
||||
from openstack import utils
|
||||
|
||||
CONSOLE_MESSAGE_FORMAT = '%(levelname)s: %(name)s %(message)s'
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@ -318,31 +318,9 @@ def option_parser():
|
||||
return parser
|
||||
|
||||
|
||||
def configure_logging(opts):
|
||||
"""Typical app logging setup
|
||||
|
||||
Based on OSC/cliff
|
||||
|
||||
"""
|
||||
|
||||
root_logger = logging.getLogger('')
|
||||
|
||||
# Always send higher-level messages to the console via stderr
|
||||
console = logging.StreamHandler(sys.stderr)
|
||||
formatter = logging.Formatter(CONSOLE_MESSAGE_FORMAT)
|
||||
console.setFormatter(formatter)
|
||||
root_logger.addHandler(console)
|
||||
|
||||
if opts.debug:
|
||||
root_logger.setLevel(logging.DEBUG)
|
||||
else:
|
||||
root_logger.setLevel(logging.WARNING)
|
||||
return
|
||||
|
||||
|
||||
def setup():
|
||||
opts = option_parser().parse_args()
|
||||
configure_logging(opts)
|
||||
utils.enable_logging(opts.debug)
|
||||
return opts
|
||||
|
||||
|
||||
|
@ -12,9 +12,50 @@
|
||||
|
||||
import unittest
|
||||
|
||||
import mock
|
||||
|
||||
from openstack import utils
|
||||
|
||||
|
||||
class Test_enable_logging(unittest.TestCase):
|
||||
|
||||
def _console_tests(self, fake_logging, level, debug):
|
||||
the_logger = mock.MagicMock()
|
||||
fake_logging.getLogger.return_value = the_logger
|
||||
|
||||
utils.enable_logging(debug=debug)
|
||||
|
||||
self.assertEqual(the_logger.addHandler.call_count, 1)
|
||||
the_logger.setLevel.assert_called_with(level)
|
||||
|
||||
def _file_tests(self, fake_logging, level, debug):
|
||||
the_logger = mock.MagicMock()
|
||||
fake_logging.getLogger.return_value = the_logger
|
||||
fake_path = "fake/path.log"
|
||||
|
||||
utils.enable_logging(debug=debug, path=fake_path)
|
||||
|
||||
fake_logging.FileHandler.assert_called_with(fake_path)
|
||||
self.assertEqual(the_logger.addHandler.call_count, 2)
|
||||
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)
|
||||
|
||||
@mock.patch("openstack.utils.logging")
|
||||
def test_warning_console(self, fake_logging):
|
||||
self._console_tests(fake_logging, fake_logging.WARNING, False)
|
||||
|
||||
@mock.patch("openstack.utils.logging")
|
||||
def test_debug_file(self, fake_logging):
|
||||
self._file_tests(fake_logging, fake_logging.DEBUG, True)
|
||||
|
||||
@mock.patch("openstack.utils.logging")
|
||||
def test_warning_file(self, fake_logging):
|
||||
self._file_tests(fake_logging, fake_logging.WARNING, False)
|
||||
|
||||
|
||||
class Test_urljoin(unittest.TestCase):
|
||||
|
||||
def test_strings(self):
|
||||
|
@ -10,6 +10,44 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import logging
|
||||
import sys
|
||||
|
||||
|
||||
def enable_logging(debug=False, path=None):
|
||||
"""Enable logging of messages to sys.stderr
|
||||
|
||||
This function is available for debugging purposes. If you wish to
|
||||
log this package's message in your application, the standard library
|
||||
``logging`` package will receive these messages in any handlers you
|
||||
create.
|
||||
|
||||
:param bool debug: Set this to ``True`` to receive debug messages,
|
||||
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.
|
||||
The path is passed to logging.FileHandler,
|
||||
which will append messages the file (and create
|
||||
it if needed). *Default: None*
|
||||
|
||||
:rtype: None
|
||||
"""
|
||||
root_logger = logging.getLogger('')
|
||||
formatter = logging.Formatter(
|
||||
'%(asctime)s %(levelname)s: %(name)s %(message)s')
|
||||
|
||||
console = logging.StreamHandler(sys.stderr)
|
||||
console.setFormatter(formatter)
|
||||
root_logger.addHandler(console)
|
||||
|
||||
if path is not None:
|
||||
file_handler = logging.FileHandler(path)
|
||||
file_handler.setFormatter(formatter)
|
||||
root_logger.addHandler(file_handler)
|
||||
|
||||
root_logger.setLevel(logging.DEBUG if debug else logging.WARNING)
|
||||
|
||||
|
||||
def urljoin(*args):
|
||||
"""A custom version of urljoin that simply joins strings into a path.
|
||||
|
Loading…
x
Reference in New Issue
Block a user