Update openstack/common code
This is just before removing the log module. Change-Id: I9aa34530a571232311bef3db3166295924f525a3
This commit is contained in:
@@ -75,8 +75,8 @@ class HookableMixin(object):
|
|||||||
|
|
||||||
:param cls: class that registers hooks
|
:param cls: class that registers hooks
|
||||||
:param hook_type: hook type, e.g., '__pre_parse_args__'
|
:param hook_type: hook type, e.g., '__pre_parse_args__'
|
||||||
:param **args: args to be passed to every hook function
|
:param args: args to be passed to every hook function
|
||||||
:param **kwargs: kwargs to be passed to every hook function
|
:param kwargs: kwargs to be passed to every hook function
|
||||||
"""
|
"""
|
||||||
hook_funcs = cls._hooks_map.get(hook_type) or []
|
hook_funcs = cls._hooks_map.get(hook_type) or []
|
||||||
for hook_func in hook_funcs:
|
for hook_func in hook_funcs:
|
||||||
|
@@ -47,6 +47,7 @@ class HTTPClient(object):
|
|||||||
"""This client handles sending HTTP requests to OpenStack servers.
|
"""This client handles sending HTTP requests to OpenStack servers.
|
||||||
|
|
||||||
Features:
|
Features:
|
||||||
|
|
||||||
- share authentication information between several clients to different
|
- share authentication information between several clients to different
|
||||||
services (e.g., for compute and image clients);
|
services (e.g., for compute and image clients);
|
||||||
- reissue authentication request for expired tokens;
|
- reissue authentication request for expired tokens;
|
||||||
@@ -152,7 +153,7 @@ class HTTPClient(object):
|
|||||||
:param method: method of HTTP request
|
:param method: method of HTTP request
|
||||||
:param url: URL of HTTP request
|
:param url: URL of HTTP request
|
||||||
:param kwargs: any other parameter that can be passed to
|
:param kwargs: any other parameter that can be passed to
|
||||||
' requests.Session.request (such as `headers`) or `json`
|
requests.Session.request (such as `headers`) or `json`
|
||||||
that will be encoded as JSON and used as `data` argument
|
that will be encoded as JSON and used as `data` argument
|
||||||
"""
|
"""
|
||||||
kwargs.setdefault("headers", kwargs.get("headers", {}))
|
kwargs.setdefault("headers", kwargs.get("headers", {}))
|
||||||
@@ -207,7 +208,7 @@ class HTTPClient(object):
|
|||||||
:param method: method of HTTP request
|
:param method: method of HTTP request
|
||||||
:param url: URL of HTTP request
|
:param url: URL of HTTP request
|
||||||
:param kwargs: any other parameter that can be passed to
|
:param kwargs: any other parameter that can be passed to
|
||||||
' `HTTPClient.request`
|
`HTTPClient.request`
|
||||||
"""
|
"""
|
||||||
|
|
||||||
filter_args = {
|
filter_args = {
|
||||||
|
@@ -56,7 +56,7 @@ def validate_args(fn, *args, **kwargs):
|
|||||||
required_args = argspec.args[:len(argspec.args) - num_defaults]
|
required_args = argspec.args[:len(argspec.args) - num_defaults]
|
||||||
|
|
||||||
def isbound(method):
|
def isbound(method):
|
||||||
return getattr(method, 'im_self', None) is not None
|
return getattr(method, '__self__', None) is not None
|
||||||
|
|
||||||
if isbound(fn):
|
if isbound(fn):
|
||||||
required_args.pop(0)
|
required_args.pop(0)
|
||||||
@@ -235,7 +235,10 @@ def find_resource(manager, name_or_id, **find_args):
|
|||||||
|
|
||||||
# now try to get entity as uuid
|
# now try to get entity as uuid
|
||||||
try:
|
try:
|
||||||
|
if six.PY2:
|
||||||
tmp_id = strutils.safe_encode(name_or_id)
|
tmp_id = strutils.safe_encode(name_or_id)
|
||||||
|
else:
|
||||||
|
tmp_id = strutils.safe_decode(name_or_id)
|
||||||
|
|
||||||
if uuidutils.is_uuid_like(tmp_id):
|
if uuidutils.is_uuid_like(tmp_id):
|
||||||
return manager.get(tmp_id)
|
return manager.get(tmp_id)
|
||||||
|
@@ -32,24 +32,113 @@ import os
|
|||||||
from babel import localedata
|
from babel import localedata
|
||||||
import six
|
import six
|
||||||
|
|
||||||
_localedir = os.environ.get('mistralclient'.upper() + '_LOCALEDIR')
|
|
||||||
_t = gettext.translation('mistralclient', localedir=_localedir, fallback=True)
|
|
||||||
|
|
||||||
# We use separate translation catalogs for each log level, so set up a
|
|
||||||
# mapping between the log level name and the translator. The domain
|
|
||||||
# for the log level is project_name + "-log-" + log_level so messages
|
|
||||||
# for each level end up in their own catalog.
|
|
||||||
_t_log_levels = dict(
|
|
||||||
(level, gettext.translation('mistralclient' + '-log-' + level,
|
|
||||||
localedir=_localedir,
|
|
||||||
fallback=True))
|
|
||||||
for level in ['info', 'warning', 'error', 'critical']
|
|
||||||
)
|
|
||||||
|
|
||||||
_AVAILABLE_LANGUAGES = {}
|
_AVAILABLE_LANGUAGES = {}
|
||||||
|
|
||||||
|
# FIXME(dhellmann): Remove this when moving to oslo.i18n.
|
||||||
USE_LAZY = False
|
USE_LAZY = False
|
||||||
|
|
||||||
|
|
||||||
|
class TranslatorFactory(object):
|
||||||
|
"""Create translator functions
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, domain, lazy=False, localedir=None):
|
||||||
|
"""Establish a set of translation functions for the domain.
|
||||||
|
|
||||||
|
:param domain: Name of translation domain,
|
||||||
|
specifying a message catalog.
|
||||||
|
:type domain: str
|
||||||
|
:param lazy: Delays translation until a message is emitted.
|
||||||
|
Defaults to False.
|
||||||
|
:type lazy: Boolean
|
||||||
|
:param localedir: Directory with translation catalogs.
|
||||||
|
:type localedir: str
|
||||||
|
"""
|
||||||
|
self.domain = domain
|
||||||
|
self.lazy = lazy
|
||||||
|
if localedir is None:
|
||||||
|
localedir = os.environ.get(domain.upper() + '_LOCALEDIR')
|
||||||
|
self.localedir = localedir
|
||||||
|
|
||||||
|
def _make_translation_func(self, domain=None):
|
||||||
|
"""Return a new translation function ready for use.
|
||||||
|
|
||||||
|
Takes into account whether or not lazy translation is being
|
||||||
|
done.
|
||||||
|
|
||||||
|
The domain can be specified to override the default from the
|
||||||
|
factory, but the localedir from the factory is always used
|
||||||
|
because we assume the log-level translation catalogs are
|
||||||
|
installed in the same directory as the main application
|
||||||
|
catalog.
|
||||||
|
|
||||||
|
"""
|
||||||
|
if domain is None:
|
||||||
|
domain = self.domain
|
||||||
|
if self.lazy:
|
||||||
|
return functools.partial(Message, domain=domain)
|
||||||
|
t = gettext.translation(
|
||||||
|
domain,
|
||||||
|
localedir=self.localedir,
|
||||||
|
fallback=True,
|
||||||
|
)
|
||||||
|
if six.PY3:
|
||||||
|
return t.gettext
|
||||||
|
return t.ugettext
|
||||||
|
|
||||||
|
@property
|
||||||
|
def primary(self):
|
||||||
|
"The default translation function."
|
||||||
|
return self._make_translation_func()
|
||||||
|
|
||||||
|
def _make_log_translation_func(self, level):
|
||||||
|
return self._make_translation_func(self.domain + '-log-' + level)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def log_info(self):
|
||||||
|
"Translate info-level log messages."
|
||||||
|
return self._make_log_translation_func('info')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def log_warning(self):
|
||||||
|
"Translate warning-level log messages."
|
||||||
|
return self._make_log_translation_func('warning')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def log_error(self):
|
||||||
|
"Translate error-level log messages."
|
||||||
|
return self._make_log_translation_func('error')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def log_critical(self):
|
||||||
|
"Translate critical-level log messages."
|
||||||
|
return self._make_log_translation_func('critical')
|
||||||
|
|
||||||
|
|
||||||
|
# NOTE(dhellmann): When this module moves out of the incubator into
|
||||||
|
# oslo.i18n, these global variables can be moved to an integration
|
||||||
|
# module within each application.
|
||||||
|
|
||||||
|
# Create the global translation functions.
|
||||||
|
_translators = TranslatorFactory('mistralclient')
|
||||||
|
|
||||||
|
# The primary translation function using the well-known name "_"
|
||||||
|
_ = _translators.primary
|
||||||
|
|
||||||
|
# Translators for log levels.
|
||||||
|
#
|
||||||
|
# The abbreviated names are meant to reflect the usual use of a short
|
||||||
|
# name like '_'. The "L" is for "log" and the other letter comes from
|
||||||
|
# the level.
|
||||||
|
_LI = _translators.log_info
|
||||||
|
_LW = _translators.log_warning
|
||||||
|
_LE = _translators.log_error
|
||||||
|
_LC = _translators.log_critical
|
||||||
|
|
||||||
|
# NOTE(dhellmann): End of globals that will move to the application's
|
||||||
|
# integration module.
|
||||||
|
|
||||||
|
|
||||||
def enable_lazy():
|
def enable_lazy():
|
||||||
"""Convenience function for configuring _() to use lazy gettext
|
"""Convenience function for configuring _() to use lazy gettext
|
||||||
|
|
||||||
@@ -58,41 +147,18 @@ def enable_lazy():
|
|||||||
your project is importing _ directly instead of using the
|
your project is importing _ directly instead of using the
|
||||||
gettextutils.install() way of importing the _ function.
|
gettextutils.install() way of importing the _ function.
|
||||||
"""
|
"""
|
||||||
global USE_LAZY
|
# FIXME(dhellmann): This function will be removed in oslo.i18n,
|
||||||
|
# because the TranslatorFactory makes it superfluous.
|
||||||
|
global _, _LI, _LW, _LE, _LC, USE_LAZY
|
||||||
|
tf = TranslatorFactory('mistralclient', lazy=True)
|
||||||
|
_ = tf.primary
|
||||||
|
_LI = tf.log_info
|
||||||
|
_LW = tf.log_warning
|
||||||
|
_LE = tf.log_error
|
||||||
|
_LC = tf.log_critical
|
||||||
USE_LAZY = True
|
USE_LAZY = True
|
||||||
|
|
||||||
|
|
||||||
def _(msg):
|
|
||||||
if USE_LAZY:
|
|
||||||
return Message(msg, domain='mistralclient')
|
|
||||||
else:
|
|
||||||
if six.PY3:
|
|
||||||
return _t.gettext(msg)
|
|
||||||
return _t.ugettext(msg)
|
|
||||||
|
|
||||||
|
|
||||||
def _log_translation(msg, level):
|
|
||||||
"""Build a single translation of a log message
|
|
||||||
"""
|
|
||||||
if USE_LAZY:
|
|
||||||
return Message(msg, domain='mistralclient' + '-log-' + level)
|
|
||||||
else:
|
|
||||||
translator = _t_log_levels[level]
|
|
||||||
if six.PY3:
|
|
||||||
return translator.gettext(msg)
|
|
||||||
return translator.ugettext(msg)
|
|
||||||
|
|
||||||
# Translators for log levels.
|
|
||||||
#
|
|
||||||
# The abbreviated names are meant to reflect the usual use of a short
|
|
||||||
# name like '_'. The "L" is for "log" and the other letter comes from
|
|
||||||
# the level.
|
|
||||||
_LI = functools.partial(_log_translation, level='info')
|
|
||||||
_LW = functools.partial(_log_translation, level='warning')
|
|
||||||
_LE = functools.partial(_log_translation, level='error')
|
|
||||||
_LC = functools.partial(_log_translation, level='critical')
|
|
||||||
|
|
||||||
|
|
||||||
def install(domain, lazy=False):
|
def install(domain, lazy=False):
|
||||||
"""Install a _() function using the given translation domain.
|
"""Install a _() function using the given translation domain.
|
||||||
|
|
||||||
@@ -112,26 +178,9 @@ def install(domain, lazy=False):
|
|||||||
any available locale.
|
any available locale.
|
||||||
"""
|
"""
|
||||||
if lazy:
|
if lazy:
|
||||||
# NOTE(mrodden): Lazy gettext functionality.
|
|
||||||
#
|
|
||||||
# The following introduces a deferred way to do translations on
|
|
||||||
# messages in OpenStack. We override the standard _() function
|
|
||||||
# and % (format string) operation to build Message objects that can
|
|
||||||
# later be translated when we have more information.
|
|
||||||
def _lazy_gettext(msg):
|
|
||||||
"""Create and return a Message object.
|
|
||||||
|
|
||||||
Lazy gettext function for a given domain, it is a factory method
|
|
||||||
for a project/module to get a lazy gettext function for its own
|
|
||||||
translation domain (i.e. nova, glance, cinder, etc.)
|
|
||||||
|
|
||||||
Message encapsulates a string so that we can translate
|
|
||||||
it later when needed.
|
|
||||||
"""
|
|
||||||
return Message(msg, domain=domain)
|
|
||||||
|
|
||||||
from six import moves
|
from six import moves
|
||||||
moves.builtins.__dict__['_'] = _lazy_gettext
|
tf = TranslatorFactory(domain, lazy=True)
|
||||||
|
moves.builtins.__dict__['_'] = tf.primary
|
||||||
else:
|
else:
|
||||||
localedir = '%s_LOCALEDIR' % domain.upper()
|
localedir = '%s_LOCALEDIR' % domain.upper()
|
||||||
if six.PY3:
|
if six.PY3:
|
||||||
|
@@ -24,10 +24,10 @@ import traceback
|
|||||||
def import_class(import_str):
|
def import_class(import_str):
|
||||||
"""Returns a class from a string including module and class."""
|
"""Returns a class from a string including module and class."""
|
||||||
mod_str, _sep, class_str = import_str.rpartition('.')
|
mod_str, _sep, class_str = import_str.rpartition('.')
|
||||||
try:
|
|
||||||
__import__(mod_str)
|
__import__(mod_str)
|
||||||
|
try:
|
||||||
return getattr(sys.modules[mod_str], class_str)
|
return getattr(sys.modules[mod_str], class_str)
|
||||||
except (ValueError, AttributeError):
|
except AttributeError:
|
||||||
raise ImportError('Class %s cannot be found (%s)' %
|
raise ImportError('Class %s cannot be found (%s)' %
|
||||||
(class_str,
|
(class_str,
|
||||||
traceback.format_exception(*sys.exc_info())))
|
traceback.format_exception(*sys.exc_info())))
|
||||||
|
@@ -31,17 +31,29 @@ This module provides a few things:
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
import codecs
|
||||||
import datetime
|
import datetime
|
||||||
import functools
|
import functools
|
||||||
import inspect
|
import inspect
|
||||||
import itertools
|
import itertools
|
||||||
import json
|
import sys
|
||||||
|
|
||||||
|
if sys.version_info < (2, 7):
|
||||||
|
# On Python <= 2.6, json module is not C boosted, so try to use
|
||||||
|
# simplejson module if available
|
||||||
|
try:
|
||||||
|
import simplejson as json
|
||||||
|
except ImportError:
|
||||||
|
import json
|
||||||
|
else:
|
||||||
|
import json
|
||||||
|
|
||||||
import six
|
import six
|
||||||
import six.moves.xmlrpc_client as xmlrpclib
|
import six.moves.xmlrpc_client as xmlrpclib
|
||||||
|
|
||||||
from mistralclient.openstack.common import gettextutils
|
from mistralclient.openstack.common import gettextutils
|
||||||
from mistralclient.openstack.common import importutils
|
from mistralclient.openstack.common import importutils
|
||||||
|
from mistralclient.openstack.common import strutils
|
||||||
from mistralclient.openstack.common import timeutils
|
from mistralclient.openstack.common import timeutils
|
||||||
|
|
||||||
netaddr = importutils.try_import("netaddr")
|
netaddr = importutils.try_import("netaddr")
|
||||||
@@ -156,12 +168,12 @@ def dumps(value, default=to_primitive, **kwargs):
|
|||||||
return json.dumps(value, default=default, **kwargs)
|
return json.dumps(value, default=default, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def loads(s):
|
def loads(s, encoding='utf-8'):
|
||||||
return json.loads(s)
|
return json.loads(strutils.safe_decode(s, encoding))
|
||||||
|
|
||||||
|
|
||||||
def load(s):
|
def load(fp, encoding='utf-8'):
|
||||||
return json.load(s)
|
return json.load(codecs.getreader(encoding)(fp))
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@@ -59,7 +59,10 @@ _SANITIZE_PATTERNS = []
|
|||||||
_FORMAT_PATTERNS = [r'(%(key)s\s*[=]\s*[\"\']).*?([\"\'])',
|
_FORMAT_PATTERNS = [r'(%(key)s\s*[=]\s*[\"\']).*?([\"\'])',
|
||||||
r'(<%(key)s>).*?(</%(key)s>)',
|
r'(<%(key)s>).*?(</%(key)s>)',
|
||||||
r'([\"\']%(key)s[\"\']\s*:\s*[\"\']).*?([\"\'])',
|
r'([\"\']%(key)s[\"\']\s*:\s*[\"\']).*?([\"\'])',
|
||||||
r'([\'"].*?%(key)s[\'"]\s*:\s*u?[\'"]).*?([\'"])']
|
r'([\'"].*?%(key)s[\'"]\s*:\s*u?[\'"]).*?([\'"])',
|
||||||
|
r'([\'"].*?%(key)s[\'"]\s*,\s*\'--?[A-z]+\'\s*,\s*u?[\'"])'
|
||||||
|
'.*?([\'"])',
|
||||||
|
r'(%(key)s\s*--?[A-z]+\s*).*?([\s])']
|
||||||
|
|
||||||
for key in _SANITIZE_KEYS:
|
for key in _SANITIZE_KEYS:
|
||||||
for pattern in _FORMAT_PATTERNS:
|
for pattern in _FORMAT_PATTERNS:
|
||||||
@@ -84,14 +87,11 @@ logging_cli_opts = [
|
|||||||
cfg.StrOpt('log-config-append',
|
cfg.StrOpt('log-config-append',
|
||||||
metavar='PATH',
|
metavar='PATH',
|
||||||
deprecated_name='log-config',
|
deprecated_name='log-config',
|
||||||
help='The name of logging configuration file. It does not '
|
help='The name of a logging configuration file. This file '
|
||||||
'disable existing loggers, but just appends specified '
|
'is appended to any existing logging configuration '
|
||||||
'logging configuration to any other existing logging '
|
'files. For details about logging configuration files, '
|
||||||
'options. Please see the Python logging module '
|
'see the Python logging module documentation.'),
|
||||||
'documentation for details on logging configuration '
|
|
||||||
'files.'),
|
|
||||||
cfg.StrOpt('log-format',
|
cfg.StrOpt('log-format',
|
||||||
default=None,
|
|
||||||
metavar='FORMAT',
|
metavar='FORMAT',
|
||||||
help='DEPRECATED. '
|
help='DEPRECATED. '
|
||||||
'A logging.Formatter log message format string which may '
|
'A logging.Formatter log message format string which may '
|
||||||
@@ -103,7 +103,7 @@ logging_cli_opts = [
|
|||||||
default=_DEFAULT_LOG_DATE_FORMAT,
|
default=_DEFAULT_LOG_DATE_FORMAT,
|
||||||
metavar='DATE_FORMAT',
|
metavar='DATE_FORMAT',
|
||||||
help='Format string for %%(asctime)s in log records. '
|
help='Format string for %%(asctime)s in log records. '
|
||||||
'Default: %(default)s'),
|
'Default: %(default)s .'),
|
||||||
cfg.StrOpt('log-file',
|
cfg.StrOpt('log-file',
|
||||||
metavar='PATH',
|
metavar='PATH',
|
||||||
deprecated_name='logfile',
|
deprecated_name='logfile',
|
||||||
@@ -112,30 +112,30 @@ logging_cli_opts = [
|
|||||||
cfg.StrOpt('log-dir',
|
cfg.StrOpt('log-dir',
|
||||||
deprecated_name='logdir',
|
deprecated_name='logdir',
|
||||||
help='(Optional) The base directory used for relative '
|
help='(Optional) The base directory used for relative '
|
||||||
'--log-file paths'),
|
'--log-file paths.'),
|
||||||
cfg.BoolOpt('use-syslog',
|
cfg.BoolOpt('use-syslog',
|
||||||
default=False,
|
default=False,
|
||||||
help='Use syslog for logging. '
|
help='Use syslog for logging. '
|
||||||
'Existing syslog format is DEPRECATED during I, '
|
'Existing syslog format is DEPRECATED during I, '
|
||||||
'and then will be changed in J to honor RFC5424'),
|
'and will change in J to honor RFC5424.'),
|
||||||
cfg.BoolOpt('use-syslog-rfc-format',
|
cfg.BoolOpt('use-syslog-rfc-format',
|
||||||
# TODO(bogdando) remove or use True after existing
|
# TODO(bogdando) remove or use True after existing
|
||||||
# syslog format deprecation in J
|
# syslog format deprecation in J
|
||||||
default=False,
|
default=False,
|
||||||
help='(Optional) Use syslog rfc5424 format for logging. '
|
help='(Optional) Enables or disables syslog rfc5424 format '
|
||||||
'If enabled, will add APP-NAME (RFC5424) before the '
|
'for logging. If enabled, prefixes the MSG part of the '
|
||||||
'MSG part of the syslog message. The old format '
|
'syslog message with APP-NAME (RFC5424). The '
|
||||||
'without APP-NAME is deprecated in I, '
|
'format without the APP-NAME is deprecated in I, '
|
||||||
'and will be removed in J.'),
|
'and will be removed in J.'),
|
||||||
cfg.StrOpt('syslog-log-facility',
|
cfg.StrOpt('syslog-log-facility',
|
||||||
default='LOG_USER',
|
default='LOG_USER',
|
||||||
help='Syslog facility to receive log lines')
|
help='Syslog facility to receive log lines.')
|
||||||
]
|
]
|
||||||
|
|
||||||
generic_log_opts = [
|
generic_log_opts = [
|
||||||
cfg.BoolOpt('use_stderr',
|
cfg.BoolOpt('use_stderr',
|
||||||
default=True,
|
default=True,
|
||||||
help='Log output to standard error')
|
help='Log output to standard error.')
|
||||||
]
|
]
|
||||||
|
|
||||||
log_opts = [
|
log_opts = [
|
||||||
@@ -143,18 +143,18 @@ log_opts = [
|
|||||||
default='%(asctime)s.%(msecs)03d %(process)d %(levelname)s '
|
default='%(asctime)s.%(msecs)03d %(process)d %(levelname)s '
|
||||||
'%(name)s [%(request_id)s %(user_identity)s] '
|
'%(name)s [%(request_id)s %(user_identity)s] '
|
||||||
'%(instance)s%(message)s',
|
'%(instance)s%(message)s',
|
||||||
help='Format string to use for log messages with context'),
|
help='Format string to use for log messages with context.'),
|
||||||
cfg.StrOpt('logging_default_format_string',
|
cfg.StrOpt('logging_default_format_string',
|
||||||
default='%(asctime)s.%(msecs)03d %(process)d %(levelname)s '
|
default='%(asctime)s.%(msecs)03d %(process)d %(levelname)s '
|
||||||
'%(name)s [-] %(instance)s%(message)s',
|
'%(name)s [-] %(instance)s%(message)s',
|
||||||
help='Format string to use for log messages without context'),
|
help='Format string to use for log messages without context.'),
|
||||||
cfg.StrOpt('logging_debug_format_suffix',
|
cfg.StrOpt('logging_debug_format_suffix',
|
||||||
default='%(funcName)s %(pathname)s:%(lineno)d',
|
default='%(funcName)s %(pathname)s:%(lineno)d',
|
||||||
help='Data to append to log format when level is DEBUG'),
|
help='Data to append to log format when level is DEBUG.'),
|
||||||
cfg.StrOpt('logging_exception_prefix',
|
cfg.StrOpt('logging_exception_prefix',
|
||||||
default='%(asctime)s.%(msecs)03d %(process)d TRACE %(name)s '
|
default='%(asctime)s.%(msecs)03d %(process)d TRACE %(name)s '
|
||||||
'%(instance)s',
|
'%(instance)s',
|
||||||
help='Prefix each line of exception output with this format'),
|
help='Prefix each line of exception output with this format.'),
|
||||||
cfg.ListOpt('default_log_levels',
|
cfg.ListOpt('default_log_levels',
|
||||||
default=[
|
default=[
|
||||||
'amqp=WARN',
|
'amqp=WARN',
|
||||||
@@ -167,25 +167,25 @@ log_opts = [
|
|||||||
'iso8601=WARN',
|
'iso8601=WARN',
|
||||||
'requests.packages.urllib3.connectionpool=WARN'
|
'requests.packages.urllib3.connectionpool=WARN'
|
||||||
],
|
],
|
||||||
help='List of logger=LEVEL pairs'),
|
help='List of logger=LEVEL pairs.'),
|
||||||
cfg.BoolOpt('publish_errors',
|
cfg.BoolOpt('publish_errors',
|
||||||
default=False,
|
default=False,
|
||||||
help='Publish error events'),
|
help='Enables or disables publication of error events.'),
|
||||||
cfg.BoolOpt('fatal_deprecations',
|
cfg.BoolOpt('fatal_deprecations',
|
||||||
default=False,
|
default=False,
|
||||||
help='Make deprecations fatal'),
|
help='Enables or disables fatal status of deprecations.'),
|
||||||
|
|
||||||
# NOTE(mikal): there are two options here because sometimes we are handed
|
# NOTE(mikal): there are two options here because sometimes we are handed
|
||||||
# a full instance (and could include more information), and other times we
|
# a full instance (and could include more information), and other times we
|
||||||
# are just handed a UUID for the instance.
|
# are just handed a UUID for the instance.
|
||||||
cfg.StrOpt('instance_format',
|
cfg.StrOpt('instance_format',
|
||||||
default='[instance: %(uuid)s] ',
|
default='[instance: %(uuid)s] ',
|
||||||
help='If an instance is passed with the log message, format '
|
help='The format for an instance that is passed with the log '
|
||||||
'it like this'),
|
'message. '),
|
||||||
cfg.StrOpt('instance_uuid_format',
|
cfg.StrOpt('instance_uuid_format',
|
||||||
default='[instance: %(uuid)s] ',
|
default='[instance: %(uuid)s] ',
|
||||||
help='If an instance UUID is passed with the log message, '
|
help='The format for an instance UUID that is passed with the '
|
||||||
'format it like this'),
|
'log message. '),
|
||||||
]
|
]
|
||||||
|
|
||||||
CONF = cfg.CONF
|
CONF = cfg.CONF
|
||||||
@@ -424,9 +424,7 @@ class JSONFormatter(logging.Formatter):
|
|||||||
|
|
||||||
def _create_logging_excepthook(product_name):
|
def _create_logging_excepthook(product_name):
|
||||||
def logging_excepthook(exc_type, value, tb):
|
def logging_excepthook(exc_type, value, tb):
|
||||||
extra = {}
|
extra = {'exc_info': (exc_type, value, tb)}
|
||||||
if CONF.verbose or CONF.debug:
|
|
||||||
extra['exc_info'] = (exc_type, value, tb)
|
|
||||||
getLogger(product_name).critical(
|
getLogger(product_name).critical(
|
||||||
"".join(traceback.format_exception_only(exc_type, value)),
|
"".join(traceback.format_exception_only(exc_type, value)),
|
||||||
**extra)
|
**extra)
|
||||||
@@ -451,7 +449,7 @@ def _load_log_config(log_config_append):
|
|||||||
logging.config.fileConfig(log_config_append,
|
logging.config.fileConfig(log_config_append,
|
||||||
disable_existing_loggers=False)
|
disable_existing_loggers=False)
|
||||||
except moves.configparser.Error as exc:
|
except moves.configparser.Error as exc:
|
||||||
raise LogConfigError(log_config_append, str(exc))
|
raise LogConfigError(log_config_append, six.text_type(exc))
|
||||||
|
|
||||||
|
|
||||||
def setup(product_name, version='unknown'):
|
def setup(product_name, version='unknown'):
|
||||||
@@ -571,9 +569,15 @@ def _setup_logging_from_conf(project, version):
|
|||||||
|
|
||||||
for pair in CONF.default_log_levels:
|
for pair in CONF.default_log_levels:
|
||||||
mod, _sep, level_name = pair.partition('=')
|
mod, _sep, level_name = pair.partition('=')
|
||||||
level = logging.getLevelName(level_name)
|
|
||||||
logger = logging.getLogger(mod)
|
logger = logging.getLogger(mod)
|
||||||
|
# NOTE(AAzza) in python2.6 Logger.setLevel doesn't convert string name
|
||||||
|
# to integer code.
|
||||||
|
if sys.version_info < (2, 7):
|
||||||
|
level = logging.getLevelName(level_name)
|
||||||
logger.setLevel(level)
|
logger.setLevel(level)
|
||||||
|
else:
|
||||||
|
logger.setLevel(level_name)
|
||||||
|
|
||||||
|
|
||||||
_loggers = {}
|
_loggers = {}
|
||||||
|
|
||||||
|
@@ -78,7 +78,7 @@ def bool_from_string(subject, strict=False, default=False):
|
|||||||
Strings yielding False are 'f', 'false', 'off', 'n', 'no', or '0'.
|
Strings yielding False are 'f', 'false', 'off', 'n', 'no', or '0'.
|
||||||
"""
|
"""
|
||||||
if not isinstance(subject, six.string_types):
|
if not isinstance(subject, six.string_types):
|
||||||
subject = str(subject)
|
subject = six.text_type(subject)
|
||||||
|
|
||||||
lowered = subject.strip().lower()
|
lowered = subject.strip().lower()
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user