You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
8.6 KiB
8.6 KiB
日志系统使用指南
日期: 2026-01-28
版本: 1.0.0
概述
项目使用 loguru 库实现轻量级日志系统,支持:
- 日志持久化(按日期和大小轮转)
- 分级输出(INFO、ERROR)
- 开发/生产环境不同配置
- 便捷的日志查看工具
日志配置
日志级别
通过环境变量 LOG_LEVEL 配置日志级别:
# .env
LOG_LEVEL=INFO # DEBUG, INFO, WARNING, ERROR, CRITICAL
推荐配置:
- 开发环境:
INFO或DEBUG - 测试环境:
INFO - 生产环境:
WARNING或ERROR
日志输出
日志会输出到以下位置:
1. 控制台输出
- 开发环境:彩色输出,显示详细信息
- 生产环境:简化输出,减少性能影响
2. 文件输出
所有日志文件位于 server/logs/ 目录:
| 文件名 | 说明 | 轮转策略 | 保留时间 |
|---|---|---|---|
app_YYYY-MM-DD.log |
所有日志(按日期) | 每天午夜 | 30 天 |
error_YYYY-MM-DD.log |
仅错误日志 | 每天午夜 | 30 天 |
app_size_YYYY-MM-DD.log |
所有日志(按大小) | 100 MB | 30 天 |
特性:
- ✅ 自动压缩旧日志(zip 格式)
- ✅ 异步写入,不阻塞主线程
- ✅ 错误日志包含完整堆栈跟踪和变量值
日志查看
方法 1:使用日志查看脚本(推荐)
项目提供了便捷的日志查看脚本 server/scripts/view_logs.sh:
cd server
# 查看帮助
./scripts/view_logs.sh -h
# 列出所有日志文件
./scripts/view_logs.sh -l
# 查看最新 50 行日志(默认)
./scripts/view_logs.sh
# 查看最新 100 行日志
./scripts/view_logs.sh -t 100
# 实时跟踪日志
./scripts/view_logs.sh -f
# 查看错误日志
./scripts/view_logs.sh -e
# 搜索日志内容
./scripts/view_logs.sh -s "用户登录"
# 查看指定日期的日志
./scripts/view_logs.sh -d 2026-01-28
# 查看容器日志
./scripts/view_logs.sh -c
方法 2:直接查看日志文件
cd server
# 查看最新日志
tail -f logs/app_$(date +%Y-%m-%d).log
# 查看错误日志
tail -f logs/error_$(date +%Y-%m-%d).log
# 搜索日志
grep "关键词" logs/app_*.log
# 查看压缩的日志
unzip -p logs/app_2026-01-27.log.zip | less
方法 3:查看容器日志
# 查看实时日志
docker logs -f jointo-server-app
# 查看最新 100 行
docker logs jointo-server-app --tail 100
# 查看特定时间段的日志
docker logs jointo-server-app --since 2026-01-28T10:00:00
# 查看 Celery Worker 日志
docker logs -f jointo-server-celery-ai
docker logs -f jointo-server-celery-export
docker logs -f jointo-server-celery-beat
日志使用示例
在代码中使用日志
from loguru import logger
# INFO 级别
logger.info("用户登录成功", user_id=user.user_id, ip=request.client.host)
# WARNING 级别
logger.warning("积分余额不足", user_id=user.user_id, balance=user.balance)
# ERROR 级别
logger.error("数据库连接失败", error=str(e))
# 带异常堆栈
try:
# 业务逻辑
pass
except Exception as e:
logger.exception("处理请求时发生异常") # 自动记录堆栈跟踪
# 结构化日志
logger.info(
"API 请求",
method=request.method,
path=request.url.path,
status_code=response.status_code,
duration_ms=duration
)
日志格式
控制台输出(开发环境):
2026-01-28 10:30:45.123 | INFO | app.api.v1.auth:login:45 | 用户登录成功
文件输出:
2026-01-28 10:30:45.123 | INFO | app.api.v1.auth:login:45 | 用户登录成功
错误日志(包含堆栈跟踪):
2026-01-28 10:30:45.123 | ERROR | app.services.user_service:create_user:78 | 创建用户失败
Traceback (most recent call last):
File "app/services/user_service.py", line 78, in create_user
await self.repository.create(user)
...
ValueError: 用户名已存在
日志管理
日志清理
日志会自动清理(保留 30 天),也可以手动清理:
cd server
# 删除 30 天前的日志
find logs/ -name "*.log" -mtime +30 -delete
find logs/ -name "*.zip" -mtime +30 -delete
# 删除所有日志(谨慎使用)
rm -rf logs/*
日志备份
cd server
# 备份日志到指定目录
tar -czf logs_backup_$(date +%Y%m%d).tar.gz logs/
# 上传到云存储(示例)
# aws s3 cp logs_backup_*.tar.gz s3://my-bucket/logs/
日志分析
使用 grep、awk、sed 等工具分析日志:
# 统计错误数量
grep "ERROR" logs/app_*.log | wc -l
# 统计 API 请求数量
grep "completed with status" logs/app_*.log | wc -l
# 统计最慢的 API 请求
grep "completed with status" logs/app_*.log | \
awk '{print $(NF-1)}' | \
sort -rn | \
head -10
# 统计错误类型分布
grep "ERROR" logs/app_*.log | \
awk -F'|' '{print $NF}' | \
sort | uniq -c | sort -rn
生产环境配置
推荐配置
# .env (生产环境)
ENVIRONMENT=production
LOG_LEVEL=WARNING
DATABASE_ECHO=False # 关闭 SQLAlchemy 日志
性能优化
-
关闭 SQLAlchemy 日志
# app/core/config.py DATABASE_ECHO: bool = False # 生产环境 -
提高日志级别
LOG_LEVEL=WARNING # 或 ERROR -
减少日志输出
- 仅记录关键业务日志
- 避免在循环中记录日志
- 使用结构化日志而非字符串拼接
监控告警
可以配合以下工具实现日志监控和告警:
-
简单方案:使用 cron 定时检查错误日志
# 每小时检查错误日志,如果有新错误则发送通知 0 * * * * [ -s /path/to/logs/error_$(date +\%Y-\%m-\%d).log ] && echo "发现错误日志" | mail -s "错误告警" admin@example.com -
企业方案:集成 ELK Stack 或 Loki + Grafana
- 参考 日志系统升级方案(未来实施)
故障排查
问题 1:日志文件不存在
原因:日志目录未创建或权限不足
解决方案:
cd server
mkdir -p logs
chmod 755 logs
问题 2:日志文件过大
原因:日志级别设置为 DEBUG,或 SQLAlchemy 日志未关闭
解决方案:
# 修改 .env
LOG_LEVEL=INFO
DATABASE_ECHO=False
# 重启服务
docker-compose restart app
问题 3:容器重启后日志丢失
原因:日志目录未挂载到宿主机
解决方案:
# docker-compose.yml
volumes:
- ./logs:/app/logs # 确保此行存在
问题 4:日志中文乱码
原因:编码问题
解决方案:
- 日志文件已配置
encoding="utf-8" - 查看时使用支持 UTF-8 的工具(如
less -R)
最佳实践
1. 日志级别使用
- DEBUG:详细的调试信息(仅开发环境)
- INFO:关键业务流程(用户登录、订单创建等)
- WARNING:警告信息(余额不足、配额即将用尽等)
- ERROR:错误信息(数据库连接失败、第三方服务异常等)
- CRITICAL:严重错误(系统崩溃、数据丢失等)
2. 日志内容
✅ 好的日志:
logger.info(
"用户登录成功",
user_id=user.user_id,
username=user.username,
ip=request.client.host,
user_agent=request.headers.get("user-agent")
)
❌ 不好的日志:
logger.info("用户登录") # 缺少上下文信息
logger.info(f"用户 {user.user_id} 登录成功") # 字符串拼接,不利于结构化分析
3. 敏感信息
❌ 禁止记录敏感信息:
- 密码、token、密钥
- 身份证号、银行卡号
- 完整的手机号(可记录脱敏后的)
✅ 脱敏示例:
# 手机号脱敏
phone_masked = phone[:3] + "****" + phone[-4:]
logger.info("发送验证码", phone=phone_masked)
4. 性能考虑
- 避免在高频循环中记录日志
- 使用结构化日志而非字符串拼接
- 生产环境使用 WARNING 或 ERROR 级别
相关文档
未来扩展
当项目规模扩大时,可以考虑升级到企业级日志系统:
-
ELK Stack(Elasticsearch + Logstash + Kibana)
- 集中式日志管理
- 强大的搜索和分析能力
- 可视化仪表板
-
Loki + Grafana(更轻量)
- Grafana Labs 出品
- 资源占用更少
- 与 Prometheus 集成良好
-
云服务
- 阿里云日志服务(SLS)
- 腾讯云日志服务(CLS)
- AWS CloudWatch Logs
详细方案参考:日志系统升级方案(待编写)