251 lines
6.1 KiB
Markdown
251 lines
6.1 KiB
Markdown
# 📝 日志使用规范
|
||
|
||
## 统一日志系统
|
||
|
||
本项目采用统一的日志系统,确保后端和前端的日志输出格式一致,便于调试和监控。
|
||
|
||
---
|
||
|
||
## 📁 日志模块位置
|
||
|
||
### 后端日志
|
||
- **模块路径**:`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. **工具纯粹**:工具函数不使用日志,日志在调用方
|
||
|
||
### 优势
|
||
- ✅ 格式统一:所有日志输出格式一致
|
||
- ✅ 易于调试:支持分级输出,开发时查看详细信息
|
||
- ✅ 性能优化:生产环境可减少日志量
|
||
- ✅ 便于监控:日志格式标准化,便于日志收集和分析
|
||
|
||
---
|
||
|
||
**📝 所有文件已按照日志规范统一!** |