Logging adapter in readme doesn't resolve log level names
See original GitHub issuesummary
The readme provides a InterceptHandler
class to hook existing logging
calls and forward them into loguru. The hook itself works, however does not resolve log levels.
The result is we get unexpected loguru output, where instead of getting the localized name 'INFO'
we get 'Level 20'
.
>>> logger.debug("loguru debug")
2019-10-13 21:21:33.728 | DEBUG | __main__:<module>:1 - loguru debug
>>> logging.debug("logging debug")
2019-10-13 21:21:33.729 | Level 10 | logging:handle:905 - logging debug
>>>
This incorrect output also breaks loguru’s color formatting
It appears that Loguru does not resolve integer log levels it can understand for message formatting.
Minimum reproduceable example
import logging
from loguru import logger
# class directly applied from the README
class InterceptHandler(logging.Handler):
def emit(self, record):
# Intercepts standard logging messages for the purpose of sending them to loguru
logger_opt = logger.opt(depth=1, exception=record.exc_info)
logger_opt.log(record.levelno, record.getMessage())
logging.basicConfig(handlers=[InterceptHandler()], level=0)
logger.debug("loguru debug")
logging.debug("logging debug")
logger.info("loguru info")
logging.info("logging info")
logger.warning("loguru warning")
logging.warning("logging warning")
logger.error("loguru error")
logging.error("logging error")
logger.critical("loguru critical")
logging.critical("logging critical")
Versions
>>> loguru.__version__
'0.3.2'
- OS: Windows 10 x64, Ubuntu Xenial
- CLI environment: Powershell, bash
Potential fix
After debugging and analyzing how loguru handles its own logging calls, it appears that its expecting string level names. e.g. "DEBUG"
and "CRITICAL"
.
With this expectation in mind, this bug can be resolved by having the InterceptHandler
resolve the logging
log level name prior to delegating the event to loguru.
It would be a one-line patch
class InterceptHandler(logging.Handler):
def emit(self, record):
# Intercepts standard logging messages for the purpose of sending them to loguru
logger_opt = logger.opt(depth=1, exception=record.exc_info)
# resolve the log level to a name, then emit the message to Loguru
logger_opt.log(logging.getLevelName(record.levelno), record.getMessage())
# logger_opt.log(record.levelno, record.getMessage())
I will open a PR soon to this effect.
Issue Analytics
- State:
- Created 4 years ago
- Comments:7 (5 by maintainers)
Top GitHub Comments
So, I think I will replace the current snippet:
With this one:
This should fix both #154 (level problem) and #78 (depth problem) in such situation:
Obviously, I’m not entirely satisfied with this solution. It’s not much pretty. Unfortunately, I don’t think there is any other possible workaround, and I do not want to make
InterceptHandler()
/PropagateHandler()
part of the Loguru API.There is also the possibility to use the
logger.patch()
to update the Loguru’s record dict, but this would not work well with.enable()
and.disable()
(because it’s resolved before patching) and hence would lead to other problems.I will probably update the Readme and close this issue in the next few days, if by then I haven’t had a revelation. 🙂
Readme updated. 😉