Pickup instance from log format record

Nova has moved to oslo.log, however one specific usecase is
blowing up in Nova. when they use instance=instance in say
LOG.info to pass in instance, they expect the uuid in the
instance dict/object to be printed in the log. However we
end up with the string-ified version of the Instance object
or the entire instance dict which is not good.

Closes-Bug: #1426544
Change-Id: I2d1b09015bead2012327f973f45f3f6728160c69
This commit is contained in:
Davanum Srinivas 2015-02-27 16:24:09 -05:00
parent 5139941a0c
commit 60e773057b
2 changed files with 48 additions and 4 deletions

View File

@ -169,9 +169,23 @@ class ContextFormatter(logging.Formatter):
record.project = self.project
record.version = self.version
# FIXME(dims): We need a better way to pick up the instance
# or instance_uuid parameters from the kwargs from say
# LOG.info or LOG.warn
instance_extra = ''
instance = getattr(record, 'instance', None)
instance_uuid = getattr(record, 'instance_uuid', None)
context = _update_record_with_context(record)
if context:
if instance:
try:
instance_extra = (self.conf.instance_format
% instance)
except TypeError:
instance_extra = instance
elif instance_uuid:
instance_extra = (self.conf.instance_uuid_format
% {'uuid': instance_uuid})
elif context:
# FIXME(dhellmann): We should replace these nova-isms with
# more generic handling in the Context class. See the
# app-agnostic-logging-parameters blueprint.
@ -182,7 +196,6 @@ class ContextFormatter(logging.Formatter):
# RequestContext
resource_uuid = getattr(context, 'resource_uuid', None)
instance_extra = ''
if instance:
instance_extra = (self.conf.instance_format
% {'uuid': instance})
@ -192,7 +205,8 @@ class ContextFormatter(logging.Formatter):
elif resource_uuid:
instance_extra = (self.conf.instance_uuid_format
% {'uuid': resource_uuid})
record.instance = instance_extra
record.instance = instance_extra
# NOTE(sdague): default the fancier formatting params
# to an empty string so we don't throw an exception if

View File

@ -486,6 +486,36 @@ class FancyRecordTestCase(LogTestBase):
self.assertEqual(infoexpected, self.stream.getvalue())
class InstanceRecordTestCase(LogTestBase):
def setUp(self):
super(InstanceRecordTestCase, self).setUp()
self.config(logging_context_format_string="[%(request_id)s]: "
"%(instance)s"
"%(resource)s"
"%(message)s",
logging_default_format_string="%(instance)s"
"%(resource)s"
"%(message)s")
self.log = log.getLogger()
self._add_handler_with_cleanup(self.log)
self._set_log_level_with_cleanup(self.log, logging.DEBUG)
def test_instance_dict_in_context_log_msg(self):
ctxt = _fake_context()
fake_resource = {'uuid': 'C9B7CCC6-8A12-4C53-A736-D7A1C36A62F3'}
self.log.info("info", context=ctxt, instance=fake_resource)
infoexpected = "[%s]: [instance: C9B7CCC6-8A12-4C53-A736-" \
"D7A1C36A62F3] info\n" % ctxt.request_id
self.assertEqual(infoexpected, self.stream.getvalue())
def test_instance_dict_in_default_log_msg(self):
fake_resource = {'uuid': 'C9B7CCC6-8A12-4C53-A736-D7A1C36A62F3'}
self.log.info("info", instance=fake_resource)
infoexpected = "[instance: C9B7CCC6-8A12-4C53-A736-" \
"D7A1C36A62F3] info\n"
self.assertEqual(infoexpected, self.stream.getvalue())
class DomainTestCase(LogTestBase):
def setUp(self):
super(DomainTestCase, self).setUp()