Added i18n formatting to log messages

Change-Id: I22143feee4ab936aac91b14f4dafb6fcdde07d7e
This commit is contained in:
Ronald Bradford 2016-03-16 12:08:54 -04:00
parent 93e2449ab0
commit 20e6e90b44
6 changed files with 99 additions and 25 deletions

50
oslo_config/_i18n.py Normal file
View File

@ -0,0 +1,50 @@
# Copyright 2016 OpenStack Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""oslo.i18n integration module.
See http://docs.openstack.org/developer/oslo.i18n/usage.html .
"""
import oslo_i18n
DOMAIN = "oslo.config"
_translators = oslo_i18n.TranslatorFactory(domain=DOMAIN)
# The primary translation function using the well-known name "_"
_ = _translators.primary
# The contextual translation function using the name "_C"
# requires oslo.i18n >=2.1.0
_C = _translators.contextual_form
# The plural translation function using the name "_P"
# requires oslo.i18n >=2.1.0
_P = _translators.plural_form
# 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
def get_available_languages():
return oslo_i18n.get_available_languages(DOMAIN)

View File

@ -375,6 +375,7 @@ import sys
import six
from six import moves
from oslo_config._i18n import _LI, _LW
from oslo_config import iniparser
from oslo_config import types
@ -817,9 +818,10 @@ class Opt(object):
if self.deprecated_for_removal and not self._logged_deprecation:
self._logged_deprecation = True
pretty_group = group_name or 'DEFAULT'
LOG.warning('Option "%s" from group "%s" is deprecated for '
'removal. Its value may be silently ignored in the '
'future.', self.dest, pretty_group)
LOG.warning(_LW('Option "%(option)s" from group "%(group)s" is '
'deprecated for removal. Its value may be '
'silently ignored in the future.'),
{'option': self.dest, 'group': pretty_group})
return value
def _add_to_cli(self, parser, group=None):
@ -1660,8 +1662,9 @@ class MultiConfigParser(object):
_Namespace.
"""
_deprecated_opt_message = ('Option "%s" from group "%s" is deprecated. '
'Use option "%s" from group "%s".')
_deprecated_opt_message = _LW('Option "%(dep_option)s" from group '
'"%(dep_group)s" is deprecated. Use option '
'"%(option)s" from group "%(group)s".')
def __init__(self):
self.parsed = []
@ -1751,8 +1754,9 @@ class MultiConfigParser(object):
# NOTE(bnemec): Not using versionutils for this to avoid a
# circular dependency between oslo.config and whatever library
# versionutils ends up in.
LOG.warning(self._deprecated_opt_message, name[1],
name[0], current[1], current[0])
LOG.warning(self._deprecated_opt_message,
{'dep_option': name[1], 'dep_group': name[0],
'option': current[1], 'group': current[0]})
class _Namespace(argparse.Namespace):
@ -1769,8 +1773,9 @@ class _Namespace(argparse.Namespace):
or convert a config file value at this point.
"""
_deprecated_opt_message = ('Option "%s" from group "%s" is deprecated. '
'Use option "%s" from group "%s".')
_deprecated_opt_message = _LW('Option "%(dep_option)s" from group '
'"%(dep_group)s" is deprecated. Use option '
'"%(option)s" from group "%(group)s".')
def __init__(self, conf):
self._conf = conf
@ -1930,8 +1935,9 @@ class _Namespace(argparse.Namespace):
# NOTE(bnemec): Not using versionutils for this to avoid a
# circular dependency between oslo.config and whatever library
# versionutils ends up in.
LOG.warning(self._deprecated_opt_message, name[1],
name[0], current[1], current[0])
LOG.warning(self._deprecated_opt_message,
{'dep_option': name[1], 'dep_group': name[0],
'option': current[1], 'group': current[0]})
def _get_value(self, names, multi=False, positional=False,
current_name=None, normalized=True):
@ -2831,12 +2837,12 @@ class ConfigOpts(collections.Mapping):
try:
namespace = self._reload_config_files()
except SystemExit as exc:
LOG.warning("Caught SystemExit while reloading configure files "
"with exit code: %d", exc.code)
LOG.warning(_LW("Caught SystemExit while reloading configure "
"files with exit code: %d"), exc.code)
return False
except Error as err:
LOG.warning("Caught Error while reloading configure files: %s",
err)
LOG.warning(_LW("Caught Error while reloading configure files: "
" %s"), err)
return False
else:
self._namespace = namespace
@ -2877,8 +2883,12 @@ class ConfigOpts(collections.Mapping):
sorted_fresh = sorted(fresh.items(), key=key_fn)
for (groupname, optname), (old, new) in sorted_fresh:
groupname = groupname if groupname else 'DEFAULT'
LOG.info("Option %s.%s changed from [%s] to [%s]",
groupname, optname, old, new)
LOG.info(_LI("Option %(group)s.%(option)s changed from "
"[%(old_val)s] to [%(new_val)s]"),
{'group': groupname,
'option': optname,
'old_val': old,
'new_val': new})
for hook in self._mutate_hooks:
hook(self, fresh)
return fresh
@ -2903,8 +2913,9 @@ class ConfigOpts(collections.Mapping):
except KeyError:
new = None
if old != new:
LOG.warning("Ignoring change to immutable option %s.%s"
% (groupname, opt.name))
LOG.warning(_LW("Ignoring change to immutable option "
"%(group)s.%(option)s"),
{"group": groupname, "option": opt.name})
def _diff_ns(self, old_ns, new_ns):
"""Compare mutable option values between two namespaces.

View File

@ -32,6 +32,7 @@ import textwrap
import pkg_resources
import six
from oslo_config._i18n import _LW
from oslo_config import cfg
import stevedore.named # noqa
@ -93,7 +94,7 @@ def _format_defaults(opt):
key=operator.itemgetter(0))
default_str = ','.join(['%s:%s' % i for i in sorted_items])
else:
LOG.warning('Unknown option type: %s', repr(opt))
LOG.warning(_LW('Unknown option type: %s'), repr(opt))
default_str = str(opt.default)
defaults = [default_str]
@ -166,7 +167,7 @@ class _OptFormatter(object):
:param opt: a cfg.Opt instance
"""
if not opt.help:
LOG.warning('"%s" is missing a help string', opt.dest)
LOG.warning(_LW('"%s" is missing a help string'), opt.dest)
option_type = getattr(opt, 'type', None)
opt_type = getattr(option_type, 'type_name', 'unknown value')

View File

@ -4354,7 +4354,10 @@ class DeprecationWarningTestScenarios(DeprecationWarningTestBase):
self.assertEqual('baz', self.conf.other.foo)
if self.deprecated:
expected = (self._parser_class._deprecated_opt_message %
('bar', self.group, 'foo', self.group) + '\n')
{'dep_option': 'bar',
'dep_group': self.group,
'option': 'foo',
'group': self.group} + '\n')
else:
expected = ''
self.assertEqual(expected, self.log_fixture.output)
@ -4393,8 +4396,10 @@ class DeprecationWarningTests(DeprecationWarningTestBase):
def assert_message_logged(self, deprecated_name, deprecated_group,
current_name, current_group):
expected = (self._parser_class._deprecated_opt_message %
(deprecated_name, deprecated_group,
current_name, current_group)
{'dep_option': deprecated_name,
'dep_group': deprecated_group,
'option': current_name,
'group': current_group}
)
self.assertEqual(expected + '\n', self.log_fixture.output)
@ -4452,5 +4457,8 @@ class DeprecationWarningTests(DeprecationWarningTestBase):
self.conf(['--config-file', paths[0]])
self.assertEqual('baz', self.conf.other.foo)
expected = (self._parser_class._deprecated_opt_message %
('bar', 'other', 'foo-bar', 'other') + '\n')
{'dep_option': 'bar',
'dep_group': 'other',
'option': 'foo-bar',
'group': 'other'} + '\n')
self.assertEqual(expected, self.log_fixture.output)

View File

@ -6,3 +6,4 @@ debtcollector>=1.2.0 # Apache-2.0
netaddr!=0.7.16,>=0.7.12 # BSD
six>=1.9.0 # MIT
stevedore>=1.10.0 # Apache-2.0
oslo.i18n>=2.1.0 # Apache-2.0

View File

@ -44,3 +44,6 @@ commands = pip-missing-reqs -d --ignore-module=oslo_config* --ignore-module=pkg_
[testenv:releasenotes]
commands = sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html
[hacking]
import_exceptions = oslo_config._i18n