python 是否可以为FastApi添加uvicorn日志的响应时间?

odopli94  于 2023-06-28  发布在  Python
关注(0)|答案(2)|浏览(346)

我的logger看起来像这样:

log_config = {
    "version": 1,
    "disable_existing_loggers": True,
    "formatters": {
        "default": {
            "()": "uvicorn.logging.DefaultFormatter",
            "fmt": "%(asctime)s::%(levelname)s::%(name)s::%(filename)s::%(funcName)s::%(message)s",
            "datefmt": "%Y-%m-%dT%H:%M:%S%z",
            "use_colors": False,
        },
        "access": {
            "()": "uvicorn.logging.AccessFormatter",
            "datefmt": "%Y-%m-%dT%H:%M:%S%z",
            "fmt": '%(asctime)s::%(levelprefix)s %(client_addr)s - "%(request_line)s" %(msecs)d %(status_code)s',
            "use_colors": False,
        },
    },
    "handlers":
    {
        "default":
        {
            "formatter": "default",
            "class": 'logging.FileHandler',
            "filename": CONFIG[SECTION]["default"]
        },
        "access":
        {
            "formatter": "access",
            "class": 'logging.FileHandler',
            "filename": CONFIG[SECTION]["access"]
        },
    },
    "loggers":
    {
        "uvicorn": {"handlers": ["default"], "level": "INFO", "propagate": False},
        "uvicorn.access": {"handlers": ["access"], "level": "INFO", "propagate": False},
    }
}

启动配置:

uvicorn.run(
    app="app.main:app",
    host="0.0.0.0",
    port=8000,
    reload=True,
    log_config=log_config,
    proxy_headers=True,
    forwarded_allow_ips='*',
    log_level="info"
)

我看不出在访问格式中添加响应时间的方法。我似乎也找不到任何地方的默认参数列表。我该怎么做呢?

bgibtngc

bgibtngc1#

我还必须为FastAPI创建一些自定义日志,最后我使用了一个中间件来获得我想要的结果。
你可以找到一个完整的教程,如何这个here
基本上,不是将日志记录器包含在FastAPI类中,而是将其作为中间件包含。
而不是:

uvicorn.run(
    app="app.main:app",
    host="0.0.0.0",
    port=8000,
    reload=True,
    log_config=log_config,
    proxy_headers=True,
    forwarded_allow_ips='*',
    log_level="info"
)

使用这样的方法:

app.add_middleware(
    RouterLoggingMiddleware,
    logger=logging.getLogger(__name__)
)

希望这能帮上忙。

zujrkrfu

zujrkrfu2#

我将使用FastAPI Middleware,它将在响应之前插入进程,以使用uvicorn.access日志记录器记录。
要访问相应的记录器,您将使用getLogger("name")
返回具有指定名称的记录器,或者,如果name为None,则返回层次结构的根记录器。如果指定,则名称通常是点分隔的分层名称,如'a'、'a.B'或'a.b.c. d'。这些名称的选择完全取决于使用日志记录的开发人员。
一个简单的例子来实现这一点:

access_logger = logging.getLogger("uvicorn.access")

@app.middleware("http")
async def log_to_access_file(request, call_next):
    try:
        return await call_next(request)
    except Exception:
        # Handle potential exceptions if you like
    finally:
        access_logger.info(f"Call finished at {datetime.utcnow().isoformat()}")

您可以通过多种方式来扩充该示例。我建议的一个方法是给予每个调用一个uuid4,以便在日志文件中识别之后的时间:

@app.middleware("http")
async def log_to_access_file(request, call_next):
    try:
        request.state.log_id = str(uuid4())
        return await call_next(request)
    except Exception:
        # Handle potential exceptions if you like
    finally:
        access_logger.info(f"Request with ID: {request.sate.log_id} finished at {datetime.utcnow().isoformat()}")

相关问题