如何为 uvicorn 日志中的每个请求添加时间戳?

How to add timestamp to each request in uvicorn logs?

当我 运行 我的 FastAPI 服务器使用 uvicorn 时:

uvicorn main:app --host 0.0.0.0 --port 8000 --log-level info

我在运行连接服务器后得到的日志:

INFO:     Started server process [405098]
INFO:     Waiting for application startup.
INFO:     Connect to database...
INFO:     Successfully connected to the database!
INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
INFO:     122.179.31.158:54604 - "GET /api/hello_world?num1=5&num2=10 HTTP/1.1" 200 OK

如何获取时间戳以及请求日志记录?喜欢:

INFO:     "2020-07-16:23:34:78" - 122.179.31.158:54604 - "GET /api/hello_world?num1=5&num2=10 HTTP/1.1" 200 OK

能够通过不使用 uvicorn 命令从终端 运行 连接服务器来实现相同的目的。 但是 运行 使用 uvicorn 包的 运行 功能连接服务器。

在网上寻找解决方案时,我最终发现 issue, where Dylan Anthony 使用 uvicorn 包的 运行 功能编写了解决方案。

不过,知道如何使用 uvicorn 命令实现同样的效果仍然是件好事。

您可以创建一个 dict 记录器配置 并在主应用程序中使用 dictConfig 函数对其进行初始化。

#main.py

<b>from logging.config import dictConfig
from config import log_config</b>

from fastapi import FastAPI

<b>dictConfig(log_config.sample_logger)</b>

app = FastAPI()


@app.get("/")
async def root():
    return {"message": "Hello World"}

#config/log_config.py

sample_logger = {
    "version": 1,
    "disable_existing_loggers": False,
    "formatters": {
        "access": {
            "()": "uvicorn.logging.AccessFormatter",
            <b>"fmt": '%(levelprefix)s %(asctime)s :: %(client_addr)s - "%(request_line)s" %(status_code)s',</b>
            "use_colors": True
        },
    },
    "handlers": {
        "access": {
            "formatter": "access",
            "class": "logging.StreamHandler",
            "stream": "ext://sys.stdout",
        },
    },
    "loggers": {
        "uvicorn.access": {
            "handlers": ["access"],
            "level": "INFO",
            "propagate": False
        },
    },
}

您可以使用 Uvicorn 的 LOGGING_CONFIG

import uvicorn
from uvicorn.config import LOGGING_CONFIG
from fastapi import FastAPI

app = FastAPI()

def run():
    LOGGING_CONFIG["formatters"]["default"]["fmt"] = "%(asctime)s [%(name)s] %(levelprefix)s %(message)s"
    uvicorn.run(app)

if __name__ == '__main__':
    run()

哪个 return uvicorn 会记录时间戳

2020-08-20 02:33:53,765 [uvicorn.error] INFO:     Started server process [107131]
2020-08-20 02:33:53,765 [uvicorn.error] INFO:     Waiting for application startup.
2020-08-20 02:33:53,765 [uvicorn.error] INFO:     Application startup complete.
2020-08-20 02:33:53,767 [uvicorn.error] INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)

结合@Yagiz Degirmenci 和@HappyFace 的答案,我得到了这个代码。

LOGGING_CONFIG["formatters"]["default"]["fmt"] = "%(asctime)s [%(name)s] %(levelprefix)s %(message)s"
LOGGING_CONFIG["formatters"]["access"][
    "fmt"] = '%(asctime)s [%(name)s] %(levelprefix)s %(client_addr)s - "%(request_line)s" %(status_code)s'

日志是这样的:

2021-03-31 18:38:22,728 [uvicorn.error] INFO:     Started server process [21824]
2021-03-31 18:38:22,729 [uvicorn.error] INFO:     Waiting for application startup.
2021-03-31 18:38:22,729 [uvicorn.error] INFO:     Application startup complete.
2021-03-31 18:38:22,729 [uvicorn.error] INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
2021-03-31 18:38:26,359 [uvicorn.access] INFO:     127.0.0.1:51932 - "POST /limit HTTP/1.1" 200 OK