'ExtraAdder throws an exception, thinks EventDict is a string?

Trying figure out how to actually use the processor. What I want to do is add a custom dictionary to log messages as per the example under Debug in the standard Python logging library (https://docs.python.org/3/library/logging.html).

It doesn't work, whether I put an extra in or not.

Python 3.9.2 (default, Feb 28 2021, 17:03:44)
[GCC 10.2.1 20210110] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import structlog
>>> from structlog import stdlib,processors
>>> import logging, sys
>>> logging.basicConfig(stream=sys.stdout)
>>> structlog.configure(logger_factory=stdlib.LoggerFactory(), processors=[stdlib.add_log_level, stdlib.add_logger_name, stdlib.filter_by_level, stdlib.PositionalArgumentsFormatter(), processors.TimeStamper(fmt="iso"), structlog.processors.JSONRenderer(), structlog.stdlib.ExtraAdder(),],)
>>> log = structlog.get_logger(__name__)
>>> type(log)
<class 'structlog._config.BoundLoggerLazyProxy'> # looks like we got a logger

# with an extra:

>>> log.error("Log message example", extra={'a':'b'})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.9/dist-packages/structlog/_log_levels.py", line 124, in meth
    return self._proxy_to_logger(name, event, **kw)
  File "/usr/local/lib/python3.9/dist-packages/structlog/_base.py", line 203, in _proxy_to_logger
    args, kw = self._process_event(method_name, event, event_kw)
  File "/usr/local/lib/python3.9/dist-packages/structlog/_base.py", line 160, in _process_event
    event_dict = proc(self._logger, method_name, event_dict)
  File "/usr/local/lib/python3.9/dist-packages/structlog/stdlib.py", line 708, in __call__
    record: Optional[logging.LogRecord] = event_dict.get("_record")
AttributeError: 'str' object has no attribute 'get'

# without an extra

>>> log.error("Log message example")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.9/dist-packages/structlog/_log_levels.py", line 124, in meth
    return self._proxy_to_logger(name, event, **kw)
  File "/usr/local/lib/python3.9/dist-packages/structlog/_base.py", line 203, in _proxy_to_logger
    args, kw = self._process_event(method_name, event, event_kw)
  File "/usr/local/lib/python3.9/dist-packages/structlog/_base.py", line 160, in _process_event
    event_dict = proc(self._logger, method_name, event_dict)
  File "/usr/local/lib/python3.9/dist-packages/structlog/stdlib.py", line 708, in __call__
    record: Optional[logging.LogRecord] = event_dict.get("_record")
AttributeError: 'str' object has no attribute 'get'

The configuration seems easy enough if I want to allow anything. Actually using this processor in a log message stumps me.

Any help appreciated.



Solution 1:[1]

JSONRenderer renders the event dict and therefore returns a string (or if you use orjson: bytes). You must move ExtraAdder before it, where the event is still a dict.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 hynek