如何阻止FastAPI将异常发送至标准输出(stdout)
解决FastAPI自定义异常处理器仍输出异常到stdout的问题
问题核心在于两点:你的自定义异常处理器虽然能捕获并处理异常,但Uvicorn内置的uvicorn.error日志器仍会将异常信息输出到标准输出;另外你代码里的logging.error调用也会通过配置的StreamHandler打印内容。下面是具体解决办法:
1. 关闭Uvicorn的异常日志输出
Uvicorn默认会通过uvicorn.error日志器记录异常,哪怕你已经用自定义处理器处理了异常。可以直接移除它的输出处理器,或者调高日志级别来限制输出:
在启动Uvicorn前添加这段代码:
uvicorn_error_logger = logging.getLogger("uvicorn.error") # 移除所有默认输出处理器,彻底阻止它向stdout打日志 for handler in uvicorn_error_logger.handlers[:]: uvicorn_error_logger.removeHandler(handler) # 若需要保留严重错误日志,可将级别设为CRITICAL,仅记录致命问题 # uvicorn_error_logger.setLevel(logging.CRITICAL)
2. (可选)调整自定义日志的输出目标
如果不想让自己的logging.error输出到stdout,把StreamHandler换成文件处理器即可:
# 替换为文件日志,不再输出到控制台 logHandler = logging.FileHandler("app_errors.log")
修改后的完整代码
import logging from ecs_logging import StdlibFormatter from fastapi import FastAPI, Request from fastapi.responses import JSONResponse # 可选:换成FileHandler避免输出到stdout # logHandler = logging.FileHandler("app_errors.log") logHandler = logging.StreamHandler() formatter = StdlibFormatter() logHandler.setFormatter(formatter) logging.basicConfig( level=getattr(logging, 'INFO', logging.INFO), handlers=[logHandler] ) # 禁用Uvicorn错误日志的stdout输出 uvicorn_error_logger = logging.getLogger("uvicorn.error") for handler in uvicorn_error_logger.handlers[:]: uvicorn_error_logger.removeHandler(handler) app = FastAPI() @app.exception_handler(Exception) async def custom_exception_handler(request: Request, exc: Exception): logging.error(f"An error occurred: {exc}") return JSONResponse( status_code=500, content={"message": "An internal server error occurred."}, ) @app.get("/") async def read_root(): raise Exception("This is a test exception") if __name__ == "__main__": import uvicorn uvicorn.run(app, host="127.0.0.1", port=8001)
额外提醒
- 如果只是不想看到冗长的堆栈信息而非完全关闭日志,可以调整日志格式,或者在记录日志时仅输出异常消息。
- 不要把Uvicorn的日志级别调得过高,否则可能错过服务器运行的重要错误信息,建议根据生产/测试环境灵活调整。
内容的提问来源于stack exchange,提问作者Javi Torre
相关产品推荐
相关产品推荐

