hynek / structlog

Simple, powerful, and fast logging for Python.
https://www.structlog.org/
Other
3.48k stars 220 forks source link

Unexpected log level set by structlog.stdlib.recreate_defaults() #621

Closed jwuerzinger closed 4 months ago

jwuerzinger commented 4 months ago

I am using uproot 5.3.7 with structlog 24.1.0 to open and inspect root files. I was getting some unexpected output when running:

import structlog
log = structlog.get_logger()
structlog.stdlib.recreate_defaults()

import uproot
f = uproot.open("myrootfile.root")

Which produced this output:

open file: myrootfile.root

The output can be suppressed by using structlog.stdlib.recreate_defaults(log_level=logging.INFO) or not calling recreate_defaults().

However, while using logging, this output is not produced with the default log level, but only if the log level is explicitly set to DEBUG, i.e.:

import logging
logging.basicConfig(format="%(levelname)s - %(name)s - %(message)s")
logging.getLogger().setLevel(logging.DEBUG)

From what I gather from https://www.structlog.org/en/stable/api.html#structlog.stdlib.recreate_defaults, should the intended behaviour not be analogue to logging?

Thanks a lot to @alexander-held for figuring this out!

alexander-held commented 4 months ago

After having had another look at structlog.stdlib.recreate_defaults I believe I misunderstood what the function intends to do. I thought it would set log levels to the defaults that logging would use, e.g.

import logging
print(logging.getLogger("asyncio"))

logs at WARNING level: <Logger asyncio (WARNING)>. The recreate_defaults() function without argument turns that into NOTSET:

import logging
import structlog

print(logging.getLogger("asyncio"))
structlog.stdlib.recreate_defaults()
print(logging.getLogger("asyncio"))

->

<Logger asyncio (WARNING)>
<Logger asyncio (NOTSET)>

I think this is consistent with what the documentation says. Apologies if that is only adding confusion to the discussion, I don't know a lot about structlog and presumably just misunderstood the use of this function.

hynek commented 4 months ago

As y'all figured out, it does only the most basic configuration possible. I really do not want to interact with stdlib logging more than I have to here – it would make everything less predictable.