osc-lib: logs
Change-Id: I2a4d40cd72cc22e97a600751ae29c2309ebed28b
This commit is contained in:
parent
e5e29a8fef
commit
59dffb9c62
@ -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):
|
||||
|
@ -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__
|
||||
)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user