# 日志管理指南 ## 概述 项目使用按服务拆分的日志系统,便于问题排查和服务监控。 ## 日志文件结构 ``` server/logs/ ├── app.log # FastAPI 应用日志(API 请求、业务逻辑) ├── celery_ai.log # AI Worker 日志(图片、视频、配音生成) ├── celery_export.log # Export Worker 日志(项目导出、视频渲染) ├── celery_beat.log # Beat 调度器日志(定时任务) ├── error.log # 所有 ERROR 级别日志(统一收集) ├── app_size.log # 按大小轮转日志(最大 100MB) └── *.log.2026-XX-XX # 历史日志(按日期轮转,保留 30 天) ``` ## 日志级别 | 级别 | 用途 | 示例 | |------|------|------| | DEBUG | 详细调试信息 | SQL 查询、函数调用 | | INFO | 常规操作信息 | 任务启动、完成状态 | | WARNING | 警告信息 | 重试操作、性能问题 | | ERROR | 错误信息 | 异常、失败操作 | | CRITICAL | 严重错误 | 服务崩溃、数据丢失 | ## 常用命令 ### 查看日志 ```bash # 实时查看 FastAPI 应用日志 tail -f logs/app.log # 实时查看 AI Worker 日志 tail -f logs/celery_ai.log # 实时查看 Export Worker 日志 tail -f logs/celery_export.log # 实时查看 Beat 调度器日志 tail -f logs/celery_beat.log # 查看所有错误日志 tail -f logs/error.log ``` ### 搜索日志 ```bash # 搜索 AI 任务错误 grep ERROR logs/celery_ai.log # 搜索特定任务 ID grep "task_id=abc123" logs/*.log # 搜索用户相关日志 grep "user_id=019c5a0b" logs/app.log # 搜索最近 1 小时的错误 grep "$(date -u +%Y-%m-%d\ %H)" logs/error.log ``` ### 日志分析 ```bash # 统计 API 请求数量 grep "GET\|POST\|PUT\|DELETE" logs/app.log | wc -l # 统计错误数量 grep -c ERROR logs/error.log # 查看最频繁的错误 grep ERROR logs/error.log | sort | uniq -c | sort -rn | head -10 # 分析 AI 任务耗时 grep "completed in" logs/celery_ai.log ``` ### 日志清理 ```bash # 删除 30 天前的历史日志 find logs/ -name "*.log.2026-*" -mtime +30 -delete # 压缩历史日志 tar czf logs_archive_$(date +%Y%m%d).tar.gz logs/*.log.2026-* # 清空当前日志(保留文件) > logs/app.log > logs/celery_ai.log > logs/celery_export.log > logs/celery_beat.log ``` ## 日志轮转配置 ### 按时间轮转(默认) - **轮转周期**:每天午夜(00:00) - **备份数量**:30 天 - **命名格式**:`app.log.2026-02-14` ### 按大小轮转 - **最大文件大小**:100 MB - **备份数量**:5 个 - **文件名**:`app_size.log` ## 容器内日志查看 ```bash # 查看 FastAPI 应用日志 docker exec jointo-server-app tail -f /app/logs/app.log # 查看 Celery AI Worker 日志 docker exec jointo-server-celery-ai tail -f /app/logs/celery_ai.log # 查看 Celery Export Worker 日志 docker exec jointo-server-celery-export tail -f /app/logs/celery_export.log # 查看容器标准输出(包含启动日志) docker logs -f jointo-server-app docker logs -f jointo-server-celery-ai docker logs -f jointo-server-celery-export docker logs -f jointo-server-celery-beat ``` ## 问题排查场景 ### 场景 1:AI 图片生成失败 ```bash # 1. 查看 AI Worker 日志 tail -f logs/celery_ai.log # 2. 搜索错误信息 grep ERROR logs/celery_ai.log | tail -20 # 3. 查找特定任务 grep "generate_image_task" logs/celery_ai.log # 4. 查看 API 触发日志 grep "generate_image" logs/app.log ``` ### 场景 2:导出任务超时 ```bash # 1. 查看 Export Worker 日志 tail -f logs/celery_export.log # 2. 查找超时任务 grep "timeout\|TimeoutError" logs/celery_export.log # 3. 检查队列积压 docker exec jointo-server-rabbitmq rabbitmqctl list_queues # 4. 查看 Worker 状态 docker logs jointo-server-celery-export ``` ### 场景 3:定时任务未执行 ```bash # 1. 查看 Beat 调度器日志 tail -f logs/celery_beat.log # 2. 搜索任务调度记录 grep "Scheduler" logs/celery_beat.log # 3. 检查 Beat 容器状态 docker ps | grep beat docker logs jointo-server-celery-beat ``` ### 场景 4:API 请求异常 ```bash # 1. 查看 FastAPI 应用日志 tail -f logs/app.log # 2. 搜索特定 API 路径 grep "/api/v1/storyboard" logs/app.log # 3. 查找 5xx 错误 grep "500\|502\|503\|504" logs/app.log # 4. 查看详细错误信息 grep ERROR logs/error.log | tail -20 ``` ## 日志监控告警(生产环境) ### 推荐工具 - **ELK Stack**:Elasticsearch + Logstash + Kibana - **Loki + Grafana**:轻量级日志聚合 - **云服务**:阿里云 SLS、AWS CloudWatch ### 告警规则建议 ```yaml # 错误率告警 - 条件:ERROR 日志超过 100 条/小时 - 级别:警告 # AI 任务失败率告警 - 条件:celery_ai.log 中 ERROR 超过 10 条/小时 - 级别:严重 # 导出任务超时告警 - 条件:celery_export.log 中 timeout 出现 - 级别:警告 # 磁盘空间告警 - 条件:logs 目录超过 10GB - 级别:警告 ``` ## 日志格式说明 ### 标准日志格式 ``` 时间戳 | 级别 | 模块:函数:行号 | request_id=xxx | user_id=xxx | 消息内容 ``` ### 示例 ``` 2026-02-14 03:21:14 | INFO | app.tasks.ai_tasks:generate_image_task:45 | request_id=abc123 | user_id=019c5a0b | 图片生成任务启动 ``` ### 字段说明 - **时间戳**:`YYYY-MM-DD HH:MM:SS` 格式 - **级别**:`DEBUG/INFO/WARNING/ERROR/CRITICAL` - **模块**:`app.tasks.ai_tasks` - **函数**:`generate_image_task` - **行号**:`45` - **request_id**:请求追踪 ID(跨服务追踪) - **user_id**:用户 ID(业务追踪) - **消息内容**:实际日志信息 ## 最佳实践 ### 1. 日志级别使用 ```python # ✅ 正确 logger.info("任务启动: task_id=%s", task_id) logger.error("任务失败: %s", error, exc_info=True) # ❌ 错误 logger.info("任务失败") # 应该使用 ERROR logger.debug("用户登录成功") # 应该使用 INFO ``` ### 2. 敏感信息处理 ```python # ✅ 正确:脱敏处理 logger.info("用户登录: phone=%s", phone[-4:]) # ❌ 错误:泄露敏感信息 logger.info("用户密码: %s", password) logger.info("API Key: %s", api_key) ``` ### 3. 异常日志记录 ```python # ✅ 正确:包含堆栈信息 try: do_something() except Exception as e: logger.error("操作失败", exc_info=True) # ❌ 错误:丢失堆栈信息 except Exception as e: logger.error(f"操作失败: {e}") ``` ### 4. 结构化日志 ```python # ✅ 正确:使用占位符 logger.info("任务完成: task_id=%s, duration=%dms", task_id, duration) # ❌ 错误:字符串拼接 logger.info(f"任务完成: task_id={task_id}, duration={duration}ms") ``` ## 日志备份策略 ### 本地备份 ```bash #!/bin/bash # 每天备份日志 BACKUP_DIR="/backup/logs" DATE=$(date +%Y%m%d) # 压缩当天日志 tar czf "${BACKUP_DIR}/logs_${DATE}.tar.gz" logs/*.log # 删除 7 天前的备份 find "${BACKUP_DIR}" -name "logs_*.tar.gz" -mtime +7 -delete ``` ### 远程备份 ```bash # 上传到 S3(阿里云 OSS) ossutil cp logs_20260214.tar.gz oss://your-bucket/logs/ # 上传到 NAS rsync -avz logs/ user@nas:/backup/logs/ ``` ## 常见问题 ### Q1: 日志文件过大导致磁盘满 **解决方案**: ```bash # 1. 检查磁盘使用 df -h # 2. 查找大文件 du -sh logs/* | sort -rh | head -10 # 3. 清理历史日志 find logs/ -name "*.log.2026-*" -mtime +7 -delete # 4. 调整日志级别(临时) # 在 .env 中设置:LOG_LEVEL=WARNING ``` ### Q2: 找不到特定日志 **排查步骤**: ```bash # 1. 确认日志文件存在 ls -lh logs/ # 2. 检查容器挂载 docker inspect jointo-server-app | grep -A 10 Mounts # 3. 查看容器内日志 docker exec jointo-server-app ls -lh /app/logs/ # 4. 检查日志配置 docker exec jointo-server-app env | grep LOG ``` ### Q3: 日志时区不一致 **说明**: - 容器内使用 UTC 时区 - 宿主机使用本地时区 - 建议统一使用 UTC,便于分布式系统日志关联 **查看时区**: ```bash # 容器内 docker exec jointo-server-app date # 宿主机 date ``` ## 相关文档 - [基础设施和部署](../../.claude/skills/jointo-tech-stack/references/infrastructure.md) - [日志规范](../../.claude/skills/jointo-tech-stack/references/logging.md) - [后端开发规范](../../.claude/skills/jointo-tech-stack/references/backend.md)