Loguru:LLM 开发中的日志神器,让日志配置从此无痛
在 LLM(大模型)应用开发中,日志是定位问题、优化性能、保障系统稳定的核心工具。但传统 Python logging 模块的繁琐配置、异步场景下的日志阻塞、异常堆栈的不完整记录,常常让开发者在日志配置上花费大量时间,而无法专注于 LLM 业务逻辑。Loguru 作为一款 “开箱即用” 的 Python 日志库,凭借其极简配置、自动格式化、异步支持、异常捕获等特性,完美解决了 LLM 开发中的日志
【个人主页:玄同765】
大语言模型(LLM)开发工程师|中国传媒大学·数字媒体技术(智能交互与游戏设计)
深耕领域:大语言模型开发 / RAG知识库 / AI Agent落地 / 模型微调
技术栈:Python / LangChain/RAG(Dify+Redis+Milvus)| SQL/NumPy | FastAPI+Docker ️
工程能力:专注模型工程化部署、知识库构建与优化,擅长全流程解决方案
专栏传送门:LLM大模型开发 项目实战指南、Python 从真零基础到纯文本 LLM 全栈实战、从零学 SQL + 大模型应用落地、大模型开发小白专属:从 0 入门 Linux&Shell
「让AI交互更智能,让技术落地更高效」
欢迎技术探讨/项目合作! 关注我,解锁大模型与智能交互的无限可能!
在 LLM(大模型)应用开发中,日志是定位问题、优化性能、保障系统稳定的核心工具。但传统 Python logging 模块的繁琐配置、异步场景下的日志阻塞、异常堆栈的不完整记录,常常让开发者在日志配置上花费大量时间,而无法专注于 LLM 业务逻辑。
Loguru 作为一款 “开箱即用” 的 Python 日志库,凭借其极简配置、自动格式化、异步支持、异常捕获等特性,完美解决了 LLM 开发中的日志痛点。本文将从核心特性、安装配置、LLM 实战场景、最佳实践四个维度,带你掌握 Loguru 在 LLM 开发中的正确打开方式。
一、Loguru 核心特性:为什么适合 LLM 开发?
Loguru 的设计理念是 “让日志变得简单”,其核心特性完美适配 LLM 开发的复杂场景:
1. 开箱即用,零配置启动
无需繁琐的logging.basicConfig配置,导入即可直接使用,适合 LLM 原型开发快速验证:
from loguru import logger
logger.info("LLM应用启动成功") # 直接输出带时间、级别、模块的格式化日志
2. 自动格式化与着色
默认输出包含时间戳、日志级别、模块名、行号的结构化日志,终端输出自动着色,便于快速定位 LLM 请求的错误位置:
2024-05-20 14:30:00 | INFO | __main__:chat:12 - LLM请求成功,模型:gpt-3.5-turbo,耗时:1.2s
2024-05-20 14:30:05 | ERROR | __main__:chat:15 - LLM请求失败,错误:API超时
3. 原生异步支持
完美兼容 FastAPI、Asyncio 等异步框架,无需额外配置即可处理高并发 LLM 请求的日志,避免阻塞事件循环:
import asyncio
from loguru import logger
async def llm_chat(prompt: str):
logger.info(f"异步LLM请求: {prompt[:50]}...")
# 模拟异步调用LLM API
await asyncio.sleep(1)
logger.success("异步LLM请求完成")
4. 全局异常捕获
自动捕获整个应用的未处理异常,记录完整堆栈信息,包括 LLM 调用的上下文(如请求参数、模型名称),大幅降低问题定位难度:
from loguru import logger
# 全局捕获未处理异常
logger.add("llm_errors.log", level="ERROR", backtrace=True, diagnose=True)
def llm_call(prompt: str):
# 模拟LLM调用中的异常
raise ValueError("模型返回格式异常")
llm_call("生成一篇技术博客") # 异常会自动记录到日志文件,包含完整堆栈
5. 灵活的日志轮转与归档
支持按文件大小、时间、行数自动轮转日志,自动压缩归档旧日志,适合长期运行的 LLM 应用(如企业级助手、API 网关):
from loguru import logger
# 按大小轮转:单个日志文件最大100MB,保留5个备份,自动压缩
logger.add("llm_app.log", rotation="100 MB", retention=5, compression="zip")
# 按时间轮转:每天0点生成新日志,保留30天
logger.add("llm_daily.log", rotation="00:00", retention="30 days")
6. 多目标输出与过滤
支持同时输出到控制台、文件、邮件、甚至第三方服务(如 Sentry),并可通过过滤器实现 LLM 场景的日志隔离(如按模型名称分开记录):
from loguru import logger
# 同时输出到控制台和文件
logger.add("llm_app.log", level="INFO")
# 仅记录gpt-4模型的日志到单独文件
logger.add("llm_gpt4.log", filter=lambda record: "gpt-4" in record["extra"].get("model", ""))
二、安装与基础配置:5 分钟搞定 LLM 日志
1. 安装 Loguru
pip install loguru
2. 基础配置:LLM 场景定制
Loguru 的配置通过logger.add()实现,以下是 LLM 开发中常用的基础配置:
from loguru import logger
import sys
# 移除默认控制台输出(可选)
logger.remove()
# 配置控制台输出:定制LLM场景的日志格式
logger.add(
sys.stderr,
format="<green>{time:YYYY-MM-DD HH:mm:ss}</green> | <level>{level: <8}</level> | <cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> | <level>{message}</level> | 模型:{extra[model]} | 请求ID:{extra[request_id]}",
level="INFO",
colorize=True
)
# 配置文件输出:记录完整日志,包含异常堆栈
logger.add(
"llm_app.log",
format="{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {name}:{function}:{line} | {message} | 模型:{extra[model]} | 请求ID:{extra[request_id]}",
level="DEBUG",
rotation="100 MB",
retention=10,
compression="zip",
backtrace=True, # 记录完整异常堆栈
diagnose=True # 记录变量值(生产环境建议关闭)
)
3. LLM 场景扩展:绑定上下文信息
通过logger.bind()绑定 LLM 请求的上下文信息(如模型名称、请求 ID),实现日志的全链路追踪:
# 绑定上下文:每个LLM请求生成唯一请求ID
import uuid
llm_logger = logger.bind(model="gpt-3.5-turbo", request_id=str(uuid.uuid4()))
llm_logger.info("LLM请求开始,prompt:生成一篇关于Loguru的技术博客")
# 输出:2024-05-20 15:00:00 | INFO | __main__:<module>:1 | LLM请求开始,prompt:生成一篇关于Loguru的技术博客 | 模型:gpt-3.5-turbo | 请求ID:xxxx-xxxx-xxxx
三、LLM 开发实战:Loguru 的核心应用场景
1. 场景 1:LLM API 调用日志记录
在调用 OpenAI、Claude 等大模型 API 时,用 Loguru 记录请求参数、响应状态、耗时等关键信息:
from loguru import logger
import openai
import time
import uuid
# 绑定上下文
def get_llm_logger(model: str):
return logger.bind(model=model, request_id=str(uuid.uuid4()))
def call_openai(prompt: str, model: str = "gpt-3.5-turbo"):
llm_logger = get_llm_logger(model)
start_time = time.time()
try:
llm_logger.info(f"LLM请求开始,prompt:{prompt[:50]}...")
response = openai.ChatCompletion.create(
model=model,
messages=[{"role": "user", "content": prompt}]
)
llm_logger.success(f"LLM请求完成,耗时:{time.time()-start_time:.2f}s,token使用量:{response['usage']['total_tokens']}")
return response["choices"][0]["message"]["content"]
except Exception as e:
llm_logger.error(f"LLM请求失败,错误:{str(e)}", exc_info=True) # exc_info=True记录异常堆栈
raise
# 调用示例
call_openai("生成一篇关于Python日志库Loguru的技术博客")
2. 场景 2:异步 LLM 接口日志处理
在 FastAPI 等异步框架中,Loguru 原生支持异步日志,避免阻塞事件循环:
from fastapi import FastAPI, Request
from loguru import logger
import openai
import time
import uuid
app = FastAPI(title="LLM API")
# 中间件:为每个请求绑定请求ID
@app.middleware("http")
async def add_request_id(request: Request, call_next):
request_id = str(uuid.uuid4())
response = await call_next(request)
response.headers["X-Request-ID"] = request_id
# 绑定请求ID到全局日志
logger.configure(extra={"request_id": request_id})
return response
@app.post("/api/chat")
async def chat(prompt: str, model: str = "gpt-3.5-turbo"):
start_time = time.time()
logger.info(f"异步LLM请求开始,prompt:{prompt[:50]}...,模型:{model}")
try:
# 异步调用OpenAI API(需安装aiohttp版本的openai)
# response = await openai.ChatCompletion.acreate(model=model, messages=[{"role": "user", "content": prompt}])
await asyncio.sleep(1) # 模拟异步调用
logger.success(f"异步LLM请求完成,耗时:{time.time()-start_time:.2f}s")
return {"response": "模拟LLM响应", "request_id": logger.extra["request_id"]}
except Exception as e:
logger.error(f"异步LLM请求失败,错误:{str(e)}", exc_info=True)
raise
3. 场景 3:异常捕获与错误追踪
Loguru 的logger.catch()装饰器可以自动捕获函数中的异常并记录,适合 LLM 应用中的工具函数:
from loguru import logger
@logger.catch # 自动捕获函数中的异常并记录
def llm_tool_function(prompt: str):
# 模拟工具函数中的异常
if not prompt:
raise ValueError("prompt不能为空")
return f"处理后的prompt:{prompt}"
# 调用示例:异常会自动记录到日志
llm_tool_function("")
4. 场景 4:JSON 格式日志:便于 LLM 日志分析
将日志输出为 JSON 格式,方便后续用 ELK、Datadog 等工具分析 LLM 请求的性能、错误率等指标:
from loguru import logger
import json
# 自定义JSON格式化函数
def json_formatter(record):
record["extra"]["message"] = record["message"]
return json.dumps(record["extra"]) + "\n"
# 配置JSON格式日志输出
logger.add(
"llm_app.json.log",
format=json_formatter,
level="INFO",
rotation="100 MB"
)
# 绑定上下文信息
logger.bind(model="gpt-3.5-turbo", request_id="xxxx-xxxx", user_id="user123").info("LLM请求开始")
# 输出JSON:{"model": "gpt-3.5-turbo", "request_id": "xxxx-xxxx", "user_id": "user123", "message": "LLM请求开始"}
四、LLM 开发中的 Loguru 最佳实践
1. 日志脱敏:保护敏感信息
LLM 应用中常常处理用户的敏感 prompt(如个人信息、企业机密),需在日志中脱敏处理:
from loguru import logger
import re
# 脱敏函数:替换手机号、邮箱
def sensitive_data_masking(message: str):
message = re.sub(r'1[3-9]\d{9}', '1*********', message)
message = re.sub(r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}', '***@***.com', message)
return message
# 配置日志过滤器
logger.add(
"llm_app.log",
filter=lambda record: record["message"] != sensitive_data_masking(record["message"]),
format="{time} | {level} | " + sensitive_data_masking("{message}")
)
2. 按 LLM 模型隔离日志
通过logger.bind()和过滤器,将不同模型的日志分开记录,便于后续分析各模型的性能:
from loguru import logger
# 记录所有模型的日志
logger.add("llm_all.log", level="INFO")
# 仅记录gpt-4模型的日志
logger.add("llm_gpt4.log", filter=lambda record: record["extra"].get("model") == "gpt-4")
# 仅记录claude-3模型的日志
logger.add("llm_claude3.log", filter=lambda record: record["extra"].get("model") == "claude-3")
# 调用时绑定模型信息
logger.bind(model="gpt-4").info("gpt-4请求开始")
logger.bind(model="claude-3").info("claude-3请求开始")
3. 结合请求 ID 实现全链路追踪
为每个 LLM 请求生成唯一请求 ID,绑定到日志中,便于追踪整个请求的日志流程:
from loguru import logger
import uuid
def llm_request(prompt: str, model: str):
request_id = str(uuid.uuid4())
# 绑定请求ID
llm_logger = logger.bind(request_id=request_id, model=model)
llm_logger.info(f"请求开始,prompt:{prompt[:50]}...")
try:
# 调用LLM API
llm_logger.success("请求完成")
return {"response": "模拟响应", "request_id": request_id}
except Exception as e:
llm_logger.error(f"请求失败,错误:{str(e)}")
raise
4. 生产环境配置建议
生产环境中需关闭diagnose=True(避免泄露敏感变量值),并配置邮件 / 告警通知:
from loguru import logger
# 生产环境日志配置
logger.add(
"llm_app.log",
level="INFO",
rotation="100 MB",
retention=30,
compression="zip",
backtrace=True,
diagnose=False # 生产环境关闭变量诊断
)
# 错误日志发送邮件(需安装smtplib)
logger.add(
"mailto:admin@example.com",
level="ERROR",
format="{time} | {level} | {message} | {extra}",
subject="LLM应用错误告警"
)
五、Loguru vs 传统 logging:LLM 开发中的效率对比
| 维度 | Loguru | 传统 logging |
|---|---|---|
| 配置复杂度 | 零配置启动,5 分钟搞定 LLM 日志 | 需编写大量配置代码,学习成本高 |
| 异步支持 | 原生支持异步日志,适配高并发 LLM 请求 | 需手动配置异步 Handler,易阻塞事件循环 |
| 异常捕获 | 自动捕获未处理异常,记录完整堆栈 | 需手动 try-except,堆栈记录繁琐 |
| 日志格式定制 | 简洁的格式化字符串,支持上下文变量 | 需编写 Formatter 类,代码繁琐 |
| 日志轮转与归档 | 一行代码实现自动轮转与压缩 | 需配置 RotatingFileHandler 等,代码复杂 |
| LLM 场景适配 | 天然支持上下文绑定、多模型日志隔离 | 需自定义过滤器和额外代码实现 |
六、总结:Loguru 让 LLM 开发更专注业务
在 LLM 开发中,Loguru 凭借其开箱即用、异步支持、异常自动捕获、灵活配置等特性,完美解决了传统日志库的痛点,让开发者从繁琐的日志配置中解放出来,专注于 LLM 业务逻辑的实现。
无论是快速原型开发、高并发 API 网关,还是企业级 LLM 助手,Loguru 都能提供简单高效的日志解决方案。从今天起,让 Loguru 成为你 LLM 开发中的日志神器,让日志配置从此无痛!
更多推荐



所有评论(0)