假设我正在设置一个脚本或库,它有一些使用 Python 标准库logging模块的依赖项,但我想用它loguru来捕获所有日志。我的第一次天真的尝试完全失败了,但我不知道如何继续。
为了测试我有两个文件
main.py:
from loguru import logger
from base_log import test_func
if __name__ == "__main__":
logger.debug("In main")
test_func()
Run Code Online (Sandbox Code Playgroud)
和base_log.py:
import logging
logger = logging.getLogger(__name__)
def test_func():
logger.warning("In test_func")
Run Code Online (Sandbox Code Playgroud)
如果我运行main.py(ie python main.py) 那么我会得到以下输出:
2020-12-16 10:57:48.269 | DEBUG | __main__:<module>:6 - In main
In test_func
Run Code Online (Sandbox Code Playgroud)
当我期望时:
2020-12-16 11:01:34.408 | DEBUG | __main__:<module>:6 - In main
2020-12-16 11:01:34.408 | WARNING | base_log:test_func:9 - In test_func
Run Code Online (Sandbox Code Playgroud)
您可以使用自定义处理程序来拦截发送至 Loguru 接收器的标准日志消息,如此处所述。
main.py然后看起来像这样:
import logging
from loguru import logger
from base_log import test_func
class InterceptHandler(logging.Handler):
def emit(self, record):
try:
level = logger.level(record.levelname).name
except ValueError:
level = record.levelno
frame, depth = logging.currentframe(), 2
while frame.f_code.co_filename == logging.__file__:
frame = frame.f_back
depth += 1
logger.opt(depth=depth, exception=record.exc_info).log(
level, record.getMessage()
)
if __name__ == "__main__":
logging.basicConfig(handlers=[InterceptHandler()], level=0)
logger.debug("In main")
test_func()
Run Code Online (Sandbox Code Playgroud)
输出:
2020-12-16 22:15:55.337 | DEBUG | __main__:<module>:26 - In main
2020-12-16 22:15:55.337 | WARNING | base_log:test_func:7 - In test_func
Run Code Online (Sandbox Code Playgroud)
这应该适用于所有行为良好的库,这些库不会将除 NullHandler 之外的任何处理程序添加到库的记录器中。其余的可能需要额外的工作。