Допустим, я настраиваю скрипт или библиотеку с несколькими зависимостями, которые используют модуль стандартной библиотеки Python logging
, но я хочу использовать loguru
для сбора всех журналов. Моя первая наивная попытка потерпела полный провал, но я не знаю, что делать дальше.
Для проверки у меня есть два файла
main.py
:
from loguru import logger
from base_log import test_func
if __name__ == "__main__":
logger.debug("In main")
test_func()
и base_log.py
:
import logging
logger = logging.getLogger(__name__)
def test_func():
logger.warning("In test_func")
Если я запускаю main.py
(т. е. python main.py
), я получаю следующий вывод:
2020-12-16 10:57:48.269 | DEBUG | __main__:<module>:6 - In main
In test_func
Когда я ожидаю:
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
Вы можете использовать настраиваемый обработчик для перехвата стандартных сообщений журнала для ваших приемников 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()
Выход:
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
Это должно работать для всех библиотек с хорошим поведением, которые не добавляют никаких обработчиков, кроме NullHandler, в регистраторы библиотек. Остальным может потребоваться дополнительная работа.