FastAPI logger日志记录方案 loguru模块

实现方式:

采用 loguru 模块、跟flask直接挂载到app上有区别,当然也可以尝试去这样做、

但是 好像没有这个必要、要的就是个快速、整那些子虚乌有的东西完全木有意义。

 

1、首先是去项目git溜达一圈:https://github.com/Delgan/loguru

   发现是英文。。。 木得感情、

  然后百度百度吧,还好python大神们都挺友好。

  百度一下 :python loguru 。。问题解决

  https://www.cnblogs.com/g2thend/p/12539923.html

  https://www.cnblogs.com/ice-coder/p/12821326.html

 

2、首先肯定是模块安装了

pip install loguru

 

3、结合到FastAPI 项目、其实老简单了。

  1)搞个单独的日志管理模块 

  2)日志内容配置

  3)项目模块引用、完活 !!!

 

1)日志配置模块: 创建extensions\logger.py,什么位置/名称的无所谓、只要能够被引用就行

 

 

 2)配置日志内容 : 应该都能看懂、看不懂自己百度去吧。

复制代码
import os
import time
from loguru import logger

basedir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

print(f"log basedir{basedir}")  # /xxx/python_code/FastAdmin/backend/app
# 定位到log日志文件
log_path = os.path.join(basedir, 'logs')

if not os.path.exists(log_path):
    os.mkdir(log_path)

log_path_all = os.path.join(log_path, f'{time.strftime("%Y-%m-%d")}_log.log')
log_path_error = os.path.join(log_path, f'{time.strftime("%Y-%m-%d")}_error.log')

# 日志简单配置
# 具体其他配置 可自行参考 https://github.com/Delgan/loguru
logger.add(log_path_all, rotation="12:00", retention="5 days", enqueue=True)
logger.add(log_path_error, rotation="12:00", retention="5 days", enqueue=True,level='ERROR') # 日志等级分割
# format 参数: {time} {level} {message}、  {time:YYYY-MM-DD at HH:mm:ss} | {level} | {message} 记录参数
# level 日志等级
# rotation 参数:1 week 一周、00:00每天固定时间、 500 MB 固定文件大小
# retention 参数: 10 days 日志最长保存时间
# compression 参数: zip 日志文件压缩格式
# enqueue 参数 True 日志文件异步写入
# serialize 参数: True 序列化json
# encoding 参数: utf-8 字符编码、部分情况会出现中文乱码问题
# logger.info('If you are using Python {}, prefer {feature} of course!', 3.6, feature='f-strings') 格式化输入内容
#  可通过等级不同对日志文件进行分割储存 
复制代码

 

 

 

 

 3)项目模块引用:

复制代码
from fastapi import FastAPI,Form,Query,UploadFile,File,Request
from pydantic import BaseModel,Field
from typing import Optional,List
import os,sys,time
from extensions.logger import logger



'''
虚拟环境切换: conda activate FastAPI
FastAPI 程序启动 :uvicorn manger:app --port 7777 --reload
'''

app = FastAPI()

@logger.catch # 异常记录装饰器、放到下面好像不行、应该是异步的关系。
def my_function(x, y, z):
    return [x,y,z]


@app.post('/')
async def root(data:dict):
    # get 请求
    logger.debug(f"这是日志!")
    logger.info('这是user接口:username={},当前时间戳为:{tiems}',data["username"], tiems=time.time())
    my_function(0,0)
    return {'message':'Hello World!'}
复制代码

 

 

      完活!!!!

 

太特么简单了,有木有、

 

 

================================================================================================================================

2025-01-15 扩展:

当业务内容多了之后,日志排查不太方便,看了一下 可以分不同的业务进行日志保存

我看推荐写的时候还有个移除默认处理器的操作,我移除后就写入失败了,说是为了防止在控制台进行内容输出,然后要加什么配置,搞不明白就没有继续深入了。

其实这样就够用了,他这个应该就是处理通常正式环境启动后的运行日志、确实可以有效减小该日志文件的大小。但是没搞懂,就先这样吧,影响不大

# 移除默认的处理器 new_logger.remove()

主要的就两点:

1、通过 logger.bind(name=name) 创建新的记录方式

2、过滤器  filter=lambda record: record["extra"].get("name") == name # 过滤器,对业务进行区分记录

完活 

复制代码
# 业务多了,日志也多了,我们可以为每个业务分别创建一个日志记录器
loggers = {}
def get_log_path(business_name, level="info") -> str:
        """
        根据业务名+等级+日期 生成日志文件名
        需要传入 业务名 和 日志等级
        """
        basedir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
        log_path = os.path.join(basedir, 'logs')

        if not os.path.exists(log_path):
            os.makedirs(log_path, exist_ok=True)

        time_str = time.strftime("%Y-%m-%d")
        log_file = f"{business_name}_{level}_{time_str}.log"
        log_path = os.path.join(log_path, log_file)

        return log_path

def get_logger(name: str) -> str:
    """
    获取日志记录器
    """
    if name in loggers:
        return loggers[name]
    
    # 创建一个新的日志记录器
    new_logger = loguru_logger.bind(name=name)

    new_logger.add(
                    get_log_path(name,'INFO'),  # 生成日志文件名
                    rotation="12:00", # 每天12点分割
                    retention="5 days",  # 保留5天
                    enqueue=True, # 异步写入
                    encoding='utf-8',  # 编码格式
                    filter=lambda record: record["extra"].get("name") == name # 过滤器,对业务进行区分记录
                    )
    
    new_logger.add(
                    get_log_path(name,'ERROR'), 
                    rotation="12:00", 
                    retention="5 days",
                    level='ERROR',  # 只记录错误
                    enqueue=True,
                    encoding='utf-8', 
                    filter=lambda record: record["extra"].get("name") == name
                   )

    loggers[name] = new_logger
    return new_logger



# 不一定要统一在这边调用,可以在需要的地方调用。 方便维护的话还是放在这边好一些。

# # 示例:为 business_b 创建日志记录器
# business_b_logger = get_logger("business_b")

# # 示例:为 business_a 创建日志记录器
# business_a_logger = get_logger("business_a")

# # 示例:为 manger 创建日志记录器
# manger_logger = get_logger("manger")
# manger_logger.info("666")
# 初始化日志记录器 
logger = get_logger("root")
logger.info("666")



复制代码

 

posted @   睡到自然醒ccc  阅读(6515)  评论(4编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示