一、概述
FastAPI 是一个现代的、快速(高性能)的Web框架,用于构建API,基于Python类型提示。
日志记录是任何应用程序中不可或缺的一部分,它允许开发者追踪事件的发生、识别错误并了解系统的运行状态。
在 FastAPI 中,日志配置可以通过多种方式进行,包括直接使用 Python 的标准 logging 模块、集成第三方库如 loguru,以及通过 uvicorn 的日志配置来实现。
二、实现方法
2.1 使用 Python 标准 logging 模块
FastAPI 默认集成了 Python 的标准logging
模块,这使得我们可以很容易地配置和管理应用程序的日志输出。
要将日志信息输出到文件中,可以使用 RotatingFileHandler
来创建一个日志处理器实例,并将其添加到 logger 中。
例如:这段代码将所有 INFO 级别及以上的日志消息记录到 app.log
文件中,当文件大小超过 1MB
时会自动创建新的备份文件。
import logging
from logging.handlers import RotatingFileHandler
from fastapi import FastAPI# 初始化 FastAPI 应用
app = FastAPI()# 创建 RotatingFileHandler 实例
file_handler = RotatingFileHandler(filename="app.log", maxBytes=1000000, backupCount=10)# 设置日志格式
formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
file_handler.setFormatter(formatter)# 获取根 logger 并添加 handler 和级别
logger = logging.getLogger()
logger.addHandler(file_handler)
logger.setLevel(logging.INFO)@app.get("/")
async def read_root():logger.info("访问了根路径")return {"Hello": "World"}if __name__ == "__main__":import uvicornuvicorn.run(app, host="127.0.0.1", port=8000)
2.1 使用 Loguru 库
尽管 Python 的 logging 模块功能强大,但它的配置可能相对复杂。
Loguru 提供了一个更简洁的接口,简化了日志记录的过程。
通过 pip 安装 ·loguru· 后,可以在 FastAPI 项目中轻松集成它,以获得更加用户友好的日志记录体验。
例如:这里展示了如何配置 loguru 来记录日志到文件,并且设置了每日轮换和最多保留一天的日志文件。
from loguru import logger
from fastapi import FastAPIapp = FastAPI()log_path = '/u01'
if not os.path.exists(log_path):os.mkdir(log_path)
log_file = '{0}/fa_25_{1}_log.log'.format(log_path, datetime.now().strftime('%Y-%m-%d'))
logger.add(log_file, rotation="12:00", retention="1 days", enqueue=True)@app.get("/")
async def root():logger.info('Hello world')logger.info('日志测试。')return "Hello world"
2.3 配置 Uvicorn 日志
Uvicorn 是一个用于运行 ASGI 应用程序的服务器,通常用来启动 FastAPI 应用。
Uvicorn 自身也支持日志配置,可以通过传递 log_config 参数给 uvicorn.run() 方法来自定义日志格式和行为。
例如:这段 JSON 配置定义了日志的格式化方式,其中包括时间戳、线程名称等信息,并指定了日志应该被发送到的标准输出流或文件。
在这个例子中,我们指定了一个外部的日志配置文件 path/to/logconfig.json,其中包含了详细的日志格式化规则和处理器配置6。这使得我们可以灵活地调整日志输出的行为,而无需修改应用程序本身的代码。
{"version": 1,"disable_existing_loggers": false,"formatters": {"default": {"()": "uvicorn.logging.DefaultFormatter","fmt": "%(asctime)s %(threadName)s %(levelprefix)s %(message)s","use_colors": null},"access": {"()": "uvicorn.logging.AccessFormatter","fmt": "%(asctime)s %(threadName)s %(levelprefix)s %(client_addr)s - '%(request_line)s' %(status_code)s"}},"handlers": {"default": {"formatter": "default","class": "logging.StreamHandler","stream": "ext://sys.stderr"},"access": {"formatter": "access","class": "logging.StreamHandler","stream": "ext://sys.stdout"}},"loggers": {"fastapi": {"handlers": ["default"],"level": "INFO"},"uvicorn": {"handlers": ["default"],"level": "INFO"},"uvicorn.error": {"level": "INFO"},"uvicorn.access": {"handlers": ["access"],"level": "INFO","propagate": false}}
}
然后,在启动应用时可以这样调用:
import uvicorn
from fastapi import FastAPIapp = FastAPI()@app.get("/")
async def root():return {"message": "Hello World"}if __name__ == "__main__":uvicorn.run(app, host="127.0.0.1", port=8000, log_config='path/to/logconfig.json')
三、FastAPI的日志级别
FastAPI 应用的日志级别可以通过多种方式来配置,这取决于你是想调整整个应用的日志输出,还是仅针对特定部分。
日志级别是用于指示事件重要性的标签,它们帮助开发者决定哪些信息应该被记录下来以供后续分析或调试。
通常情况下,Python 的 logging 模块提供了以下几种日志级别(按照严重性递增):
DEBUG (10)
:详细的调试信息,通常只在诊断问题时有用。INFO (20)
:确认程序按预期工作,表示应用程序正常运行的信息。WARNING (30)
:表示某些非致命问题的警告信息,但这些问题可能需要关注。ERROR (40)
:由于更严重的问题导致功能未能执行的日志信息。CRITICAL (50)
:非常严重的错误,表明程序本身可能无法继续运行。
在 FastAPI 中,你可以通过 Python 标准库中的 logging 模块来设置日志级别,或者使用 Uvicorn 提供的命令行选项和配置文件来控制日志输出的行为。
下面将详细介绍如何为 FastAPI 设置不同的日志级别。
- 使用 Python 标准 logging 模块设置日志级别
当你使用 Python 的标准 logging 模块时,可以创建一个 logger 对象,并通过 setLevel() 方法来指定最低的日志级别。
任何低于该级别的消息都将被忽略。
例如,如果你设置了 INFO 级别,则只有 INFO、WARNING、ERROR 和 CRITICAL 级别的消息会被记录下来。
在这个例子中,尽管我们调用了 logger.debug(),但由于日志级别设置为 INFO,所以这条消息不会出现在输出中。
import logging
from fastapi import FastAPIapp = FastAPI()# 创建并配置 logger
logger = logging.getLogger()
logger.setLevel(logging.INFO) # 设置全局日志级别为 INFO@app.get("/")
async def read_root():logger.debug("这是一个调试信息") # 不会打印,因为低于 INFO 级别logger.info("访问了根路径")return {"Hello": "World"}if __name__ == "__main__":import uvicornuvicorn.run(app, host="127.0.0.1", port=8000)
- 使用 Uvicorn 设置日志级别
Uvicorn 是 FastAPI 的 ASGI 服务器实现之一,它允许你通过命令行参数或配置文件来设置日志级别。你可以直接在启动命令中添加 --log-level 参数来改变日志级别,如 uvicorn main:app --log-level debug。此外,还可以通过 JSON 或 YAML 格式的日志配置文件来进一步自定义日志格式和其他行为1。
例如,创建一个名为 uvicorn_config.json 的日志配置文件:
{"version": 1,"disable_existing_loggers": false,"formatters": {"default": {"()": "uvicorn.logging.DefaultFormatter","fmt": "%(asctime)s %(levelprefix)s %(message)s","use_colors": null},"access": {"()": "uvicorn.logging.AccessFormatter","fmt": "%(asctime)s %(levelprefix)s %(client_addr)s - '%(request_line)s' %(status_code)s"}},"handlers": {"default": {"formatter": "default","class": "logging.StreamHandler","stream": "ext://sys.stderr"},"access": {"formatter": "access","class": "logging.StreamHandler","stream": "ext://sys.stdout"}},"loggers": {"fastapi": {"handlers": ["default"],"level": "DEBUG" # 设置 FastAPI 日志级别为 DEBUG},"uvicorn": {"handlers": ["default"],"level": "INFO"},"uvicorn.error": {"level": "INFO"},"uvicorn.access": {"handlers": ["access"],"level": "INFO","propagate": false}}
}
然后,在启动应用时可以这样调用:
if __name__ == "__main__":import uvicornuvicorn.run(app, host="127.0.0.1", port=8000, log_config='path/to/uvicorn_config.json')
在这个配置文件中,我们将 FastAPI 的日志级别设置为了 DEBUG,这意味着所有级别的日志都会被记录下来。
请注意,这里提到的 fastapi logger 并不是默认存在的;
你需要确保你的应用程序中有相应的 logger 被正确命名并使用。
四、相关链接
【FastAPI】日志
【FastAPI】中间件
【FastAPI】简介
【FastAPI】BaseModel类