fastapi: 第十四章: loguru记录多个日志
一,应用场景:
生产环境中,有时需要明确告诉loguru,我要把日志写入到定义的哪个文件中。
例如:有一个日志记录支付宝post的数据,有另一个日志记录快递100提交的数据
怎么做?
在
配合在
loguru 中,明确指定某条日志写入哪个文件的标准做法是:使用 logger.bind(name="特定标识"),配合在
logger.add() 中设置对应的 filter。这相当于给不同的日志文件拉了“专属微信群”,
你用
你用
bind 给日志打上标签,它就会自动对号入座,绝对不会串门二,代码:
说明:
logger.bind(key=value):它的作用是在日志的extra字典中注入一对键值对。record["extra"].get("log_type") == "alipay":loguru每记录一条日志,都会把日志送到所有 add 的文件里过一遍筛选。
过滤器发现这条日志的extra里恰好有log_type="alipay",alipay.log就会收下它;
而kuaidi100.log发现不匹配,就会直接忽略它。
通过这种“打标签-对暗号”的方式,你可以在项目里精准控制任何一条日志的去向。
配置logger
# app/core/logger.py
import os
import sys
from loguru import logger
# 确定日志存放目录
LOG_DIR = os.path.join(os.getcwd(), "logs")
os.makedirs(LOG_DIR, exist_ok=True)
# 1. 清除 Loguru 默认的控制台处理器
logger.remove()
# 2. 添加带颜色的控制台输出(开发环境)
logger.add(
sys.stdout,
level="INFO",
format="<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green> | <level>{level: <8}</level> | <cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - <level>{message}</level>",
)
# 3. 添加文件输出(生产环境,按天轮转,通用)
logger.add(
os.path.join(LOG_DIR, "app_{time:YYYY-MM-DD}.log"),
# 核心:只有调用 logger.bind(log_type="alipay") 的日志才会写入此文件
filter=lambda record: record["extra"].get("log_type") == "system",
level="INFO",
rotation="00:00", # 每天午夜 0 点创建新日志
retention="30 days", # 日志保留 30 天
compression="zip", # 历史日志自动压缩为 zip
enqueue=True, # 开启异步/线程安全写入
format="{time:YYYY-MM-DD HH:mm:ss.SSS} | {level: <8} | {name}:{function}:{line} - {message}",
)
# 4. 支付宝专用日志文件
logger.add(
os.path.join(LOG_DIR, "alipay_{time:YYYY-MM-DD}.log"),
level="INFO",
# 核心:只有调用 logger.bind(log_type="alipay") 的日志才会写入此文件
filter=lambda record: record["extra"].get("log_type") == "alipay",
format="{time:YYYY-MM-DD HH:mm:ss} | {message}",
encoding="utf-8",
enqueue=True,
rotation = "00:00", # 每天午夜 0 点创建新日志
retention = "30 days", # 日志保留 30 天
)
# 5. 快递100专用日志文件
logger.add(
os.path.join(LOG_DIR, "kuaidi100_{time:YYYY-MM-DD}.log"),
level="INFO",
# 核心:只有调用 logger.bind(log_type="kuaidi100") 的日志才会写入此文件
filter=lambda record: record["extra"].get("log_type") == "kuaidi100",
format="{time:YYYY-MM-DD HH:mm:ss} | {message}",
encoding="utf-8",
enqueue=True,
rotation="00:00", # 每天午夜 0 点创建新日志
retention="30 days", # 日志保留 30 天
)
# 导出配置好的 logger
__all__ = ["logger"]
业务中调用logger
# app/api/users.py
from fastapi import APIRouter
from app.core.logger import logger
# 创建路由器实例
# prefix:所有路由的统一前缀,避免重复写"/users"
# tags:在Swagger文档中分组显示
router = APIRouter(prefix="/users", tags=["用户管理"])
@router.get("/all")
def get_all_users():
"""获取所有用户"""
log_alipay = "支付宝post数据"
logger.bind(log_type="alipay").info(f"收到支付宝推送: {log_alipay}")
log_kuaidi100 = "快递100post数据"
logger.bind(log_type="kuaidi100").info(f"收到快递100推送: {log_kuaidi100}")
return [{"id": 1, "name": "张三"}, {"id": 2, "name": "李四"}]
异常时调用logger
# 4. 捕获系统未知异常 (如: 代码崩溃、数据库连接断开 500)
@app.exception_handler(Exception)
async def all_exception_handler(request: Request, exc: Exception):
# 注意:生产环境应将 exc 记录到日志系统(如 loguru)
params = await get_query_param(request)
logger.bind(log_type="system").exception(f"服务器内部崩溃 -> {params}")
content = BaseResponse(code=500, msg="服务器内部错误,请稍后再试", data=None).model_dump()
return JSONResponse(status_code=500, content=content)
三,查看效果:
kuaidi100的回调数据的log
2026-05-24 14:53:43 | 收到快递100推送: 快递100post数据
浙公网安备 33010602011771号