Uvicorn/FastAPI 重复记录

问题描述 投票:0回答:6

我的 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 的日志处理程序?

logging fastapi uvicorn
6个回答
12
投票

只需删除

uvicorn
处理程序:

logging.getLogger("uvicorn").handlers.clear()

7
投票

FastAPI 不做太多日志记录。使用或不使用

fastapi
,您如何运行
gunicorn
? ~~从你提供的信息中,还不足以判断重复项来自哪里。~~但无论如何,我们仍然可以找到解决方案。

uvicorn.error
uvicorn
用于记录错误消息的内部记录器。
propagate
是此记录器的默认行为。其中一个重复行必须来自
uvicorn.error
上的处理程序,另一行来自上级/父级记录器。

解决方案是停止两个记录器处理消息。

  1. 停止为父记录器设置处理程序(可能是

    root
    记录器)

  2. 禁用

    uvicorn.error
    传播。

    logger = logging.getLogger("uvicorn.error")
    logger.propagate = False
    

当您使用最新版本的 uvicorn 时,运行

gunicorn
+
uvicorn
UvicornWorker
时这应该不是问题。


1
投票

如果它对某人有帮助,此页面非常有帮助。此外,我遇到了一个问题,即从该代码调用 setup_logging() 之后,SQLAlchemy 被初始化。一旦我将其更改为立即初始化,我的重复日志就被删除了。


1
投票

我想删除 uvicorn 完成的默认日志记录并使用我的自定义记录器。

logging.getLogger("uvicorn").removeHandler(logging.getLogger("uvicorn").handlers[0])

确保您没有像上面的答案中提到的那样关闭日志传播。


0
投票
uvicorn

日志被传播到应用程序中的自定义记录器。我想要

uvicorn
日志记录,但不想重复。从
propagate=False
日志记录设置
uvicorn
为我解决了这个问题。
import logging
uvicorn_logger = logging.getLogger("uvicorn")
uvicorn_logger.propagate = False

app_logger = logging.getLogger(__name__)



0
投票

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)

	
© www.soinside.com 2019 - 2024. All rights reserved.