如何配置FastAPI日志以适配本地Uvicorn与生产环境?
解决FastAPI日志在Uvicorn及生产环境不输出的问题
你的日志无法输出的核心原因是未正确配置Python标准logging模块,默认情况下logging的根日志级别为WARNING,低于该级别的INFO日志不会被输出;同时Uvicorn的热重载模式会触发多进程执行,模块级别的日志代码可能在非服务进程中执行,导致日志不显示。以下是具体解决方案:
1. 基础日志配置
在代码中添加logging的全局配置,指定日志级别、输出格式和处理器,确保自定义日志能正常输出:
from fastapi import FastAPI import logging import uvicorn from logging.config import dictConfig # 统一配置logging dictConfig({ "version": 1, "disable_existing_loggers": False, "formatters": { "simple": { "format": "%(levelname)s: %(message)s" }, "standard": { "format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s" } }, "handlers": { "console": { "class": "logging.StreamHandler", "formatter": "simple", "level": "INFO" } }, "loggers": { "": { # 根日志器,捕获所有未指定的日志 "handlers": ["console"], "level": "INFO" }, __name__: { # 当前模块的日志器,避免日志重复传播 "handlers": ["console"], "level": "INFO", "propagate": False } } }) app = FastAPI(title="api") LOG = logging.getLogger(__name__) # 使用FastAPI启动事件替代模块级日志,避免热重载进程重复执行 @app.on_event("startup") async def startup_log(): LOG.info("API is starting up") LOG.info(f"ASGI version: {uvicorn.Config.asgi_version}") @app.get("/") async def get_index(): LOG.info("GET /") return {"Hello": "Api"}
2. 关键调整说明
- 日志级别与处理器:通过
dictConfig显式设置日志级别为INFO,并添加控制台处理器,确保LOG.info()能被输出。 - 启动事件替代模块级代码:Uvicorn热重载模式会启动两个进程(重载器+服务进程),模块级的
LOG.info()会被执行两次且可能无输出。使用@app.on_event("startup")可以确保日志仅在服务进程启动时执行。
3. 生产环境适配
如果需要在生产环境使用(如Gunicorn+Uvicorn Worker),只需调整logging配置即可:
- 替换控制台处理器为文件处理器(如
RotatingFileHandler),避免日志占满磁盘; - 调整日志格式为更详细的
standard格式,方便排查问题; - 通过环境变量切换配置,例如开发环境用控制台输出,生产环境用文件输出。
示例生产环境日志配置片段:
"handlers": { "file": { "class": "logging.handlers.RotatingFileHandler", "filename": "app.log", "maxBytes": 1024*1024*5, # 5MB "backupCount": 5, "formatter": "standard", "level": "INFO" } }, "loggers": { __name__: { "handlers": ["file"], "level": "INFO", "propagate": False } }
验证效果
运行uvicorn api:app --reload后,会看到启动日志:
INFO: Will watch for changes in these directories: ['/Users/user/code/backend/api'] INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) INFO: Started reloader process [44258] using StatReload INFO: Started server process [44260] INFO: Waiting for application startup. INFO: API is starting up INFO: ASGI version: 3.0 INFO: Application startup complete.
发送GET请求后,会输出:
INFO: 127.0.0.1:50538 - "GET / HTTP/1.1" 200 OK INFO: GET /
内容的提问来源于stack exchange,提问作者Istvan
相关产品推荐
相关产品推荐

