summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladyslav Drok <vdrok@mirantis.com>2018-07-20 14:17:43 +0300
committerStephen Finucane <stephenfin@redhat.com>2019-12-09 15:18:45 +0000
commitb52c8cd247e9b185d176bfbc4c24c5a2cb35e5be (patch)
tree25f3fed2af1b7a52b25f429bf34bfe4ccece2574
parent1f6336a25a90a32c9fa93d0972a1bdfa13c3e61a (diff)
downloadoslo-log-b52c8cd247e9b185d176bfbc4c24c5a2cb35e5be.tar.gz
Serialize complex objects in FluentFormatter3.45.1
This change introduces the serialization with basically json dumps, falling back to repr for non-serializable object. We check the types of the top level objects passed to the formatter, as for example an object enclosed into dictionary passed to the logger should be a much more rare case. Closes-Bug: 1782361 Change-Id: Ib214f95abfadd91f85b6cce853057a572ec287f6
-rw-r--r--oslo_log/formatters.py30
1 files changed, 20 insertions, 10 deletions
diff --git a/oslo_log/formatters.py b/oslo_log/formatters.py
index 3c50899..8aa73c6 100644
--- a/oslo_log/formatters.py
+++ b/oslo_log/formatters.py
@@ -184,6 +184,19 @@ class _ReplaceFalseValue(dict):
_MSG_KEY_REGEX = re.compile(r'(%+)\((\w+)\)')
+def _json_dumps_with_fallback(obj):
+ if _HAVE_JSONUTILS_FALLBACK:
+ # Bug #1593641: If an object cannot be serialized to JSON, convert
+ # it using repr() to prevent serialization errors. Using repr() is
+ # not ideal, but serialization errors are unexpected on logs,
+ # especially when the code using logs is not aware that the
+ # JSONFormatter will be used.
+ convert = functools.partial(jsonutils.to_primitive, fallback=repr)
+ return jsonutils.dumps(obj, default=convert)
+ else:
+ return jsonutils.dumps(obj)
+
+
class JSONFormatter(logging.Formatter):
def __init__(self, fmt=None, datefmt=None, style='%'):
# NOTE(sfinucan) we ignore the fmt and style arguments, but they're
@@ -271,16 +284,7 @@ class JSONFormatter(logging.Formatter):
if record.exc_info:
message['traceback'] = self.formatException(record.exc_info)
- if _HAVE_JSONUTILS_FALLBACK:
- # Bug #1593641: If an object cannot be serialized to JSON, convert
- # it using repr() to prevent serialization errors. Using repr() is
- # not ideal, but serialization errors are unexpected on logs,
- # especially when the code using logs is not aware that the
- # JSONFormatter will be used.
- convert = functools.partial(jsonutils.to_primitive, fallback=repr)
- return jsonutils.dumps(message, default=convert)
- else:
- return jsonutils.dumps(message)
+ return _json_dumps_with_fallback(message)
class FluentFormatter(logging.Formatter):
@@ -352,6 +356,12 @@ class FluentFormatter(logging.Formatter):
else:
message['context'] = {}
extra.pop('context', None)
+ # NOTE(vdrok): try to dump complex objects
+ primitive_types = six.string_types + six.integer_types + (
+ bool, type(None), float, list, dict)
+ for key, value in extra.items():
+ if not isinstance(value, primitive_types):
+ extra[key] = _json_dumps_with_fallback(value)
message['extra'] = extra
if record.exc_info: