From 572cfecb4da5c618a407b8de2a7feae9c3f35ce4 Mon Sep 17 00:00:00 2001 From: Matt Odden Date: Tue, 1 Oct 2013 05:11:43 +0000 Subject: [PATCH] Make Messages unicode before hitting logging Some of the log handlers in the python standard library are hitting issues with Messages since they check for basestring types only, and attempt to coerce anything else to string. This leads to Messages being coerced to bad encodings, resulting in unhandled exceptions. This change adds a check that looks for non-basestring objects and coerces them to unicode before they hit the problematic logging areas. bug 1225099 Change-Id: I0bff6b52205e3c88db38876b8c6de1bd820f460a Co-authored-by: Luis A. Garcia --- openstack/common/log.py | 7 +++++++ tests/unit/test_log.py | 14 ++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/openstack/common/log.py b/openstack/common/log.py index c7ee361da..2cd02efee 100644 --- a/openstack/common/log.py +++ b/openstack/common/log.py @@ -249,6 +249,13 @@ def deprecated(self, msg, *args, **kwargs): self.warn(stdmsg, *args, **kwargs) def process(self, msg, kwargs): + # NOTE(mrodden): catch any Message/other object and + # coerce to unicode before they can get + # to the python logging and possibly + # cause string encoding trouble + if not isinstance(msg, basestring): + msg = unicode(msg) + if 'extra' not in kwargs: kwargs['extra'] = {} extra = kwargs['extra'] diff --git a/tests/unit/test_log.py b/tests/unit/test_log.py index b9802b525..ee71faf82 100644 --- a/tests/unit/test_log.py +++ b/tests/unit/test_log.py @@ -25,6 +25,7 @@ from openstack.common import context from openstack.common.fixture import config from openstack.common.fixture import moxstubout +from openstack.common import gettextutils from openstack.common import jsonutils from openstack.common import log from openstack.common import log_handler @@ -263,6 +264,19 @@ def test_debugging_log(self): self.log.debug("baz") self.assertEqual("NOCTXT: baz --DBG\n", self.stream.getvalue()) + def test_message_logging(self): + # NOTE(luisg): Logging message objects with unicode objects + # may cause trouble by the logging mechanism trying to coerce + # the Message object, with a wrong encoding. This test case + # tests that problem does not occur. + ctxt = _fake_context() + ctxt.request_id = unicode('99') + message = gettextutils.Message('test ' + unichr(128), 'test') + self.log.info(message, context=ctxt) + expected = "HAS CONTEXT [%s]: %s\n" % (ctxt.request_id, + unicode(message)) + self.assertEqual(expected, self.stream.getvalue()) + class ExceptionLoggingTestCase(test.BaseTestCase): """Test that Exceptions are logged."""