代码
class InterceptHandler(logging.Handler):
def emit(self, record):
# ✓ corresponding Loguru level if it exists
try:
level = logger.level(record.levelname).name
except ValueError:
level = record.levelno
# Find caller from where originated the logged message
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())
logging.basicConfig(handlers=[InterceptHandler()], level=0)
效果
scrapy日志如何与其他模块日志输出到一起; log是loguru的彩色风格
2023-04-07 16:18:51.905 | DEBUG | rediscluster.connection:reset:187 - Resetting ConnectionPool
2023-04-07 16:18:51.905 | INFO | bf_sp_scrapy.utils.redis_db:<module>:12 - cluster_client: RedisCluster<10.0.21.190:7000>
2023-04-07 16:18:52.464 | INFO | scrapy.utils.log:log_scrapy_info:147 - Scrapy 2.6.2 started (bot: bf_sp_scrapy)
2023-04-07 16:18:52.477 | INFO | scrapy.utils.log:log_scrapy_info:154 - Versions: lxml 4.9.2.0, l
同时,我认为可以回答这个问题:coding.imooc.com/learn/quest…
代码解析from gpt4:
这段代码定义了一个名为InterceptHandler
的类,这个类是Python标准库logging
模块中的Handler
类的子类。它的目的是拦截由Scrapy产生的标准日志,并将它们转发到Loguru日志库进行处理。
我会一步步地解释这段代码:
-
类定义:
class InterceptHandler(logging.Handler):
这里定义了一个新的日志处理器类,继承自
logging.Handler
。 -
emit方法: 这是
Handler
子类必须实现的一个方法,它描述了当一个日志消息被处理时应该执行的动作。-
尝试获取Loguru的日志级别:
try: level = logger.level(record.levelname).name except ValueError: level = record.levelno
以上代码尝试根据传入的日志记录的级别名(如'INFO', 'WARNING')获取对应的Loguru日志级别。如果该级别在Loguru中不存在,它会回退到使用数字形式的日志级别。
-
找到产生日志消息的调用者:
frame, depth = logging.currentframe(), 2 while frame.f_code.co_filename == logging.__file__: frame = frame.f_back depth += 1
这里的目标是确定产生日志消息的原始位置(文件名和行号)。
logging.currentframe()
提供了当前调用栈的帧。然后,代码遍历调用栈,直到找到不是logging
模块本身的帧,从而找到原始的调用者位置。 -
使用Loguru记录日志:
logger.opt(depth=depth, exception=record.exc_info).log(level, record.getMessage())
这里使用Loguru的
logger
实例来记录日志。logger.opt()
允许为这个特定的日志调用设置一些选项。设置的depth
确保日志输出显示的源代码位置是原始的调用者,而不是InterceptHandler
类。同时,如果日志记录包含异常信息,它也会被包含进去。
-
总之,这个InterceptHandler
类的目的是为了在Scrapy中使用Loguru作为日志系统,并确保Scrapy产生的所有日志都被正确地转发到Loguru进行处理和输出。