Files
ailine/LOGGING.md

251 lines
6.1 KiB
Markdown
Raw Normal View History

2026-04-16 03:21:38 +08:00
# 📝 日志使用规范
## 统一日志系统
本项目采用统一的日志系统,确保后端和前端的日志输出格式一致,便于调试和监控。
---
## 📁 日志模块位置
### 后端日志
- **模块路径**`app/logger.py`
- **日志器名称**`ai_agent`
- **使用方式**
```python
from app.logger import debug, info, warning, error
```
### 前端日志
- **模块路径**`frontend/logger.py`
- **日志器名称**`ai_agent_frontend`
- **使用方式**
```python
from frontend.logger import debug, info, warning, error
# 或
from .logger import debug, info, warning, error # 在 frontend 包内
```
---
## 🎯 日志级别
| 级别 | 函数 | 使用场景 | 环境变量控制 |
|------|------|---------|-------------|
| **DEBUG** | `debug()` | 详细调试信息(变量值、中间状态) | `DEBUG=true` 时输出 |
| **INFO** | `info()` | 关键流程节点服务启动、API 请求) | 始终输出 |
| **WARNING** | `warning()` | 警告信息(配置缺失、降级处理) | 始终输出 |
| **ERROR** | `error()` | 错误信息(异常、失败) | 始终输出 |
---
## 📝 使用示例
### 后端使用app/ 目录下)
```python
from app.logger import debug, info, warning, error
async def process_message(self, message: str, ...):
info(f"收到用户消息: {message[:50]}...")
try:
result = await graph.ainvoke(...)
debug(f"Graph 执行结果: {result}")
return result
except Exception as e:
error(f"消息处理失败: {e}")
raise
```
### 前端使用frontend/ 目录下)
```python
from .logger import error, warning
class APIClient:
def get_user_threads(self, user_id: str):
try:
resp = requests.get(...)
if resp.status_code != 200:
error(f"获取历史列表失败: HTTP {resp.status_code}")
return []
except Exception as e:
error(f"获取历史列表异常: {e}")
return []
```
---
## ⚙️ 配置说明
### 环境变量
| 变量 | 说明 | 默认值 | 示例 |
|------|------|--------|------|
| `LOG_LEVEL` | 日志级别 | `INFO` | `DEBUG`, `INFO`, `WARNING`, `ERROR` |
| `DEBUG` | 调试模式 | `false` | `true`, `false` |
### 本地开发配置(.env
```bash
# 输出详细调试信息
LOG_LEVEL=DEBUG
DEBUG=true
```
### Docker 部署配置(.env.docker
```bash
# 仅输出关键信息,减少日志量
LOG_LEVEL=WARNING
DEBUG=false
```
---
## 🚫 禁止事项
### ❌ 不要使用 `print()`
```python
# ❌ 错误
print("处理消息...")
print(f"错误: {e}")
# ✅ 正确
info("处理消息...")
error(f"错误: {e}")
```
### ❌ 不要使用 `loguru`
```python
# ❌ 错误
from loguru import logger
logger.info("消息")
# ✅ 正确
from app.logger import info # 后端
from frontend.logger import info # 前端
info("消息")
```
### ❌ 不要在工具函数中使用日志
工具函数应保持纯粹,避免副作用:
```python
# ❌ 错误
@tool
def read_file(filename: str):
info(f"读取文件: {filename}") # 工具函数不应有日志
return content
# ✅ 正确(日志在调用工具的地方)
async def tool_call_node(state):
info(f"调用工具: read_file")
result = await read_file.ainvoke(...)
return result
```
---
## 📊 日志格式
### 输出格式
```
2026-04-16 10:30:45 | INFO | ai_agent | 收到用户消息: 你好...
2026-04-16 10:30:45 | DEBUG | ai_agent | Graph 执行结果: {...}
2026-04-16 10:30:46 | WARNING | ai_agent_frontend | JSON 解析失败: ...
2026-04-16 10:30:46 | ERROR | ai_agent | 消息处理失败: ConnectionError
```
### 字段说明
| 字段 | 说明 |
|------|------|
| 时间 | `YYYY-MM-DD HH:MM:SS` |
| 级别 | `DEBUG`, `INFO`, `WARNING`, `ERROR`8 字符宽度,左对齐) |
| 日志器 | `ai_agent`(后端)或 `ai_agent_frontend`(前端) |
| 消息 | 日志内容 |
---
## 🔧 最佳实践
### 1. 使用结构化日志
```python
# ✅ 推荐:包含关键信息
info(f"用户 {user_id} 调用模型 {model_name}")
# ❌ 不推荐:信息不完整
info("调用模型")
```
### 2. 异常日志包含堆栈
```python
# ✅ 推荐:记录完整异常信息
try:
result = await api_call()
except Exception as e:
error(f"API 调用失败: {e}", exc_info=True)
```
### 3. 敏感信息脱敏
```python
# ✅ 推荐:隐藏敏感信息
debug(f"API Key: {api_key[:4]}...{api_key[-4:]}")
# ❌ 错误:泄露完整密钥
debug(f"API Key: {api_key}")
```
### 4. 日志级别合理使用
```python
# ✅ 推荐:根据重要性选择级别
info("服务启动成功") # 关键流程
debug(f"配置参数: {config}") # 调试信息
warning("配置缺失,使用默认值") # 警告但不影响运行
error("数据库连接失败") # 严重错误
```
---
## 📋 文件清单
| 文件 | 日志导入 | 说明 |
|------|---------|------|
| `app/agent.py` | `from app.logger import debug, info, warning, error` | ✅ 正确 |
| `app/backend.py` | `from app.logger import debug, info, warning, error` | ✅ 正确 |
| `app/history.py` | `from app.logger import error` | ✅ 已修复 |
| `app/nodes/*.py` | `from app.logger import ...` | ✅ 正确 |
| `app/tools.py` | 无日志 | ✅ 正确(工具函数不使用日志) |
| `frontend/api_client.py` | `from .logger import error, warning` | ✅ 已修复 |
| `frontend/logger.py` | 自身定义 | ✅ 前端日志模块 |
---
## 🎯 总结
### 核心原则
1. **统一模块**:后端使用 `app.logger`,前端使用 `frontend.logger`
2. **禁止 print**:所有输出必须通过日志模块
3. **禁止 loguru**:不使用第三方日志库
4. **环境控制**:通过 `LOG_LEVEL``DEBUG` 控制输出
5. **工具纯粹**:工具函数不使用日志,日志在调用方
### 优势
- ✅ 格式统一:所有日志输出格式一致
- ✅ 易于调试:支持分级输出,开发时查看详细信息
- ✅ 性能优化:生产环境可减少日志量
- ✅ 便于监控:日志格式标准化,便于日志收集和分析
---
**📝 所有文件已按照日志规范统一!**