前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >为 FastAPI 配置日志的三种方法

为 FastAPI 配置日志的三种方法

作者头像
somenzz
发布2022-05-24 14:38:17
6.9K0
发布2022-05-24 14:38:17
举报
文章被收录于专栏:Python七号Python七号

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

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

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

配置日志:

代码语言:javascript
复制
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) #将日志输出至文件

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

代码语言:javascript
复制
fh = logging.handlers.RotatingFileHandler("api.log",mode="a",maxBytes = 100*1024, backupCount = 3)

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

代码语言:javascript
复制
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 函数:

代码语言:javascript
复制
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 本身就会在终端输出信息:

代码语言:javascript
复制
❯ 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 启动的时候配置:

代码语言:javascript
复制
@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:

代码语言:javascript
复制
app = FastAPI()
uvicorn.run(app, host="0.0.0.0", port=8000)

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

代码语言:javascript
复制
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 传入配置文件:

代码语言:javascript
复制
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 配置并记录日志的方法。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-04-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python七号 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 第一种,就像写脚本那样记录日志
  • 第二种,记录 uvicorn 的日志
  • 第三种,配置 uvicorn 的日志
  • 最后的话
相关产品与服务
消息队列 TDMQ
消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档