diff options
author | Vladyslav Drok <vdrok@mirantis.com> | 2018-07-20 14:17:43 +0300 |
---|---|---|
committer | Stephen Finucane <stephenfin@redhat.com> | 2019-12-09 15:18:45 +0000 |
commit | b52c8cd247e9b185d176bfbc4c24c5a2cb35e5be (patch) | |
tree | 25f3fed2af1b7a52b25f429bf34bfe4ccece2574 | |
parent | 1f6336a25a90a32c9fa93d0972a1bdfa13c3e61a (diff) | |
download | oslo-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.py | 30 |
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: |