-
-
Notifications
You must be signed in to change notification settings - Fork 250
Description
Just started using structlog recently; I've have found it's a great library to work with. Appreciate your all your hard work!
I'm using it both for internal logging library and for formatting the root python logging library's messages. Both are printing JSON to stdout. I get a traceback when I try to use structlog.stdlib.filter_by_level
. Actually, I run into several similar tracebacks for several processors from the structlog.stdlib
library. With these processors commented out, I am able to successfully encode JSON logs to the console from 3rd party libraries using the built in Python logger.
However, I was hoping to utilize the additional processors listed in the documentation. I checked for similar issues in GH and the documentation on integrating with the stdlib python logger, but didn't find any solutions. I'm hoping to understand if there was any insight here on something I'm doing wrong - configuring the python standard library to use structlog or if I'm using the processors incorrectly? Otherwise, I think this might be a bug with structlog.
After some review of the stack trace, I think the issue may comes from isEnabeldFor
not being available on whatever object structlog.stdlib.ProcessorFormatter
provides as it seems to only exist on structlog.stdlib.BoundLogger
.
dev:api logs api: File "/root/.pyenv/versions/3.8.12/lib/python3.8/logging/__init__.py", line 1085, in emit
dev:api logs api: msg = self.format(record)
dev:api logs api: File "/root/.pyenv/versions/3.8.12/lib/python3.8/logging/__init__.py", line 929, in format
dev:api logs api: return fmt.format(record)
dev:api logs api: File "/root/.pyenv/versions/3.8/lib/python3.8/site-packages/structlog/stdlib.py", line 1046, in format
dev:api logs api: ed = p(logger, meth_name, ed)
dev:api logs api: File "/root/.pyenv/versions/3.8/lib/python3.8/site-packages/structlog/stdlib.py", line 744, in filter_by_level
dev:api logs api: if logger.isEnabledFor(_NAME_TO_LEVEL[method_name]):
dev:api logs api: AttributeError: 'NoneType' object has no attribute 'isEnabledFor'
I'm attempting to configure it like this for each logger instance respectively.
# internal application logging
internal_processors = [
structlog.contextvars.merge_contextvars,
structlog.processors.add_log_level,
structlog.processors.UnicodeDecoder(),
structlog.processors.StackInfoRenderer(),
structlog.processors.dict_tracebacks,
structlog.processors.TimeStamper(fmt="iso", utc=True),
structlog.processors.EventRenamer(to="message"),
structlog.processors.CallsiteParameterAdder(<omitted>),
structlog.processors.JSONRenderer(serializer=dumps)
]
structlog.configure(
cache_logger_on_first_use=True,
wrapper_class=structlog.make_filtering_bound_logger(20),
processors=internal_processors,
logger_factory=structlog.BytesLoggerFactory(),
)
# stdlib python logging
formatter = structlog.stdlib.ProcessorFormatter(
processors=[
structlog.stdlib.PositionalArgumentsFormatter(),
# structlog.stdlib.filter_by_level,
structlog.stdlib.add_log_level,
structlog.stdlib.add_logger_name,
# structlog.stdlib.ExtraAdder,
# structlog.stdlib.StackInfoRenderer,
structlog.processors.TimeStamper(fmt="iso", utc=True),
structlog.processors.EventRenamer(to="message"),
structlog.stdlib.ProcessorFormatter.remove_processors_meta,
structlog.processors.JSONRenderer(),
],
)
handler = logging.StreamHandler()
handler.setFormatter(formatter)
root_logger = logging.getLogger()
root_logger.addHandler(handler)
root_logger.setLevel(logging.INFO)```