fastapi结合loguru进行日志记录
问题:
使用FastAPI结合loguru进行日志记录的时候会出现一个问题,在某些日志记录的时候会重复的记录
原因:
这个问题是因为loguru和FastAPI都使用了logging这个内置的模块进行日志记录
解决方案:
如果在使用自定义的日志记录模块的时候,首先要删除已经存在的日志记录器(handlers),但是删除之后的话,又会出现一个新的问题,终端不会再打印任何日志,这样的话就不易于调试,所以要再次去设置终端打印日志的参数
# 单例模式
class SingletonMeta(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super().__call__(*args, **kwargs)
return cls._instances[cls]
class Mylog(metaclass=SingletonMeta):
def __init__(self):
self.configure_logger()
def configure_logger(self):
# 设置日志文件路径和名称格式
logfile_path = os.path.join(Setting.logfile_path, "{time:YYYY-MM-DD}.log")
# 移除所有已存在的handlers
logger.remove()
# 添加日志处理器将error级别日志分开写入
logger.add(os.path.join(Setting.logfile_path, 'error.log'), filter=lambda record: record["level"].name == "ERROR")
# info日志和轮转设置
logger.add(sink=logfile_path, level=Setting.log_level, rotation='1 day')
# 终端打印
logger.add(sys.stderr, level="INFO")
log_instance = Mylog()
log = logger # loguru的logger实例已经被配置好,可以直接使用
if __name__ == '__main__':
log.info('2024年2月5日11:28:21')
如下是ChatGPT回答的可能导致这个问题的原因具可供参考
FastAPI 和 Uvicorn 都有自己的日志记录系统,这可能与 Loguru 发生重复或冲突。
FastAPI 日志记录
FastAPI 本身依赖于 Starlette,它使用标准的 Python logging
模块进行日志记录。默认情况下,FastAPI 配置了一些基本的日志处理,如请求和错误日志。如果你没有自定义 FastAPI 应用的日志配置,它将使用 Python 标准库 logging
的默认设置。
Uvicorn 日志记录
Uvicorn 作为 ASGI 服务器,提供了详细的日志记录功能,包括访问日志和错误日志。Uvicorn 使用标准的 Python logging
模块来管理日志,并提供了配置选项来自定义日志级别、格式和处理器。当你通过 Uvicorn 运行你的 FastAPI 应用时,Uvicorn 的日志设置将影响到应用的日志输出。
Loguru 与 FastAPI/Uvicorn 日志的冲突
Loguru 是一个第三方日志库,提供了一些比标准 logging
模块更简洁和强大的功能。然而,Loguru 不直接与 Python 的 logging
模块兼容。如果你在使用 Loguru 的同时,FastAPI 或 Uvicorn 的日志处理器也在运行,你可能会遇到日志消息重复的问题。这是因为 Loguru 的日志处理器和 FastAPI/Uvicorn 使用的基于 logging
模块的处理器可能都会捕捉并处理同样的日志消息。