From 03ba99ad31ccfec30614569d6d65f2ae41f24231 Mon Sep 17 00:00:00 2001 From: James Carey Date: Tue, 5 Aug 2014 19:57:47 +0000 Subject: [PATCH] Add unicode coercion of logged messages to ContextFormatter The ContextAdapter is being retired as part of blueprint remove-context-adapter so any processing in the ContextAdapter needs to be added to the ContextFormatter. Coercion in the ContextAdapter was fixed as part of change-id: I26b0d3490f731f6fdb9a429aa9ef59360ddc88ba Partially implements blueprint remove-context-adapter Change-Id: Icf4533074b45623983f4e3eeb7e1a1ae618bf605 --- openstack/common/log.py | 6 ++++++ tests/unit/test_log.py | 19 ++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/openstack/common/log.py b/openstack/common/log.py index 8480b485..0bcc2e3e 100644 --- a/openstack/common/log.py +++ b/openstack/common/log.py @@ -621,6 +621,12 @@ class ContextFormatter(logging.Formatter): def format(self, record): """Uses contextstring if request_id is set, otherwise default.""" + # NOTE(jecarey): If msg is not unicode, coerce it into unicode + # before it can get to the python logging and + # possibly cause string encoding trouble + if not isinstance(record.msg, six.text_type): + record.msg = six.text_type(record.msg) + # store project info record.project = self.project record.version = self.version diff --git a/tests/unit/test_log.py b/tests/unit/test_log.py index facd2433..03890be8 100644 --- a/tests/unit/test_log.py +++ b/tests/unit/test_log.py @@ -408,7 +408,7 @@ class ContextFormatterTestCase(LogTestBase): six.text_type(message)) self.assertEqual(expected, self.stream.getvalue()) - def test_unicode_conversion(self): + def test_unicode_conversion_in_adapter(self): ctxt = _fake_context() ctxt.request_id = six.text_type('99') message = "Exception is (%s)" @@ -419,6 +419,23 @@ class ContextFormatterTestCase(LogTestBase): message) self.assertEqual(expected, self.stream.getvalue()) + def test_unicode_conversion_in_formatter(self): + ctxt = _fake_context() + local.store.context = ctxt + ctxt.request_id = six.text_type('99') + try: + no_adapt_log = logging.getLogger('no_adapt') + no_adapt_log.setLevel(logging.INFO) + message = "Exception is (%s)" + ex = Exception(gettextutils.Message('test' + six.unichr(128))) + no_adapt_log.info(message, ex) + message = six.text_type(message) % ex + expected = "HAS CONTEXT [%s]: %s\n" % (ctxt.request_id, + message) + self.assertEqual(expected, self.stream.getvalue()) + finally: + del local.store.context + class ExceptionLoggingTestCase(LogTestBase): """Test that Exceptions are logged."""