Use six.text_type() when logging Instance object
We're seeing a trace in gate jobs, for example:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position
402: ordinal not in range(128)
when attempting to log an Instance object with a unicode display name.
This resurfaced relatively recently because of the change in devstack
to use the new OSJournalHandler with use_journal=True which is
suspected of causing some deadlock issues [1] unrelated to this bug.
The problem occurs in code that logs an entire Instance object when
the object has a field with unicode characters in it (display_name).
When the object is sent to logging, the UnicodeDecodeError is raised
while formatting the log record here [2]. This implies an implicit
conversion attempt to unicode at this point.
I found that with the Instance object, the conversion to unicode fails
with the UnicodeDecodeError unless the encoding 'utf-8' is explicitly
specified to six.text_type(). And when specifying an encoding to
six.text_type(), the argument to convert must be a string, not an
Instance object, so this does the conversion in two steps as a utility
function:
1. Get the string representation of the Instance with repr()
2. Call six.text_type(instance_repr, 'utf-8') passing the encoding
if not six.PY3
Closes-Bug: #1580728
[1] https://review.openstack.org/#/c/462163
[2] https://github.com/python/cpython/blob/2e576f5/Lib/logging/__init__.py#L338
Change-Id: I0fc3ae02cb2e401b3240faf0d8b6aa5dc52b91fc
This commit is contained in:
@@ -1258,6 +1258,18 @@ def get_sha256_str(base_str):
|
||||
return hashlib.sha256(base_str).hexdigest()
|
||||
|
||||
|
||||
def get_obj_repr_unicode(obj):
|
||||
"""Returns a string representation of an object converted to unicode.
|
||||
|
||||
In the case of python 3, this just returns the repr() of the object,
|
||||
else it converts the repr() to unicode.
|
||||
"""
|
||||
obj_repr = repr(obj)
|
||||
if not six.PY3:
|
||||
obj_repr = six.text_type(obj_repr, 'utf-8')
|
||||
return obj_repr
|
||||
|
||||
|
||||
def filter_and_format_resource_metadata(resource_type, resource_list,
|
||||
search_filts, metadata_type=None):
|
||||
"""Get all metadata for a list of resources after filtering.
|
||||
|
||||
Reference in New Issue
Block a user