From 9524fdf7a6b9a4e66e8a28003bd32f072debb431 Mon Sep 17 00:00:00 2001 From: Brian Curtin Date: Fri, 14 Aug 2015 11:50:24 -0500 Subject: [PATCH] Only log text strings in requests As was exposed by object_store.create_object, we were attempting to mix text and bytes in log messages, which was causing _logger.debug to choke when combining the parts of the message, specifically the --data piece. This is an issue for two reasons: 1. It's binary data in general 2. It's a very large amount of binary data The fix is to not log byte strings that come in as `data` unless we can decode them to ascii. This will allow us to continue logging some data such as auth credentials, but we won't be logging megabytes or gigabytes worth of binary data - such as objects being uploaded to Swift - into the log file. Change-Id: Iba49552b8ebc58a46cedf826751193a1fa7feb11 Partial-Bug: 1485054 --- openstack/transport.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/openstack/transport.py b/openstack/transport.py index a0d5225d0..ce01533ae 100644 --- a/openstack/transport.py +++ b/openstack/transport.py @@ -364,8 +364,26 @@ class Transport(requests.Session): if 'data' in kwargs and kwargs['data'] is not None: string_parts.append("--data '") - string_parts.append(kwargs['data']) + + data = kwargs['data'] + # Only log text strings and byte strings that can be decoded + # in ascii. Raw byte strings both mess up the actual + # writing of the data to any log stream because we'd be mixing + # text and bytes, and they are generally overly long strings + # that would make the logs unreadable anyway. + if isinstance(data, six.binary_type): + # Some data, such as auth creds, is generally decodable + # to ascii. If it works, log it, otherwise put in a + # placeholder to specify that it's a blob of binary data. + try: + string_parts.append(data.decode("ascii")) + except UnicodeDecodeError: + string_parts.append("") + else: + string_parts.append(data) + string_parts.append("'") + _logger.debug("REQ: %s" % " ".join(string_parts)) def _log_response(self, response):