From 59dffb9c62b48dbf5e99395e8f58e317e43cf036 Mon Sep 17 00:00:00 2001 From: Dean Troyer Date: Thu, 9 Jun 2016 16:29:42 -0500 Subject: [PATCH] osc-lib: logs Change-Id: I2a4d40cd72cc22e97a600751ae29c2309ebed28b --- doc/source/plugins.rst | 2 +- openstackclient/common/logs.py | 188 ++-------------------- openstackclient/shell.py | 2 +- openstackclient/tests/common/test_logs.py | 15 +- 4 files changed, 20 insertions(+), 187 deletions(-) diff --git a/doc/source/plugins.rst b/doc/source/plugins.rst index 27846318b3..62c0aedc2e 100644 --- a/doc/source/plugins.rst +++ b/doc/source/plugins.rst @@ -153,12 +153,12 @@ the plugin commands: # osc-lib interfaces available to plugins: from osc_lib import exceptions + from osc_lib import logs from osc_lib import utils # OSC common interfaces available to plugins: from openstackclient.common import command from openstackclient.common import parseractions - from openstackclient.common import logs class DeleteMypluginobject(command.Command): diff --git a/openstackclient/common/logs.py b/openstackclient/common/logs.py index 8671555b60..8aa97d5bae 100644 --- a/openstackclient/common/logs.py +++ b/openstackclient/common/logs.py @@ -11,186 +11,16 @@ # under the License. # -"""Application logging""" +# NOTE(dtroyer): This file is deprecated in Jun 2016, remove after 4.x release +# or Jun 2017. -import logging import sys -import warnings + +from osc_lib.logs import * # noqa +from osc_lib.logs import _FileFormatter # noqa -def get_loggers(): - loggers = {} - for logkey in logging.Logger.manager.loggerDict.keys(): - loggers[logkey] = logging.getLevelName(logging.getLogger(logkey).level) - return loggers - - -def log_level_from_options(options): - # if --debug, --quiet or --verbose is not specified, - # the default logging level is warning - log_level = logging.WARNING - if options.verbose_level == 0: - # --quiet - log_level = logging.ERROR - elif options.verbose_level == 2: - # One --verbose - log_level = logging.INFO - elif options.verbose_level >= 3: - # Two or more --verbose - log_level = logging.DEBUG - return log_level - - -def log_level_from_string(level_string): - log_level = { - 'critical': logging.CRITICAL, - 'error': logging.ERROR, - 'warning': logging.WARNING, - 'info': logging.INFO, - 'debug': logging.DEBUG, - }.get(level_string, logging.WARNING) - return log_level - - -def log_level_from_config(config): - # Check the command line option - verbose_level = config.get('verbose_level') - if config.get('debug', False): - verbose_level = 3 - if verbose_level == 0: - verbose_level = 'error' - elif verbose_level == 1: - # If a command line option has not been specified, check the - # configuration file - verbose_level = config.get('log_level', 'warning') - elif verbose_level == 2: - verbose_level = 'info' - else: - verbose_level = 'debug' - return log_level_from_string(verbose_level) - - -def set_warning_filter(log_level): - if log_level == logging.ERROR: - warnings.simplefilter("ignore") - elif log_level == logging.WARNING: - warnings.simplefilter("ignore") - elif log_level == logging.INFO: - warnings.simplefilter("once") - - -class _FileFormatter(logging.Formatter): - """Customize the logging format for logging handler""" - _LOG_MESSAGE_BEGIN = ( - '%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s ') - _LOG_MESSAGE_CONTEXT = '[%(cloud)s %(username)s %(project)s] ' - _LOG_MESSAGE_END = '%(message)s' - _LOG_DATE_FORMAT = '%Y-%m-%d %H:%M:%S' - - def __init__(self, options=None, config=None, **kwargs): - context = {} - if options: - context = { - 'cloud': getattr(options, 'cloud', ''), - 'project': getattr(options, 'os_project_name', ''), - 'username': getattr(options, 'username', ''), - } - elif config: - context = { - 'cloud': config.config.get('cloud', ''), - 'project': config.auth.get('project_name', ''), - 'username': config.auth.get('username', ''), - } - if context: - self.fmt = (self._LOG_MESSAGE_BEGIN + - (self._LOG_MESSAGE_CONTEXT % context) + - self._LOG_MESSAGE_END) - else: - self.fmt = self._LOG_MESSAGE_BEGIN + self._LOG_MESSAGE_END - logging.Formatter.__init__(self, self.fmt, self._LOG_DATE_FORMAT) - - -class LogConfigurator(object): - - _CONSOLE_MESSAGE_FORMAT = '%(message)s' - - def __init__(self, options): - self.root_logger = logging.getLogger('') - self.root_logger.setLevel(logging.DEBUG) - - # Force verbose_level 3 on --debug - self.dump_trace = False - if options.debug: - options.verbose_level = 3 - self.dump_trace = True - - # Always send higher-level messages to the console via stderr - self.console_logger = logging.StreamHandler(sys.stderr) - log_level = log_level_from_options(options) - self.console_logger.setLevel(log_level) - formatter = logging.Formatter(self._CONSOLE_MESSAGE_FORMAT) - self.console_logger.setFormatter(formatter) - self.root_logger.addHandler(self.console_logger) - - # Set the warning filter now - set_warning_filter(log_level) - - # Set up logging to a file - self.file_logger = None - log_file = options.log_file - if log_file: - self.file_logger = logging.FileHandler(filename=log_file) - self.file_logger.setFormatter(_FileFormatter(options=options)) - self.file_logger.setLevel(log_level) - self.root_logger.addHandler(self.file_logger) - - # Requests logs some stuff at INFO that we don't want - # unless we have DEBUG - requests_log = logging.getLogger("requests") - - # Other modules we don't want DEBUG output for - cliff_log = logging.getLogger('cliff') - stevedore_log = logging.getLogger('stevedore') - iso8601_log = logging.getLogger("iso8601") - - if options.debug: - # --debug forces traceback - requests_log.setLevel(logging.DEBUG) - else: - requests_log.setLevel(logging.ERROR) - - cliff_log.setLevel(logging.ERROR) - stevedore_log.setLevel(logging.ERROR) - iso8601_log.setLevel(logging.ERROR) - - def configure(self, cloud_config): - log_level = log_level_from_config(cloud_config.config) - set_warning_filter(log_level) - self.dump_trace = cloud_config.config.get('debug', self.dump_trace) - self.console_logger.setLevel(log_level) - - log_file = cloud_config.config.get('log_file') - if log_file: - if not self.file_logger: - self.file_logger = logging.FileHandler(filename=log_file) - self.file_logger.setFormatter(_FileFormatter(config=cloud_config)) - self.file_logger.setLevel(log_level) - self.root_logger.addHandler(self.file_logger) - - logconfig = cloud_config.config.get('logging') - if logconfig: - highest_level = logging.NOTSET - for k in logconfig.keys(): - level = log_level_from_string(logconfig[k]) - logging.getLogger(k).setLevel(level) - if (highest_level < level): - highest_level = level - self.console_logger.setLevel(highest_level) - if self.file_logger: - self.file_logger.setLevel(highest_level) - # loggers that are not set will use the handler level, so we - # need to set the global level for all the loggers - for logkey in logging.Logger.manager.loggerDict.keys(): - logger = logging.getLogger(logkey) - if logger.level == logging.NOTSET: - logger.setLevel(log_level) +sys.stderr.write( + "WARNING: %s is deprecated and will be removed after Jun 2017. " + "Please use osc_lib.logs\n" % __name__ +) diff --git a/openstackclient/shell.py b/openstackclient/shell.py index 2697128bd4..3e899cb51c 100644 --- a/openstackclient/shell.py +++ b/openstackclient/shell.py @@ -27,6 +27,7 @@ from cliff import command from cliff import complete from cliff import help from osc_lib import exceptions as exc +from osc_lib import logs from osc_lib import utils from oslo_utils import importutils from oslo_utils import strutils @@ -34,7 +35,6 @@ from oslo_utils import strutils import openstackclient from openstackclient.common import clientmanager from openstackclient.common import commandmanager -from openstackclient.common import logs from openstackclient.common import timing from os_client_config import config as cloud_config diff --git a/openstackclient/tests/common/test_logs.py b/openstackclient/tests/common/test_logs.py index 0386cdfda0..5091510cd3 100644 --- a/openstackclient/tests/common/test_logs.py +++ b/openstackclient/tests/common/test_logs.py @@ -11,6 +11,9 @@ # under the License. # +# NOTE(dtroyer): This file is deprecated in Jun 2016, remove after 4.x release +# or Jun 2017. + import logging import mock @@ -121,7 +124,7 @@ class TestLogConfigurator(utils.TestCase): @mock.patch('logging.StreamHandler') @mock.patch('logging.getLogger') - @mock.patch('openstackclient.common.logs.set_warning_filter') + @mock.patch('osc_lib.logs.set_warning_filter') def test_init(self, warning_filter, getLogger, handle): getLogger.side_effect = self.loggers console_logger = mock.Mock() @@ -142,7 +145,7 @@ class TestLogConfigurator(utils.TestCase): self.assertFalse(configurator.dump_trace) @mock.patch('logging.getLogger') - @mock.patch('openstackclient.common.logs.set_warning_filter') + @mock.patch('osc_lib.logs.set_warning_filter') def test_init_no_debug(self, warning_filter, getLogger): getLogger.side_effect = self.loggers self.options.debug = True @@ -155,8 +158,8 @@ class TestLogConfigurator(utils.TestCase): @mock.patch('logging.FileHandler') @mock.patch('logging.getLogger') - @mock.patch('openstackclient.common.logs.set_warning_filter') - @mock.patch('openstackclient.common.logs._FileFormatter') + @mock.patch('osc_lib.logs.set_warning_filter') + @mock.patch('osc_lib.logs._FileFormatter') def test_init_log_file(self, formatter, warning_filter, getLogger, handle): getLogger.side_effect = self.loggers self.options.log_file = '/tmp/log_file' @@ -176,8 +179,8 @@ class TestLogConfigurator(utils.TestCase): @mock.patch('logging.FileHandler') @mock.patch('logging.getLogger') - @mock.patch('openstackclient.common.logs.set_warning_filter') - @mock.patch('openstackclient.common.logs._FileFormatter') + @mock.patch('osc_lib.logs.set_warning_filter') + @mock.patch('osc_lib.logs._FileFormatter') def test_configure(self, formatter, warning_filter, getLogger, handle): getLogger.side_effect = self.loggers configurator = logs.LogConfigurator(self.options)