为 FastAPI 配置日志的三种方法

Python七号

共 4089字,需浏览 9分钟

 ·

2022-04-27 23:07

你好,我是 somenzz,可以叫我征哥,最近在用 FastAPI 的时候,发现 FastAPI 的官方文档没有配置日志的相关说明,今天就分享一下 FastAPI 配置日志的三种方法。

第一种,就像写脚本那样记录日志

这一种方法最简单直接,平时写脚本的时候怎么记录日志,这里就怎么记录日志,通常就是先配置日志格式,然后在需要的地方 logger.info 一下:

配置日志:

import logging

logger = logging.getLogger()
logger.setLevel(logging.INFO)
ch = logging.StreamHandler()
fh = logging.FileHandler(filename='./server.log')
formatter = logging.Formatter(
    "%(asctime)s - %(module)s - %(funcName)s - line:%(lineno)d - %(levelname)s - %(message)s"
)

ch.setFormatter(formatter)
fh.setFormatter(formatter)
logger.addHandler(ch) #将日志输出至屏幕
logger.addHandler(fh) #将日志输出至文件

如果怕文件太大,可以使用循环日志:

fh = logging.handlers.RotatingFileHandler("api.log",mode="a",maxBytes = 100*1024, backupCount = 3)

然后,在需要记录日志的地方添加 logger.info / logger.warning / logger.debug / logger.error

from fastapi import FastAPI

# setup loggers
import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
ch = logging.StreamHandler()
fh = logging.FileHandler(filename='./server.log'))
ch.setFormatter(LogFormatter())
fh.setFormatter(LogFormatter())
logger.addHandler(ch) #将日志输出至屏幕
logger.addHandler(fh) #将日志输出至文件



app = FastAPI()

@app.get("/")
async def root():
    logger.info("logging from the root logger")
    return {"status""alive"}

你可能会说,我接口特别多,难道一行一行加?

那也不用,你可以在中间件里面拦截所有请求,然后日志记录每一个请求,完整代码如下所示:

文件名 main.py,重点在 log_requests 函数:

import logging
from fastapi import FastAPI
import time
import random
import string

logger = logging.getLogger()
logger.setLevel(logging.INFO)
ch = logging.StreamHandler()
fh = logging.FileHandler(filename='./server.log')
formatter = logging.Formatter(
    "%(asctime)s - %(module)s - %(funcName)s - line:%(lineno)d - %(levelname)s - %(message)s"
)

ch.setFormatter(formatter)
fh.setFormatter(formatter)
logger.addHandler(ch) #将日志输出至屏幕
logger.addHandler(fh) #将日志输出至文件


logger = logging.getLogger(__name__)

app = FastAPI()

@app.middleware("http")
async def log_requests(request, call_next):
    idem = ''.join(random.choices(string.ascii_uppercase + string.digits, k=6))
    logger.info(f"rid={idem} start request path={request.url.path}")
    start_time = time.time()
    
    response = await call_next(request)
    
    process_time = (time.time() - start_time) * 1000
    formatted_process_time = '{0:.2f}'.format(process_time)
    logger.info(f"rid={idem} completed_in={formatted_process_time}ms status_code={response.status_code}")
    
    return response


@app.get("/")
async def root():
    return {"status""alive"}

命令行 uvicorn main:app --host 0.0.0.0 --port 8081 然后访问一下 http://localhost:8081,就会看到日志输出,同时会保存在 server.log 文件中:

第二种,记录 uvicorn 的日志

fastapi 其实是 uvicorn 驱动的,uvicorn 本身就会在终端输出信息:

❯ uvicorn main:app --host 0.0.0.0 --port 8081
INFO:     Started server process [88064]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:8081 (Press CTRL+C to quit)

将这些信息记录到文件里就可以了,可以在 fastapi 启动的时候配置:

@app.on_event("startup")
async def startup_event():
    logger = logging.getLogger("uvicorn.access")
    handler = logging.handlers.RotatingFileHandler("api.log",mode="a",maxBytes = 100*1024, backupCount = 3)
    handler.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(message)s"))
    logger.addHandler(handler)

这样,uvicorn 的输出,就会记录在 api.log 中。

第三种,配置 uvicorn 的日志

如果你是这种方法运行 FastApi:

app = FastAPI()
uvicorn.run(app, host="0.0.0.0", port=8000)

那么可以在代码里配置 uvicorn 的日志,然后在 run 函数里传入日志配置信息,就可以了:

log_config = uvicorn.config.LOGGING_CONFIG
log_config["formatters"]["access"]["fmt"] = "%(asctime)s - %(levelname)s - %(message)s"
log_config["formatters"]["default"]["fmt"] = "%(asctime)s - %(levelname)s - %(message)s"
uvicorn.run(app, log_config=log_config)

当然,在命令行里面也可以通过 uvicorn --log-config=log.ymal 传入配置文件:

version: 1
formatters:
simple:
format: '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
handlers:
console:
class: logging.StreamHandler
level: DEBUG
formatter: simple
stream: ext://sys.stdout
loggers:
simpleExample:
level: DEBUG
handlers: [console]
propagate: no
root:
level: DEBUG
handlers: [console]

日志文件支持 .ini, .json, .yaml 格式。

最后的话

本文分享了 FastAPI 配置日志的三种方法,后两种其实是 uvicorn 配置并记录日志的方法,如果觉得有帮助,请在看、转发、评论,感谢阅读。



浏览 97
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报