【问题标题】:Python Logging with loguru- log request params on Fastapi app在 Fastapi 应用程序上使用 loguru-log 请求参数进行 Python 日志记录
【发布时间】:2020-08-13 17:52:06
【问题描述】:

我有一个 fastapi 应用程序,我想记录对它发出的每个请求。我正在尝试为此使用 loguru 和 uvicorn,但我不知道如何打印与每个请求关联的标头和请求参数(如果有的话)。

我想要这样的东西:

INFO 2020-08-13 13:36:33.494 uvicorn.protocols.http.h11_impl:send - 127.0.0.1:52660 - "GET 
/url1/url2/ HTTP/1.1" 400 params={"some": value, "some1":value}

有办法吗?感谢您的帮助。

这里有一些链接:

loguruuvicornfastapi

【问题讨论】:

    标签: python logging fastapi uvicorn


    【解决方案1】:

    您可以使用中间件记录每个请求:

    import sys
    
    import uvicorn
    
    from fastapi import FastAPI, Request
    from loguru import logger
    from starlette.routing import Match
    
    logger.remove()
    logger.add(sys.stdout, colorize=True, format="<green>{time:HH:mm:ss}</green> | {level} | <level>{message}</level>")
    app = FastAPI()
    
    
    @app.middleware("http")
    async def log_middle(request: Request, call_next):
        logger.debug(f"{request.method} {request.url}")
        routes = request.app.router.routes
        logger.debug("Params:")
        for route in routes:
            match, scope = route.matches(request)
            if match == Match.FULL:
                for name, value in scope["path_params"].items():
                    logger.debug(f"\t{name}: {value}")
        logger.debug("Headers:")
        for name, value in request.headers.items():
            logger.debug(f"\t{name}: {value}")
    
        response = await call_next(request)
        return response
    
    
    @app.get("/{param1}/{param2}")
    async def path_operation(param1: str, param2: str):
        return {'param1': param1, 'param2': param2}
    
    
    if __name__ == "__main__":
        uvicorn.run("app:app", host="localhost", port=8001)
    

    更新:还可以使用对路由器级别的依赖(感谢下面 cmets 中的@lsabi):

    import sys
    
    import uvicorn
    
    from fastapi import FastAPI, Request, APIRouter, Depends
    from loguru import logger
    from starlette.routing import Match
    
    logger.remove()
    logger.add(sys.stdout, colorize=True, format="<green>{time:HH:mm:ss}</green> | {level} | <level>{message}</level>")
    app = FastAPI()
    
    router = APIRouter()
    
    
    async def logging_dependency(request: Request):
        logger.debug(f"{request.method} {request.url}")
        logger.debug("Params:")
        for name, value in request.path_params.items():
            logger.debug(f"\t{name}: {value}")
        logger.debug("Headers:")
        for name, value in request.headers.items():
            logger.debug(f"\t{name}: {value}")
    
    
    @router.get("/{param1}/{param2}")
    async def path_operation(param1: str, param2: str):
        return {'param1': param1, 'param2': param2}
    
    app.include_router(router, dependencies=[Depends(logging_dependency)])
    
    if __name__ == "__main__":
        uvicorn.run("app:app", host="localhost", port=8001)
    

    curl http://localhost:8001/admin/home

    输出:

    16:06:43 | DEBUG | GET http://localhost:8001/admin/home
    16:06:43 | DEBUG | Params:
    16:06:43 | DEBUG |  param1: admin
    16:06:43 | DEBUG |  param2: home
    16:06:43 | DEBUG | Headers:
    16:06:43 | DEBUG |  host: localhost:8001
    16:06:43 | DEBUG |  user-agent: curl/7.64.0
    16:06:43 | DEBUG |  accept: */*
    

    【讨论】:

    • 也可以使用依赖,这样 URL 路径可以单独或一起记录
    • 谢谢!!这真的可以帮助我解决问题!...我只有一个问题...我将 sys.stdout 替换为“log/access.log”以保存到文件中...但是格式看起来真的很糟糕.. 。任何的想法 ?再次感谢您!
    • @AlexNoname 我知道...这就是我的意思...字符错误prnt.sc/tzqx95
    • 尝试禁用 colorize=False
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-17
    • 2017-04-09
    • 2021-03-22
    • 1970-01-01
    • 2021-02-27
    相关资源
    最近更新 更多