fastapi 的uvicorn配置日志

news/2024/11/14 14:49:49/文章来源:https://www.cnblogs.com/shenh/p/18335089

  目前从flask框架转fastapi,之前flask框架日志很好用。这次学习了fastapi的日志使用,第一种是自定义日志,这个不讲了,自己封装就好,第二种是使用uvicorn自带日志, Uvicorn 是 fastapi 框架的默认ASGI服务器,它提供了强大的异步能力和高性能。

 

一、配置输出格式化

uvicorn 其实已经有日志,只是没有格式化输出,我们希望可以加点东西丰富输出。

找到 uvicorn.config 里的源码, LOGGING_CONFIG配置如下:

LOGGING_CONFIG: Dict[str, Any] = {"version": 1,"disable_existing_loggers": False,"formatters": {"default": {"()": "uvicorn.logging.DefaultFormatter","fmt": "%(levelprefix)s %(message)s","use_colors": None,},"access": {"()": "uvicorn.logging.AccessFormatter","fmt": '%(levelprefix)s %(client_addr)s - "%(request_line)s" %(status_code)s',  # noqa: E501},},"handlers": {"default": {"formatter": "default","class": "logging.StreamHandler","stream": "ext://sys.stderr",},"access": {"formatter": "access","class": "logging.StreamHandler","stream": "ext://sys.stdout",},},"loggers": {"uvicorn": {"handlers": ["default"], "level": "INFO", "propagate": False},"uvicorn.error": {"level": "INFO"},"uvicorn.access": {"handlers": ["access"], "level": "INFO", "propagate": False},},
}

这段默认配置我们可以自定义,不过不是改源码,是初始化时加载我们新建的配置。比如在用 uvicorn 启动时,加上参数 log_config,uvicorn 自定义日志配置文件支持 json、yaml、ini 三种格式。

uvicorn.run(app='main:app',host="0.0.0.0",log_config='./uvicorn_config.json',port=8000,loop="asyncio")

以下这段 json 实现了,格式化输出控制台,日志输出到本地文件。首先创建 uvicorn_config.json 存放项目根目录:

{"version": 1,"disable_existing_loggers": false,"formatters": {"default": {"()": "uvicorn.logging.DefaultFormatter","fmt": "%(asctime)s %(threadName)s %(levelprefix)s  %(message)s",      # 增加了asctime和threadName"use_colors": null},"access": {"()": "uvicorn.logging.AccessFormatter","fmt": "%(asctime)s %(threadName)s %(levelprefix)s %(client_addr)s - '%(request_line)s' %(status_code)s"  # 增加了asctime和threadName}},"handlers": {"default": {"formatter": "default","class": "logging.StreamHandler","stream": "ext://sys.stderr"},# default日志输出到本地文件,定义了日志路径、备份数量"default_file": {"formatter": "default","class": "logging.handlers.TimedRotatingFileHandler","filename": "./logs/app.log","when": "midnight","encoding": "utf-8","backupCount": 10},"access": {"formatter": "access","class": "logging.StreamHandler","stream": "ext://sys.stdout"},# access日志输出到本地文件,定义了日志路径、备份数量"access_file": {"formatter": "access","class": "logging.handlers.TimedRotatingFileHandler","filename": "./logs/app.log","when": "midnight","encoding": "utf-8","backupCount": 10}},"loggers": {# 添加handler,default_file"uvicorn": {"handlers": ["default","default_file"], "level": "INFO", "propagate": false},"uvicorn.error": {"level": "INFO"},# 添加handler,access_file"uvicorn.access": {"handlers": ["access","access_file"], "level": "INFO", "propagate": false}}
}

 main.py文件

from api.aiserver_v3 import ai_server_v3
from fastapi import FastAPI
import uvicornapp = FastAPI()@app.get("/home")
async def get():return {'message':'OK'}@app.get("/test")
async def get():return {'message':'OK'}@app.get("/dev")
async def get():return {'message':'OK'}if __name__ == "__main__":uvicorn.run(app='main:app',host="0.0.0.0",log_config='./uvicorn_config.json',port=8000,loop="asyncio")

 运行main.py

控制台

app.log

 

二、业务代码调用 uvicorn 日志

查看 uvicorn 日志源码处理机制发现,本质上还是 logger.addHandler 方法添加 handler,所以可以用以下方法调用:

from api.aiserver_v3 import ai_server_v3
from fastapi import FastAPI
import uvicorn,loggingapp = FastAPI()log = logging.getLogger("uvicorn")@app.get("/home")
async def get():log.info('this is a test')return {'message':'OK'}@app.get("/test")
async def get():return {'message':'OK'}@app.get("/dev")
async def get():return {'message':'OK'}app.include_router(ai_server_v3,prefix='/ai',tags=['person'])if __name__ == "__main__":uvicorn.run(app='main:app',host="0.0.0.0",log_config='./uvicorn_config.json',port=8000,loop="asyncio")

 输出:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/775692.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL 学习笔记 进阶(锁 下,InnoDB引擎 上)

锁锁-表级锁-表锁介绍表级锁,每次操作锁住整张表。锁定粒度大,发生锁冲突的概率最高,并发度最低。应用在MyISAM,InnoDB,BDB等存储引擎中。 对于表级锁,主要分为以下三类:表锁 元数据锁(meta data lock,MDL) 意向锁表锁对于表锁,分为两类:表共享读锁(read lock) 表…

伙伴匹配系统踩坑日记1

伙伴匹配系统踩坑日记1 前端初始化 文档参考https://cn.vitejs.dev/guide/输入指令后报错解决方法参考https://blog.csdn.net/qq_26018335/article/details/126201219 yarn安装默认在c盘所以其global和cache配置在c盘,输入以下指令查看默认配置在哪个盘 yarn global dir只要在…

OpenAI 向部分用户开放 GPT-4o 高级语音模式;AI 视频生成工具 Vidu 全球上线丨 RTE 开发者日报

开发者朋友们大家好:这里是 「RTE 开发者日报」 ,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE(Real-Time Engagement) 领域内「有话题的新闻」、「有态度的观点」、「有意思的数据」、「有思考的文章」、「有看点的会议」,但内容仅代表编辑的个人观点…

如何设计可扩展的RPC协议

如何设计可扩展且向后兼容的RPC协议 为什么不直接用现成的HTTP协议? RPC的职责是负责应用间的通信,所以性能要求相对更高。而HTTP协议的数据包相对于请求数据本身要大很多,有很多冗余内容(如换行回车等),会影响性能。另外HTTP协议是无状态的协议,每次请求都要重新建立连接…

DataX - [02] 安装部署

题记部分 一、安装部署 (1)下载DataX:http://datax-opensource.oss-cn-hangzhou.aliyuncs.com/datax.tar.gz wget http://datax-opensource.oss-cn-hangzhou.aliyuncs.com/datax.tar.gz(2)解压到合适的目录:tar -zxvf datax.tar.gz -C /home/ecs-user/module/(3)进入b…

部署STONE-CRM中小企业的客户关系管理系统

Gitee地址 https://gitee.com/xpliu2166/stone-crm?skip_mobile=true环境查看# cat /etc/redhat-release Rocky Linux release 9.3 (Blue Onyx) # uname -a Linux Rocky9StoneCrm003080 5.14.0-362.18.1.el9_3.0.1.x86_64 #1 SMP PREEMPT_DYNAMIC Sun Feb 11 13:49:23 UTC 20…

全新小体积RK3562核心板,解锁神秘技能!

RK3562小体积金手指系列核心板基于瑞芯微四核Cortex-A53+Cortex-M0处理器设计,工作主频高达2GHz,最高搭载4GB高速LPDDR4、32GB eMMC。该核心板拥有204 Pin脚,尺寸仅为67.6mm *45mm,支持千兆网、USB3.0、串口、PCIE、HDMI等丰富外设资源,非常适合于高性能、高性价比的工业应…

H7-TOOL自制Flash读写保护算法系列,为STM32H7全系列芯片制作读写使能和解除算法,支持在线烧录和脱机烧录使用(2024-07-30)

说明:很多IC厂家仅发布了内部Flash算法文件,并没有提供读写保护算法文件,也就是选项字节算法文件,需要我们制作。 实际上当前已经发布的TOOL版本,已经自制很多了。但是依然有些厂家还没自制,所以陆续开始为这些厂家提供读写保护支持。 最近好几个网友咨询H7系列芯片保护支…

H7-TOOL自制Flash读写保护算法系列,为国民技术N32G031制作读写使能和解除算法,支持在线烧录和脱机烧录使用(2024-07-29)

说明: 很多IC厂家仅发布了内部Flash算法文件,并没有提供读写保护算法文件,也就是选项字节算法文件,需要我们制作。 实际上当前已经发布的TOOL版本,已经自制很多了。但是依然有些厂家还没自制,所以陆续开始为这些厂家提供读写保护支持。 实现效果: 本次添加国民技术的N32G…

DNS在架构中的使用

1 介绍 DNS(Domain Name System,域名系统)是一种服务,它是域名和IP地址相互映射的一个分布式数据库,能够使人更方便的访问互联网,而不用去记住能够被机器直接读取的IP地址数串。 简单来说,DNS就是一个将我们输入的网址(比如www.baidu.com )转换成对应的IP地址(比如19…

RPC核心原理

什么是RPC RPC就是远程过程调用 RPC的作用屏蔽远程调用和本地调用的区别,让我们感觉就是调用本地项目内的方法。 隐藏底层网络通信的复杂性,让我们更专注于业务逻辑。RPC通信流程 一个完整的RPC会涉及哪些步骤呢? 在调用方程序中,RPC框架根据调用的服务接口提前生成动态代理…