Replace '_' with '_LI', '_LE', '_LW', '_LC'

oslo.i18n uses different marker functions to separate the
translatable messages into different catalogs, which the translation
teams can prioritize translating. For details, please refer to:
http://docs.openstack.org/developer/oslo.i18n/guidelines.html#guidelines-for-use-in-openstack

Added hacking rules for warning, info, critical, error and exception
about checking translation for log messages and fixed for below cases only,
1. LOG.error(_(""))
2. LOG.info(_(""))
3. LOG.exception(_(""))
4. LOG.critical(_(""))
5. LOG.warning(_(""))

Below scenario is not handled in this patch,
If message is passed to LOG call using separate variable,
ex.
    msg = (_("")
    LOG.error(msg)

Change-Id: Idbf8779cdfc41ca1424bebcd101096bec482872f
This commit is contained in:
Pranali Deore 2014-12-09 05:23:48 -08:00 committed by PranaliDeore
parent cc3435647d
commit 6eebebc80b
7 changed files with 76 additions and 19 deletions

View File

@ -16,3 +16,9 @@ glance Specific Commandments
assertIsNone(A)
- [G319] Validate that debug level logs are not translated
- [G320] For python 3 compatibility, use six.text_type() instead of unicode()
- [G321] Validate that LOG messages, except debug ones, have translations
- [G322] Validate that LOG.info messages use _LI.
- [G323] Validate that LOG.exception messages use _LE.
- [G324] Validate that LOG.error messages use _LE.
- [G325] Validate that LOG.critical messages use _LC.
- [G326] Validate that LOG.warning messages use _LW.

View File

@ -22,6 +22,7 @@ from glance import i18n
import glance.openstack.common.log as logging
_ = i18n._
_LE = i18n._LE
location_strategy_opts = [
cfg.StrOpt('location_strategy', default='location_order',
@ -61,8 +62,9 @@ def _load_strategies():
mgr.driver.init()
modules[strategy_name] = mgr.driver
except Exception as e:
LOG.error(_("Failed to load location strategy module "
"%(module)s: %(e)s") % {'module': module_name, 'e': e})
LOG.error(_LE("Failed to load location strategy module "
"%(module)s: %(e)s") % {'module': module_name,
'e': e})
return modules

View File

@ -32,6 +32,7 @@ from glance.openstack.common import policy
CONFIG = ConfigParser.SafeConfigParser(dict_type=OrderedDict)
LOG = logging.getLogger(__name__)
_ = i18n._
_LE = i18n._LE
property_opts = [
cfg.StrOpt('property_protection_file',
@ -99,9 +100,9 @@ class PropertyRules(object):
if self.prop_prot_rule_format == 'policies':
if ',' in permissions:
LOG.error(
_("Multiple policies '%s' not allowed"
"for a given operation. Policies can be "
"combined in the policy file"),
_LE("Multiple policies '%s' not allowed "
"for a given operation. Policies can be "
"combined in the policy file"),
permissions)
raise InvalidPropProtectConf()
self.prop_exp_mapping[compiled_rule] = property_exp

View File

@ -25,6 +25,7 @@ from glance import i18n
from glance.openstack.common import log as logging
_ = i18n._
_LE = i18n._LE
swift_opts = [
cfg.StrOpt('default_swift_reference',
@ -97,6 +98,6 @@ class SwiftParams(object):
reference['key'] = CONFIG.get(ref, 'key')
account_params[ref] = reference
except (ValueError, SyntaxError, ConfigParser.NoOptionError) as e:
LOG.exception(_("Invalid format of swift store config"
"cfg"))
LOG.exception(_LE("Invalid format of swift store config "
"cfg"))
return account_params

View File

@ -51,6 +51,8 @@ import glance.openstack.common.log as logging
_ = i18n._
_LE = i18n._LE
_LI = i18n._LI
bind_opts = [
cfg.StrOpt('bind_host', default='0.0.0.0',
@ -265,7 +267,7 @@ class Server(object):
self.pool.spawn_n(self._single_run, self.application, self.sock)
return
else:
LOG.info(_("Starting %d workers") % CONF.workers)
LOG.info(_LI("Starting %d workers") % CONF.workers)
signal.signal(signal.SIGTERM, kill_children)
signal.signal(signal.SIGINT, kill_children)
signal.signal(signal.SIGHUP, hup)
@ -280,13 +282,14 @@ class Server(object):
try:
pid, status = os.wait()
if os.WIFEXITED(status) or os.WIFSIGNALED(status):
LOG.info(_('Removing dead child %s') % pid)
LOG.info(_LI('Removing dead child %s') % pid)
self.children.remove(pid)
if os.WIFEXITED(status) and os.WEXITSTATUS(status) != 0:
LOG.error(_('Not respawning child %d, cannot '
'recover from termination') % pid)
LOG.error(_LE('Not respawning child %d, cannot '
'recover from termination') % pid)
if not self.children:
LOG.info(_('All workers have terminated. Exiting'))
LOG.info(_LI('All workers have terminated. '
'Exiting'))
self.running = False
else:
self.run_child()
@ -294,7 +297,7 @@ class Server(object):
if err.errno not in (errno.EINTR, errno.ECHILD):
raise
except KeyboardInterrupt:
LOG.info(_('Caught keyboard interrupt. Exiting.'))
LOG.info(_LI('Caught keyboard interrupt. Exiting.'))
break
eventlet.greenio.shutdown_safe(self.sock)
self.sock.close()
@ -320,12 +323,12 @@ class Server(object):
# and is respawned unnecessarily as a result
signal.signal(signal.SIGINT, signal.SIG_IGN)
self.run_server()
LOG.info(_('Child %d exiting normally') % os.getpid())
LOG.info(_LI('Child %d exiting normally') % os.getpid())
# self.pool.waitall() has been called by run_server, so
# its safe to exit here
sys.exit(0)
else:
LOG.info(_('Started child %s') % pid)
LOG.info(_LI('Started child %s') % pid)
self.children.append(pid)
def run_server(self):
@ -349,7 +352,7 @@ class Server(object):
def _single_run(self, application, sock):
"""Start a WSGI server in a new green thread."""
LOG.info(_("Starting single process server"))
LOG.info(_LI("Starting single process server"))
eventlet.wsgi.server(sock, application, custom_pool=self.pool,
log=self._wsgi_logger,
debug=False)

View File

@ -14,6 +14,8 @@
import re
import pep8
"""
Guidelines for writing new hacking checks
@ -41,6 +43,18 @@ asse_equal_end_with_none_re = re.compile(
asse_equal_start_with_none_re = re.compile(
r"(.)*assertEqual\(None, (\w|\.|\'|\"|\[|\])+\)")
unicode_func_re = re.compile(r"(\s|\W|^)unicode\(")
log_translation = re.compile(
r"(.)*LOG\.(audit)\(\s*('|\")")
log_translation_info = re.compile(
r"(.)*LOG\.(info)\(\s*(_\(|'|\")")
log_translation_exception = re.compile(
r"(.)*LOG\.(exception)\(\s*(_\(|'|\")")
log_translation_error = re.compile(
r"(.)*LOG\.(error)\(\s*(_\(|'|\")")
log_translation_critical = re.compile(
r"(.)*LOG\.(critical)\(\s*(_\(|'|\")")
log_translation_warning = re.compile(
r"(.)*LOG\.(warning)\(\s*(_\(|'|\")")
def assert_true_instance(logical_line):
@ -101,9 +115,34 @@ def no_direct_use_of_unicode_function(logical_line):
yield(0, "G320: Use six.text_type() instead of unicode()")
def validate_log_translations(logical_line, physical_line, filename):
# Translations are not required in the test directory
if pep8.noqa(physical_line):
return
msg = "G322: LOG.info messages require translations `_LI()`!"
if log_translation_info.match(logical_line):
yield (0, msg)
msg = "G323: LOG.exception messages require translations `_LE()`!"
if log_translation_exception.match(logical_line):
yield (0, msg)
msg = "G324: LOG.error messages require translations `_LE()`!"
if log_translation_error.match(logical_line):
yield (0, msg)
msg = "G325: LOG.critical messages require translations `_LC()`!"
if log_translation_critical.match(logical_line):
yield (0, msg)
msg = "G326: LOG.warning messages require translations `_LW()`!"
if log_translation_warning.match(logical_line):
yield (0, msg)
msg = "G321: Log messages require translations!"
if log_translation.match(logical_line):
yield (0, msg)
def factory(register):
register(assert_true_instance)
register(assert_equal_type)
register(assert_equal_none)
register(no_translate_debug_logs)
register(no_direct_use_of_unicode_function)
register(validate_log_translations)

View File

@ -20,9 +20,14 @@ from oslo.config import cfg
import glance.context
import glance.db.sqlalchemy.api as db_api
from glance import i18n
import glance.openstack.common.log as logging
import glance.registry.context
_ = i18n._
_LC = i18n._LC
_LI = i18n._LI
LOG = logging.getLogger(__name__)
LOG.addHandler(logging.StreamHandler())
LOG.setLevel(logging.DEBUG)
@ -44,7 +49,7 @@ def build_image_owner_map(owner_map, db, context):
owner_name = image['owner']
if not owner_name:
LOG.info('Image %s has no owner. Skipping.' % image_id)
LOG.info(_LI('Image %s has no owner. Skipping.') % image_id)
continue
try:
@ -65,7 +70,7 @@ def build_image_owner_map(owner_map, db, context):
def update_image_owners(image_owner_map, db, context):
for (image_id, image_owner) in image_owner_map.items():
db.image_update(context, image_id, {'owner': image_owner})
LOG.info('Image %s successfully updated.' % image_id)
LOG.info(_LI('Image %s successfully updated.') % image_id)
if __name__ == "__main__":
@ -96,7 +101,7 @@ if __name__ == "__main__":
admin_password = config.keystone_admin_password
if not (auth_uri and admin_tenant_name and admin_user and admin_password):
LOG.critical('Missing authentication arguments')
LOG.critical(_LC('Missing authentication arguments'))
sys.exit(1)
ks = keystoneclient.v2_0.client.Client(username=admin_user,