我的 FastAPI 应用程序似乎将很多事情记录两次。
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [21360] using statreload
INFO: Started server process [21362]
INFO:uvicorn.error:Started server process [21362]
INFO: Waiting for application startup.
INFO:uvicorn.error:Waiting for application startup.
INFO: Application startup complete.
INFO:uvicorn.error:Application startup complete.
^CINFO: Shutting down
INFO:uvicorn.error:Shutting down
INFO: Waiting for application shutdown.
INFO:uvicorn.error:Waiting for application shutdown.
INFO: Application shutdown complete.
INFO:uvicorn.error:Application shutdown complete.
INFO: Finished server process [21362]
INFO:uvicorn.error:Finished server process [21362]
INFO: Stopping reloader process [21360]
这包括引发的任何异常,您将获得整个堆栈跟踪两次。我看到一些答案建议删除 Uvicorn 的日志处理程序,但这感觉不对。如果日志记录事件发生在堆栈的 Uvicorn 层而不是 FastAPI 中怎么办?
有没有办法只获取一次日志输出而不覆盖 uvicorn 的日志处理程序?
只需删除
uvicorn
处理程序:
logging.getLogger("uvicorn").handlers.clear()
FastAPI 不做太多日志记录。使用或不使用
fastapi
,您如何运行 gunicorn
? ~~从你提供的信息中,还不足以判断重复项来自哪里。~~但无论如何,我们仍然可以找到解决方案。
uvicorn.error
是 uvicorn
用于记录错误消息的内部记录器。 propagate
是此记录器的默认行为。其中一个重复行必须来自 uvicorn.error
上的处理程序,另一行来自上级/父级记录器。
解决方案是停止两个记录器处理消息。
停止为父记录器设置处理程序(可能是
root
记录器)
或 禁用
uvicorn.error
传播。
logger = logging.getLogger("uvicorn.error")
logger.propagate = False
当您使用最新版本的 uvicorn 时,运行
gunicorn
+ uvicorn
和 UvicornWorker
时这应该不是问题。
如果它对某人有帮助,此页面非常有帮助。此外,我遇到了一个问题,即从该代码调用 setup_logging() 之后,SQLAlchemy 被初始化。一旦我将其更改为立即初始化,我的重复日志就被删除了。
我想删除 uvicorn 完成的默认日志记录并使用我的自定义记录器。
logging.getLogger("uvicorn").removeHandler(logging.getLogger("uvicorn").handlers[0])
确保您没有像上面的答案中提到的那样关闭日志传播。
uvicorn
日志被传播到应用程序中的自定义记录器。我想要
uvicorn
日志记录,但不想重复。从 propagate=False
日志记录设置 uvicorn
为我解决了这个问题。import logging
uvicorn_logger = logging.getLogger("uvicorn")
uvicorn_logger.propagate = False
app_logger = logging.getLogger(__name__)
import logging
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s %(levelname)-5s %(message)s",
handlers=[
logging.handlers.TimedRotatingFileHandler(
"logs/kss_local_executor.log", when="midnight", interval=1
),
logging.StreamHandler(),
],
)
import uvicorn
import uvicorn.config
log_config = dict(uvicorn.config.LOGGING_CONFIG)
log_config["loggers"]["uvicorn"] = {"handlers": []}
log_config["loggers"]["uvicorn.error"] = {"handlers": []}
log_config["loggers"]["uvicorn.access"] = {"handlers": []}
uvicorn.run(app, port=server_context.port, log_config=log_config)