# 家庭日报系统 专注于家庭生活的轻量级日报系统,使用Django框架开发。 ## 功能特性 ### 核心功能模块 #### 1. 阅读记录管理 - 支持添加、编辑、删除阅读记录 - 阅读类型分类管理(如:书籍、文章、论文等) - 记录阅读标题、来源、进度 - 支持添加阅读笔记 - 支持文件上传(阅读相关资料) - 支持查看昨日和今日的阅读记录 #### 2. 感悟记录管理 - 支持添加、编辑、删除感悟记录 - 支持选择发言人(家庭成员) - 感悟内容记录 - 支持文件上传(感悟相关资料) - 支持查看昨日和今日的感悟记录 #### 3. 汇总记录管理 - 支持添加、编辑、删除汇总记录 - 汇总分类管理(如:新闻、知识、生活等) - 支持选择发言人和来源 - 汇总内容记录 - 支持文件上传 #### 4. 家庭事项管理 - 支持添加、编辑、删除家庭事项 - 自定义事项类型 - 设置优先级(高、中、低) - 设置状态(待处理、已完成等) - 设置截止日期 - 支持按优先级和截止日期排序 #### 5. 今日计划管理 - 支持添加、编辑、删除今日计划 - 设置计划类型 - 设置优先级 - 设置状态(待处理、已完成) - 支持状态快速切换 - 支持选择发言人 - 按优先级排序显示 #### 6. 报告生成与查看 - 自动生成每日家庭日报 - 报告内容包括: - 昨日阅读记录汇总 - 昨日感悟记录汇总 - 昨日汇总记录 - 今日计划列表 - 家庭事项统计 - 支持查看历史报告 - 支持选择不同日期查看报告 #### 7. PDF报告生成 - 使用WeasyPrint生成PDF格式报告 - 支持报告预览(HTML格式,与PDF样式一致) - 支持下载PDF文件 - PDF文件自动保存到服务器 - 支持查看历史PDF文件列表 #### 8. 邮件发送功能 - 支持SMTP邮件发送 - 邮件包含PDF报告附件 - 支持定时发送(通过Celery Beat) - 支持手动发送 - 可配置发送时间 - 支持多个收件人 #### 9. 系统配置 - SMTP服务器配置 - 发送时间设置 - 发件人邮箱配置 - 收件人邮箱配置 - 通过Web界面进行配置 #### 10. 后台管理界面 - 完整的Django Admin后台 - 访问路径:/houtai - 管理所有数据模型 - 管理用户和权限 ### 数据模型 | 模型 | 说明 | 主要字段 | |-----|------|---------| | ReadingType | 阅读记录类型 | name | | FamilyTaskType | 家庭事项类型 | name | | Priority | 优先级 | name | | Status | 状态 | name | | PlanType | 今日计划类型 | name | | FamilyMember | 家庭成员 | name | | ReadingRecord | 阅读记录 | date, type, title, source, progress, note, file | | InsightRecord | 感悟记录 | date, content, speaker, file | | Summary | 汇总记录 | date, category, speaker, content, source, file | | FamilyTask | 家庭事项 | type, content, priority, status, deadline | | TodayPlan | 今日计划 | date, content, speaker, priority, type, status | | SystemConfig | 系统配置 | smtp_server, send_time, recipient_email等 | ### 异步任务 系统使用Celery处理异步任务: - `generate_daily_pdf_report`:每日PDF报告生成 - `send_daily_report`:每日邮件发送 - 依赖Redis作为消息代理 - 支持定时任务调度 ## 技术栈 - Python 3.10+ - Django 4.2+ - Bootstrap 5 - SQLite(开发环境) - PostgreSQL/MySQL(生产环境) - Gunicorn + Nginx(生产部署) ## 快速开始 ### 安装依赖 ```bash pip install -r requirements.txt ``` ### 运行开发服务器 ```bash python manage.py runserver ``` ### 访问系统 打开浏览器访问:http://127.0.0.1:8000 ## 数据库迁移指南 ### 基本迁移流程 1. 生成迁移文件: ```bash python manage.py makemigrations ``` 2. 查看迁移文件内容(重要!): ```bash cat core/migrations/000x_xxx.py ``` 3. 应用迁移: ```bash python manage.py migrate ``` ### 当数据库有数据时增加字段 #### 问题说明 当数据库中已有数据时,通过Django的migrate命令增加新字段**不会删除原有数据**,但需要注意以下几点: 1. 如果新字段设置为**非空**(`null=False, blank=False`),则必须提供默认值,否则迁移会失败 2. 如果新字段设置为**可空**(`null=True, blank=True`),则迁移会自动执行,原有记录的新字段值为NULL #### 正确部署流程 1. **在开发环境测试**: - 首先在开发环境生成迁移文件 - 检查迁移文件内容,确保: - 新字段设置为可空(`null=True, blank=True`),或者 - 新字段提供了合理的默认值 - 在开发环境执行迁移,测试功能是否正常 2. **备份生产数据库**(重要!): ```bash # PostgreSQL示例 pg_dump -U username -d dbname > backup_$(date +%Y%m%d_%H%M%S).sql # MySQL示例 mysqldump -u username -p dbname > backup_$(date +%Y%m%d_%H%M%S).sql ``` 3. **在生产环境执行迁移**: ```bash # 进入项目目录 cd /path/to/diary-family # 激活虚拟环境 source venv/bin/activate # 生成迁移文件(如果在开发环境已生成,可跳过) python manage.py makemigrations # 应用迁移 python manage.py migrate ``` 4. **验证迁移结果**: - 检查应用是否正常运行 - 验证新功能是否可用 - 检查数据是否完整 #### 示例:增加阅读笔记(note)字段 1. 在模型中添加字段(`core/models.py`): ```python # 正确的做法:设置为可空字段 note = models.TextField(blank=True, null=True, verbose_name="阅读笔记") # 或者:提供默认值 note = models.TextField(default="", blank=True, verbose_name="阅读笔记") ``` 2. 生成迁移文件: ```bash python manage.py makemigrations ``` 3. 检查迁移文件,确保新字段设置正确: ```python # 迁移文件示例(0003_readingrecord_note.py) class Migration(migrations.Migration): dependencies = [ ('core', '0002_xxx'), ] operations = [ migrations.AddField( model_name='readingrecord', name='note', field=models.TextField(blank=True, null=True, verbose_name='阅读笔记'), ), ] ``` 4. 应用迁移: ```bash python manage.py migrate ``` ## CSV数据导入指南 ### 生成CSV文件 项目包含一个`generate_import_csv.py`脚本,用于生成符合数据库表结构的CSV文件并导入数据。 1. 生成CSV文件: ```bash python generate_import_csv.py ``` 2. 生成的CSV文件: - `reading_type.csv` - 阅读记录类型 - `insight_record.csv` - 感悟记录 - `reading_record.csv` - 阅读记录 ### CSV文件格式说明 #### reading_type.csv(阅读记录类型) | 字段名 | 类型 | 说明 | |-------|------|------| | name | 字符串 | 阅读类型名称(如:书籍、文章、论文等) | #### insight_record.csv(感悟记录) | 字段名 | 类型 | 说明 | |-------|------|------| | date | 日期 | 记录日期(格式:YYYY-MM-DD) | | content | 文本 | 感悟内容 | #### reading_record.csv(阅读记录) | 字段名 | 类型 | 说明 | |-------|------|------| | date | 日期 | 记录日期(格式:YYYY-MM-DD) | | type_id | 整数 | 阅读类型ID(关联reading_type表的id字段) | | title | 字符串 | 阅读标题 | | source | 字符串 | 阅读来源 | | progress | 字符串 | 阅读进度(如:已完成、进行中、未开始) | | note | 文本 | 阅读笔记 | ### 自定义CSV数据 你可以手动编辑生成的CSV文件,添加或修改数据,然后再次运行导入脚本将数据导入到数据库。 ### 数据导入 脚本会自动将CSV数据导入到数据库中,导入流程: 1. 清空ReadingType表的现有数据(避免类型ID冲突) 2. 导入ReadingType数据 3. 导入InsightRecord数据 4. 导入ReadingRecord数据 ### 验证导入结果 可以使用Django shell查询数据库,验证数据是否正确导入: ```bash python -c "import os; os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'diary_family.settings'); import django; django.setup(); from core.models import ReadingType, InsightRecord, ReadingRecord; print('ReadingType数量:', ReadingType.objects.count()); print('InsightRecord数量:', InsightRecord.objects.count()); print('ReadingRecord数量:', ReadingRecord.objects.count()); print('ReadingType数据:', [rt.name for rt in ReadingType.objects.all()])" ``` ## 生产部署 ### 使用Gunicorn + Nginx 1. 安装Gunicorn: ```bash pip install gunicorn ``` 2. 启动Gunicorn: ```bash gunicorn diary_family.wsgi:application --bind 0.0.0.0:8000 ``` 3. 配置Nginx(`/etc/nginx/sites-available/diary-family`): ```nginx server { listen 80; server_name example.com; location / { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } location /static/ { alias /path/to/diary-family/static/; } location /media/ { alias /path/to/diary-family/media/; } } ``` 4. 启用Nginx配置: ```bash ln -s /etc/nginx/sites-available/diary-family /etc/nginx/sites-enabled/ systemctl restart nginx ``` ## Redis服务器部署(必需) 家庭日报系统使用Celery进行异步任务处理(如PDF生成、邮件发送),而Celery依赖Redis作为消息代理和结果后端。**在生产环境中必须部署Redis服务器**。 ### 1. 安装Redis服务器 在Ubuntu服务器上安装Redis: ```bash # 更新包管理器 sudo apt update # 安装Redis服务器 sudo apt install redis-server -y # 启动Redis服务 sudo systemctl start redis-server # 设置Redis开机自启 sudo systemctl enable redis-server # 检查Redis服务状态 sudo systemctl status redis-server ``` ### 2. 配置Redis安全设置(生产环境重要) 编辑Redis配置文件以增强安全性: ```bash # 备份原始配置文件 sudo cp /etc/redis/redis.conf /etc/redis/redis.conf.backup # 编辑Redis配置文件 sudo nano /etc/redis/redis.conf ``` 在配置文件中进行以下修改: ```ini # 1. 绑定到本地地址(或特定IP),禁止外部访问 bind 127.0.0.1 # 2. 设置强密码(强烈建议) requirepass your_secure_password_here # 3. 禁用危险命令(防止误操作) rename-command FLUSHDB "" rename-command FLUSHALL "" rename-command CONFIG "" # 4. 限制内存使用(根据服务器内存调整) maxmemory 256mb maxmemory-policy allkeys-lru # 5. 启用持久化 save 900 1 save 300 10 save 60 10000 ``` 保存并重启Redis服务: ```bash # 重启Redis使配置生效 sudo systemctl restart redis-server # 验证Redis是否正常运行 redis-cli ping ``` ### 3. 测试Redis连接 验证Redis是否可以正常连接: #### 基本连接测试: ```bash # 测试无密码连接(如果设置了密码,应该失败) redis-cli ping # 使用密码连接(应该成功) redis-cli -a your_secure_password_here ping # 测试基本操作 redis-cli -a your_secure_password_here set test_key "hello" redis-cli -a your_secure_password_here get test_key redis-cli -a your_secure_password_here del test_key ``` #### 高级测试: ```bash # 测试Redis信息 redis-cli -a your_secure_password_here info # 测试内存使用 redis-cli -a your_secure_password_here info memory # 测试持久化状态 redis-cli -a your_secure_password_here info persistence # 测试连接数 redis-cli -a your_secure_password_here info clients # 性能测试(设置100个键) for i in {1..100}; do redis-cli -a your_secure_password_here set "perf:$i" "value$i" > /dev/null; done # 性能测试(获取100个键) for i in {1..100}; do redis-cli -a your_secure_password_here get "perf:$i" > /dev/null; done # 清理测试数据 for i in {1..100}; do redis-cli -a your_secure_password_here del "perf:$i" > /dev/null; done ``` #### 使用Python测试脚本: 项目提供了专门的测试脚本,可以全面测试Redis和Celery集成: ```bash # 运行完整的Redis和Celery测试 python test_redis_celery.py # 测试输出示例: # 2024-01-15 10:30:00 | INFO | 开始测试Redis连接... # 2024-01-15 10:30:01 | SUCCESS | Redis连接测试通过! # 2024-01-15 10:30:02 | INFO | 开始测试Celery与Redis集成... # 2024-01-15 10:30:03 | SUCCESS | Celery与Redis集成测试通过! # 2024-01-15 10:30:04 | INFO | 开始测试Redis性能... # 2024-01-15 10:30:05 | SUCCESS | Redis性能优秀! # 2024-01-15 10:30:06 | SUCCESS | 所有测试通过!生产环境Redis和Celery配置正确。 ``` #### 快速验证命令: ```bash # 一键验证Redis服务状态 sudo systemctl status redis-server --no-pager # 验证Redis端口监听 sudo netstat -tlnp | grep 6379 # 验证Redis进程 ps aux | grep redis-server # 验证Redis日志 sudo tail -n 10 /var/log/redis/redis-server.log ``` ### 4. 配置Django项目使用Redis 在Django项目的`settings.py`中,更新Celery配置以使用Redis: ```python # 生产环境Redis配置(带密码) CELERY_BROKER_URL = 'redis://:your_secure_password_here@localhost:6379/0' CELERY_RESULT_BACKEND = 'redis://:your_secure_password_here@localhost:6379/0' ``` ### 5. 验证Celery与Redis连接 测试Celery是否可以正常连接到Redis: ```bash # 激活虚拟环境 source /path/to/venv/bin/activate # 测试Celery连接 celery -A diary_family inspect ping # 查看Celery worker状态 celery -A diary_family status # 查看任务队列 celery -A diary_family inspect active celery -A diary_family inspect scheduled ``` ### 6. Redis监控和维护 #### 监控Redis性能: ```bash # 查看Redis基本信息 redis-cli -a your_secure_password_here info # 查看内存使用情况 redis-cli -a your_secure_password_here info memory # 查看连接数 redis-cli -a your_secure_password_here info clients # 查看持久化状态 redis-cli -a your_secure_password_here info persistence ``` #### 定期维护: ```bash # 备份Redis数据 sudo cp /var/lib/redis/dump.rdb /backup/redis/dump.rdb.$(date +%Y%m%d) # 清理过期键 redis-cli -a your_secure_password_here --scan --pattern "*" | xargs redis-cli -a your_secure_password_here del # 查看慢查询日志 redis-cli -a your_secure_password_here slowlog get 10 ``` ### 7. Redis故障排除 #### 问题1:Redis服务无法启动 ```bash # 查看Redis日志 sudo journalctl -u redis-server -f # 检查配置文件语法 sudo redis-server /etc/redis/redis.conf --test # 检查端口占用 sudo netstat -tlnp | grep 6379 ``` #### 问题2:连接被拒绝 ```bash # 检查防火墙设置 sudo ufw status sudo ufw allow 6379/tcp # 检查Redis绑定地址 sudo grep "^bind" /etc/redis/redis.conf # 检查Redis是否在监听 sudo ss -tlnp | grep 6379 ``` #### 问题3:内存不足 ```bash # 查看内存使用情况 redis-cli -a your_secure_password_here info memory # 清理过期数据 redis-cli -a your_secure_password_here memory purge # 调整内存策略 # 编辑 /etc/redis/redis.conf 调整 maxmemory 和 maxmemory-policy ``` ### 8. 生产环境优化建议 1. **使用独立Redis实例**:为Celery专门配置一个Redis实例 2. **配置监控告警**:使用Prometheus + Grafana监控Redis性能 3. **定期备份**:设置定时任务备份Redis数据 4. **性能调优**:根据实际使用情况调整内存和连接数配置 5. **高可用方案**:考虑使用Redis Sentinel或Redis Cluster ### 9. Redis部署常见问题解答(FAQ) #### Q1: Redis是必须的吗?可以用其他消息队列替代吗? **A**: 是的,Redis是必须的。家庭日报系统使用Celery进行异步任务处理,而Celery默认使用Redis作为消息代理。虽然可以使用RabbitMQ、Amazon SQS等其他消息队列,但需要修改Celery配置和代码。Redis是最简单、性能最好的选择。 #### Q2: Redis应该安装在哪台服务器上? **A**: 建议的部署方案: 1. **小型部署**:Redis和Django应用安装在同一台服务器上(推荐初学者) 2. **中型部署**:Redis安装在与Django应用不同的服务器上,但在同一内网 3. **生产部署**:使用Redis集群或云Redis服务(如AWS ElastiCache、Azure Cache for Redis) #### Q3: Redis需要多少内存? **A**: 内存需求取决于使用情况: - **最小配置**: 256MB(适合小型家庭使用) - **推荐配置**: 1GB(适合常规使用,有增长空间) - **生产配置**: 2GB+(适合多用户或高频任务) #### Q4: 如何设置Redis密码? **A**: 在 `/etc/redis/redis.conf` 中设置: ```ini requirepass your_strong_password_here ``` 然后在Django的 `settings.py` 中更新: ```python CELERY_BROKER_URL = 'redis://:your_strong_password_here@localhost:6379/0' ``` #### Q5: Redis数据会丢失吗? **A**: Redis默认将数据存储在内存中,重启服务会丢失数据。但可以通过配置持久化来避免: ```ini # 在redis.conf中启用持久化 save 900 1 # 900秒内至少有1个键被修改 save 300 10 # 300秒内至少有10个键被修改 save 60 10000 # 60秒内至少有10000个键被修改 ``` #### Q6: 如何监控Redis性能? **A**: 使用以下命令监控: ```bash # 实时监控 redis-cli -a your_password monitor # 查看统计信息 redis-cli -a your_password info # 查看慢查询 redis-cli -a your_password slowlog get 10 ``` #### Q7: Celery任务堆积怎么办? **A**: 处理步骤: 1. 增加worker数量:`celery -A diary_family worker --concurrency=4 -l info` 2. 优化任务代码,减少执行时间 3. 使用优先级队列 4. 监控Redis内存使用,防止内存不足 #### Q8: 如何备份Redis数据? **A**: 备份方法: ```bash # 手动备份 sudo cp /var/lib/redis/dump.rdb /backup/redis/dump.rdb.$(date +%Y%m%d) # 自动备份(添加到crontab) 0 2 * * * sudo cp /var/lib/redis/dump.rdb /backup/redis/dump.rdb.$(date +\%Y\%m\%d) ``` #### Q9: Redis连接数过多怎么办? **A**: 解决方法: 1. 增加最大连接数(在redis.conf中): ```ini maxclients 10000 ``` 2. 优化Celery连接池 3. 检查是否有连接泄漏 #### Q10: 如何验证Redis部署是否成功? **A**: 使用项目提供的测试脚本: ```bash # 运行完整测试 python test_redis_celery.py # 预期输出:所有测试通过,显示绿色成功信息 ``` #### Q11: 生产环境Redis安全注意事项? **A**: 安全配置清单: - [x] 设置强密码 - [x] 绑定到127.0.0.1或内网IP - [x] 禁用危险命令(FLUSHALL, FLUSHDB, CONFIG) - [x] 启用防火墙,只允许必要端口 - [x] 定期更新Redis版本 - [x] 配置日志监控 #### Q12: Redis性能调优参数有哪些? **A**: 关键调优参数: ```ini # 内存管理 maxmemory 1gb maxmemory-policy allkeys-lru # 持久化优化 save 900 1 save 300 10 save 60 10000 # 网络优化 tcp-keepalive 60 timeout 300 ``` ## 常规代码更新流程 当需要更新代码时,可以使用以下命令: ```bash # 退出虚拟环境 deactivate # 切换到项目目录 cd /var/www/diary-family # 1. 拉取远程最新代码(只获取,不合并) git fetch origin # 2. 硬重置本地分支到远程分支的最新版本(会覆盖所有本地未提交修改) # 注意:将 main 替换为你的分支名(如 master、dev 等) git reset --hard origin/main # 3. 激活虚拟环境 source venv/bin/activate # 4. 安装新依赖(如果有) pip install -r requirements.txt # 5. 收集静态文件(如果有静态文件更新) python manage.py collectstatic --noinput # 6. 重启服务 sudo supervisorctl restart all sudo systemctl restart nginx ``` ## 系统配置 在系统配置页面可以设置: - SMTP服务器信息 - 邮件发送时间 - 收件人邮箱 ## Celery 定时发送邮件任务配置 ### 1. 邮件配置设置 在系统配置页面设置完邮件信息后,还需要在 Django 项目的 settings.py 中添加基础邮件配置: ```python # 邮件基础配置 EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_PORT = 587 # 或根据你的 SMTP 服务器设置 EMAIL_USE_TLS = True # 或根据你的 SMTP 服务器设置 ``` ### 2. 启动 Celery Worker 和 Beat #### 开发环境 ```bash # 启动 Celery Worker celery -A diary_family worker -l info # 启动 Celery Beat(用于定时任务调度) celery -A diary_family beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler ``` #### 生产环境 建议使用 supervisor 管理 Celery 进程。创建两个 supervisor 配置文件: 1. **celery_worker.conf** ```ini [program:celery_worker] command=/path/to/venv/bin/celery -A diary_family worker -l info directory=/path/to/diary-family user=www-data group=www-data autostart=true autorestart=true stdout_logfile=/var/log/celery/worker.log stderr_logfile=/var/log/celery/worker_error.log ``` 2. **celery_beat.conf** ```ini [program:celery_beat] command=/path/to/venv/bin/celery -A diary_family beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler directory=/path/to/diary-family user=www-data group=www-data autostart=true autorestart=true stdout_logfile=/var/log/celery/beat.log stderr_logfile=/var/log/celery/beat_error.log ``` 启动 supervisor 服务: ```bash sudo supervisorctl reread sudo supervisorctl update sudo supervisorctl start celery_worker sudo supervisorctl start celery_beat ``` ### 3. 配置定时任务 系统使用 `django_celery_beat` 进行定时任务管理,支持两种方式配置: #### 方式一:通过 Django 管理后台(推荐) 1. 登录 Django 管理后台(/houtai) 2. 找到 **Periodic tasks**(周期性任务) 3. 点击 **Add** 按钮添加新任务 4. 配置任务: - **Name**: 任务名称(如:每日报告发送) - **Task (registered)**: 选择 `core.tasks.send_daily_report` - **Interval**: 设置执行间隔(如:每天) - **Enabled**: 勾选启用 5. 点击 **Save** 保存 #### 方式二:通过代码配置 在 `core/tasks.py` 中添加定时任务配置: ```python from celery import shared_task from django_celery_beat.models import PeriodicTask, IntervalSchedule # 创建或更新定时任务 def setup_daily_report_task(): # 创建每天执行的间隔 schedule, created = IntervalSchedule.objects.get_or_create( every=1, period=IntervalSchedule.DAYS, ) # 创建或更新定时任务 task, created = PeriodicTask.objects.update_or_create( name='Daily Report Task', defaults={ 'interval': schedule, 'task': 'core.tasks.send_daily_report', }, ) return task ``` 然后在 Django 启动时调用此函数(如在 `core/apps.py` 中)。 ### 4. 验证任务执行 - 查看 Celery 日志:`tail -f /var/log/celery/worker.log` - 检查邮件是否正常发送 - 在 Django 管理后台查看任务执行记录 ### 5. 日志文件不存在问题解决方法 如果在生产服务器上执行 `tail -f /var/log/celery/worker.log` 时提示 `No such file or directory`,请按照以下步骤解决: #### 步骤1:检查日志目录是否存在 ```bash # 检查日志目录是否存在 ls -la /var/log/celery/ # 如果目录不存在,创建目录 sudo mkdir -p /var/log/celery/ # 设置正确的权限(确保 Celery 进程用户有读写权限) sudo chown -R www-data:www-data /var/log/celery/ sudo chmod -R 755 /var/log/celery/ ``` #### 步骤2:检查 Supervisor 配置 确保 Supervisor 配置文件中指定的日志路径正确,并且 Celery 进程用户对该路径有读写权限。 #### 步骤3:重启 Supervisor 和 Celery ```bash sudo supervisorctl reread sudo supervisorctl update sudo supervisorctl restart celery_worker celery_beat ``` ### 5.1 日志文件查看指南 在生产环境中,有多种日志来源,了解每种日志的位置和查看方法非常重要: #### 5.1.1 Celery Worker 和 Beat 日志 这些日志由 Celery 进程产生,需要先创建日志目录: ```bash # 创建日志目录 sudo mkdir -p /var/log/celery/ # 设置权限 sudo chown -R www-data:www-data /var/log/celery/ sudo chmod -R 755 /var/log/celery/ ``` 查看日志: ```bash # 实时查看 Worker 日志 tail -f /var/log/celery/worker.log # 实时查看 Beat 日志 tail -f /var/log/celery/beat.log # 查看最近50行 tail -n 50 /var/log/celery/worker.log # 搜索错误信息 grep -i error /var/log/celery/worker.log # 搜索特定任务 grep -i "generate_daily_pdf_report" /var/log/celery/worker.log ``` #### 5.1.2 测试脚本日志 运行测试脚本时,日志会同时输出到控制台和文件: ```bash # 运行测试脚本(输出到控制台) python test_redis_celery.py # 查看测试日志文件 tail -f /var/log/celery/test_redis_celery.log # 运行测试并保存到文件 python test_redis_celery.py 2>&1 | tee /var/log/celery/test_output.log ``` 测试脚本日志内容示例: ``` 2024-01-15 10:30:00 | INFO | 开始测试Redis连接... 2024-01-15 10:30:01 | SUCCESS | Redis连接测试通过! 2024-01-15 10:30:02 | INFO | 开始测试Celery与Redis集成... 2024-01-15 10:30:03 | SUCCESS | Celery与Redis集成测试通过! ``` #### 5.1.3 Redis 日志 Redis 的日志通常在系统日志中: ```bash # 查看 Redis 系统日志 sudo journalctl -u redis-server -f # 查看 Redis 错误日志 sudo tail -f /var/log/redis/redis-server.log # 查看所有 Redis 相关日志 sudo grep -i redis /var/log/syslog ``` #### 5.1.4 Django 应用日志 ```bash # 查看 Django 应用日志 tail -f /path/to/diary-family/logs/app.log # 查看 Gunicorn 日志 sudo tail -f /var/log/gunicorn/access.log sudo tail -f /var/log/gunicorn/error.log ``` #### 5.1.5 Nginx 日志 ```bash # 查看访问日志 sudo tail -f /var/log/nginx/access.log # 查看错误日志 sudo tail -f /var/log/nginx/error.log ``` #### 5.1.6 综合日志查看脚本 创建一个综合日志查看脚本: ```bash #!/bin/bash # save as: /usr/local/bin/view-all-logs echo "=== Celery Worker Log ===" tail -n 20 /var/log/celery/worker.log echo -e "\n=== Celery Beat Log ===" tail -n 20 /var/log/celery/beat.log echo -e "\n=== Redis Server Log ===" sudo tail -n 20 /var/log/redis/redis-server.log echo -e "\n=== Nginx Error Log ===" sudo tail -n 20 /var/log/nginx/error.log ``` 使用方法: ```bash # 给脚本添加执行权限 sudo chmod +x /usr/local/bin/view-all-logs # 运行脚本 view-all-logs ``` #### 5.1.7 日志轮转配置 为防止日志文件过大,配置日志轮转: 创建 `/etc/logrotate.d/celery-app`: ``` /var/log/celery/*.log { daily missingok rotate 14 compress delaycompress notifempty create 0640 www-data www-data sharedscripts postrotate supervisorctl restart celery_worker celery_beat > /dev/null 2>&1 || true endscript } ``` 启用配置: ```bash sudo logrotate -f /etc/logrotate.d/celery-app ``` #### 5.1.8 日志查看常见问题 **问题1:日志文件权限被拒绝** ```bash # 检查权限 ls -la /var/log/celery/ # 如果权限不对,重新设置 sudo chown -R www-data:www-data /var/log/celery/ sudo chmod -R 755 /var/log/celery/ ``` **问题2:日志文件不存在** ```bash # 检查目录是否存在 ls -la /var/log/ | grep celery # 如果不存在,创建目录 sudo mkdir -p /var/log/celery/ sudo chown www-data:www-data /var/log/celery/ ``` **问题3:日志不更新** ```bash # 检查进程是否运行 ps aux | grep celery # 检查文件是否被锁定 sudo lsof /var/log/celery/worker.log # 检查磁盘空间 df -h /var/log/ ``` **问题4:如何清理旧日志** ```bash # 删除7天前的日志 find /var/log/celery/ -name "*.log.*.gz" -mtime +7 -delete # 清空当前日志文件(谨慎使用) sudo truncate -s 0 /var/log/celery/worker.log ``` ### 6. 试运行周期任务 当设置一个周期任务后,您可以通过以下方式试运行任务,而不需要等待到指定的时间: #### 方式1:通过 Django 管理后台 1. 登录 Django 管理后台(/houtai) 2. 找到 **Periodic tasks**(周期性任务) 3. 选择您创建的任务 4. 点击页面底部的 **Run Task** 按钮立即执行任务 #### 方式2:通过命令行 ```bash # 直接调用任务函数(同步执行) python manage.py shell -c "from core.tasks import generate_daily_pdf_report; generate_daily_pdf_report()" # 或者使用 Celery 命令行工具 celery -A diary_family call core.tasks.generate_daily_pdf_report ``` #### 方式3:使用测试脚本 项目提供了多个测试脚本,用于验证不同功能: 1. **Celery任务测试**: ```bash # 测试Celery任务执行 python test_celery.py ``` 2. **Redis和Celery集成测试**(生产环境推荐): ```bash # 测试Redis连接、Celery集成和性能 python test_redis_celery.py ``` 3. **Redis连接测试**(快速验证): ```bash # 仅测试Redis连接 python -c "import redis; r = redis.Redis(host='localhost', port=6379); print('Redis连接成功' if r.ping() else '连接失败')" ``` ### 7. 常见错误和解决方法 #### 错误1:日志文件不存在 **错误信息**:`tail: cannot open '/var/log/celery/worker.log' for reading: No such file or directory` **解决方法**: - 按照步骤5中的说明创建日志目录并设置正确权限 - 检查 Supervisor 配置中的日志路径是否正确 - 重启 Supervisor 和 Celery 服务 #### 错误2:Celery 无法连接到 Redis **错误信息**:`redis.exceptions.ConnectionError: Error 111 connecting to localhost:6379. Connection refused.` **解决方法**: 1. **检查Redis服务状态**: ```bash sudo systemctl status redis-server ``` 2. **如果Redis未运行,启动服务**: ```bash sudo systemctl start redis-server sudo systemctl enable redis-server ``` 3. **检查Redis配置**: - 确保Redis配置文件 `/etc/redis/redis.conf` 中 `bind` 设置为 `127.0.0.1` - 检查是否有防火墙阻止连接:`sudo ufw status` - 检查端口是否被占用:`sudo netstat -tlnp | grep 6379` 4. **测试Redis连接**: ```bash # 测试基本连接 redis-cli ping # 如果设置了密码,使用密码连接 redis-cli -a your_password ping ``` 5. **检查Celery配置**: - 确保 `settings.py` 中的 `CELERY_BROKER_URL` 和 `CELERY_RESULT_BACKEND` 配置正确 - 如果Redis有密码,URL格式应为:`redis://:password@localhost:6379/0` 6. **详细排查**: - 查看Redis日志:`sudo journalctl -u redis-server -f` - 查看Celery日志:`tail -f /var/log/celery/worker.log` - 参考 [Redis服务器部署](#redis服务器部署必需) 章节进行完整配置 **注意**:如果这是新部署的环境,请确保已按照 [Redis服务器部署](#redis服务器部署必需) 章节完整安装和配置Redis。 #### 错误3:任务执行失败 **错误信息**:`Task core.tasks.generate_daily_pdf_report[xxx] raised unexpected: Exception(...)` **解决方法**: - 查看详细日志:`tail -f /var/log/celery/worker.log` - 检查任务代码中的错误 - 确保所有依赖库都已正确安装 - 检查相关服务(如数据库、Redis)是否正常运行 #### 错误4:PDF 生成失败 **错误信息**:`WeasyPrint库不可用,无法生成PDF报告` **解决方法**: - 安装 WeasyPrint 库:`pip install weasyprint` - 对于 Ubuntu 系统,可能需要安装系统依赖: ```bash sudo apt-get install -y libpango-1.0-0 libpangoft2-1.0-0 ``` ### 8. 常见问题排查 1. **任务不执行** - 检查 Celery worker 和 beat 是否正常运行 - 检查 Redis 服务是否正常 - 检查任务是否已启用 - 检查系统时间是否正确 2. **邮件发送失败** - 检查 SMTP 服务器配置是否正确 - 检查邮箱账号密码是否正确 - 检查收件人邮箱格式是否正确 - 查看 Celery 日志中的错误信息 3. **任务执行延迟** - 检查系统负载是否过高 - 考虑增加 Celery worker 数量 - 检查 Redis 性能 ### 6. 生产环境优化建议 #### Redis相关优化: 1. **使用独立Redis实例**:为Celery专门配置一个Redis实例,避免与其他应用共享 2. **Redis性能调优**: - 根据服务器内存调整 `maxmemory` 配置 - 使用合适的内存淘汰策略(如 `allkeys-lru`) - 启用持久化确保数据安全 3. **Redis监控**: - 配置Prometheus + Grafana监控Redis性能 - 设置内存使用告警 - 监控连接数和慢查询 #### Celery相关优化: 1. **Worker配置**: - 配置合适的worker数量(建议:CPU核心数 × 2) - 使用prefork或gevent模式根据任务类型选择 - 设置合理的任务超时时间 2. **任务管理**: - 定期清理Celery任务结果 - 配置任务重试机制 - 使用任务优先级队列 3. **监控工具**: - 启用Celery监控工具(如Flower) - 配置任务执行统计 - 设置任务失败告警 #### 系统级优化: 1. **资源隔离**:为Celery worker和Redis分配独立的系统资源 2. **日志管理**:配置集中式日志收集(如ELK Stack) 3. **备份策略**:定期备份Redis数据和任务结果 4. **高可用方案**:考虑使用Redis Sentinel或Redis Cluster实现高可用 ## 定时生成PDF文件配置 除了定时发送邮件外,系统还支持单独定时生成PDF文件,便于在服务器上保存历史报告。 ### 1. 配置定时生成PDF任务 #### 方式一:通过 Django 管理后台(推荐) 1. 登录 Django 管理后台(/houtai) 2. 找到 **Periodic tasks**(周期性任务) 3. 点击 **Add** 按钮添加新任务 4. 配置任务: - **Name**: 任务名称(如:每日PDF报告生成) - **Task (registered)**: 选择 `core.tasks.generate_daily_pdf_report` - **Interval**: 设置执行间隔(如:每天) - **Enabled**: 勾选启用 5. 点击 **Save** 保存 #### 方式二:通过代码配置 在 `core/tasks.py` 中添加定时任务配置: ```python from celery import shared_task from django_celery_beat.models import PeriodicTask, IntervalSchedule # 创建或更新PDF生成定时任务 def setup_daily_pdf_task(): # 创建每天执行的间隔 schedule, created = IntervalSchedule.objects.get_or_create( every=1, period=IntervalSchedule.DAYS, ) # 创建或更新定时任务 task, created = PeriodicTask.objects.update_or_create( name='Daily PDF Generation Task', defaults={ 'interval': schedule, 'task': 'core.tasks.generate_daily_pdf_report', }, ) return task ``` 然后在 Django 启动时调用此函数(如在 `core/apps.py` 中)。 ### 2. PDF文件存储位置 生成的PDF文件默认存储在项目的 `reports` 目录下,命名格式为 `report_YYYY-MM-DD.pdf`。 可以在 `settings.py` 中修改存储位置: ```python # Reports files configuration REPORTS_URL = '/reports/' REPORTS_ROOT = BASE_DIR / 'reports' # 可以修改为其他路径 ``` ### 3. 验证PDF生成任务 - 查看 Celery 日志:`tail -f /var/log/celery/worker.log` - 检查PDF文件是否生成:`ls -la /path/to/diary-family/reports/` - 在 Django 管理后台查看任务执行记录 ### 4. 常见问题排查 1. **PDF生成失败** - 检查 WeasyPrint 库是否正确安装:`pip list | grep weasyprint` - 检查系统字体是否完整:PDF生成需要系统字体支持 - 查看 Celery 日志中的错误信息 2. **任务执行但没有生成文件** - 检查 `REPORTS_ROOT` 目录权限:确保 Celery 进程有写入权限 - 检查磁盘空间是否充足 - 查看 Celery 日志中的详细信息 3. **PDF内容不完整** - 检查模板文件 `core/templates/core/report_pdf.html` 是否完整 - 确保所有依赖的 CSS 和图像资源都能正常访问 ## 邮件功能测试 项目提供了两个专门的测试脚本,用于验证邮件发送功能是否正常工作: ### 1. 基础邮件测试(test_email.py) 用于测试直接邮件发送功能,验证SMTP配置是否正确。 #### 测试内容 - ✅ 邮件配置验证 - ✅ SMTP连接测试 - ✅ 发送简单文本邮件 - ✅ 发送HTML邮件(带附件) - ✅ 邮件发送性能测试 #### 运行方式 ```bash # 运行基础邮件测试 python test_email.py ``` #### 测试结果说明 - 所有测试通过:邮件系统配置正确,可以正常工作 - 3项以上通过:邮件系统基本可用,部分功能可能需要优化 - 少于3项通过:邮件系统存在严重问题,需要检查配置 ### 2. Celery异步邮件测试(test_celery_email.py) 用于测试通过Celery异步发送邮件的功能,验证整个异步任务链是否正常。 #### 测试内容 - ✅ Celery邮件配置验证 - ✅ Celery Worker状态检查 - ✅ Celery异步邮件任务执行 - ✅ 同步发送测试邮件(用于对比) #### 运行方式 ```bash # 运行Celery异步邮件测试 python test_celery_email.py ``` #### 测试结果说明 - 所有测试通过:Celery邮件功能正常 - 2项以上通过:Celery邮件功能基本可用 - 少于2项通过:存在严重问题,需要检查配置 ### 3. 常见问题排查 #### 测试失败时的检查步骤 1. **检查SMTP配置** ```bash # 查看Django邮件配置 python -c "import os; os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'diary_family.settings'); import django; django.setup(); from django.conf import settings; print('EMAIL_HOST:', getattr(settings, 'EMAIL_HOST', None)); print('EMAIL_PORT:', getattr(settings, 'EMAIL_PORT', None)); print('EMAIL_HOST_USER:', getattr(settings, 'EMAIL_HOST_USER', None))" ``` 2. **检查Redis服务** ```bash sudo systemctl status redis-server redis-cli ping ``` 3. **检查Celery Worker状态** ```bash # 查看Celery Worker状态 celery -A diary_family status # 如果Worker未运行,启动它 celery -A diary_family worker -l info ``` 4. **查看日志文件** ```bash # 查看邮件测试日志 tail -f /var/log/celery/test_email.log tail -f /var/log/celery/test_celery_email.log # 查看Celery日志 tail -f /var/log/celery/worker.log tail -f /var/log/celery/beat.log ``` 5. **验证网络连通性** ```bash # 测试SMTP服务器连通性 telnet smtp.example.com 587 # 测试DNS解析 nslookup smtp.example.com ``` #### 常见错误及解决方案 | 错误信息 | 可能原因 | 解决方案 | |---------|---------|---------| | 连接被拒绝 | SMTP服务器地址/端口错误 | 检查SMTP配置,确认服务器地址和端口 | | 认证失败 | 用户名或密码错误 | 检查邮箱账号和密码,确认是否开启了SMTP服务 | | Celery连接失败 | Redis未运行或配置错误 | 检查Redis服务状态,验证CELERY_BROKER_URL配置 | | 任务超时 | Worker未运行或任务执行时间过长 | 启动Celery Worker,检查任务代码 | ## Celery 监控(可选) 使用 Flower 监控 Celery 任务: ```bash # 安装 Flower pip install flower # 启动 Flower celery -A diary_family flower --port=5555 ``` 访问 http://your-server:5555 查看任务监控界面。 ## API接口文档 系统提供RESTful API接口,用于外部客户端提交汇总记录。 ### 1. 汇总记录提交API 用于外部客户端(如监控脚本、自动化任务)向系统提交汇总记录。 #### 请求信息 - **URL**: `/api/v1/summary/submit/` - **方法**: `POST` - **Content-Type**: `application/x-www-form-urlencoded` 或 `multipart/form-data` #### 请求参数 | 参数名 | 类型 | 必填 | 说明 | |-------|------|------|------| | content | string | 是 | 汇总记录内容,最大长度不限 | #### 响应格式 **成功响应** (HTTP 200): ```json { "success": true, "message": "提交成功", "id": 123 } ``` **失败响应** (HTTP 400/500): ```json { "success": false, "message": "错误信息描述" } ``` #### 调用示例 ```bash # 使用 curl 提交汇总记录 curl -X POST http://your-server/api/v1/summary/submit/ \ -d "content=这是自动提交的汇总内容" # Python requests 调用示例 import requests url = "http://your-server/api/v1/summary/submit/" data = { "content": "监控报告:系统运行正常,CPU使用率15%,内存使用率42%" } response = requests.post(url, data=data) result = response.json() print(result) ``` #### 客户端自动提交示例 创建一个Python脚本用于自动提交系统监控数据: ```python #!/usr/bin/env python3 # submit_summary.py import socket import psutil import requests from datetime import datetime def get_system_info(): """获取系统基本信息""" cpu_percent = psutil.cpu_percent(interval=1) memory = psutil.virtual_memory() disk = psutil.disk_usage('/') return { 'cpu': cpu_percent, 'memory': memory.percent, 'disk': disk.percent } def submit_summary(content): """提交汇总记录到家庭日报系统""" url = "http://your-server/api/v1/summary/submit/" try: response = requests.post(url, data={'content': content}, timeout=10) result = response.json() if result['success']: print(f"提交成功,记录ID: {result['id']}") else: print(f"提交失败: {result['message']}") except Exception as e: print(f"请求异常: {str(e)}") if __name__ == "__main__": info = get_system_info() timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S') content = f"[系统监控 {timestamp}] CPU使用率: {info['cpu']}%, 内存使用率: {info['memory']}%, 磁盘使用率: {info['disk']}%" submit_summary(content) ``` #### 注意事项 1. **数据验证**:API仅接受以下条件的记录: - 分类必须为"定期" - 发言人必须为"机器人" - 内容不能为空 2. **来源自动生成**:系统会自动获取客户端的主机名和IP地址,填充到source字段。 3. **日期自动设置**:记录日期自动设置为提交时的日期。 4. **错误处理**:如果分类或发言人不存在,API会返回错误信息。 ### 2. 初始化必需数据 在使用API提交功能前,需要确保数据库中存在以下数据: #### 方法一:Django Shell初始化 ```bash python manage.py shell -c " from core.models import SummaryCategory, FamilyMember # 创建'定期'分类(如果不存在) category, created = SummaryCategory.objects.get_or_create(name='定期') if created: print('创建分类: 定期') else: print('分类已存在: 定期') # 创建'机器人'发言人(如果不存在) speaker, created = FamilyMember.objects.get_or_create(name='机器人') if created: print('创建发言人: 机器人') else: print('发言人已存在: 机器人') print('初始化完成') " ``` #### 方法二:Django Admin后台创建 1. 登录后台管理:`/houtai` 2. 在 **汇总分类** 中添加名为"定期"的分类 3. 在 **家庭成员** 中添加名为"机器人"的成员 ### 3. 常见问题排查 #### 问题1:提交返回"分类 '定期' 不存在" **解决方法**:在数据库中创建该分类(见上方初始化方法) #### 问题2:提交返回"发言人 '机器人' 不存在" **解决方法**:在数据库中创建该发言人(见上方初始化方法) #### 问题3:提交返回"内容不能为空" **解决方法**:确保请求中包含 `content` 参数且不为空 #### 问题4:返回HTTP 405错误 **解决方法**:确认使用的是POST方法,不是GET方法 ## 注意事项 1. 定期备份数据库 2. 生产环境建议使用PostgreSQL或MySQL数据库 3. 定期清理过期数据 4. 保持依赖包更新 5. 定期运行邮件测试脚本,确保邮件功能正常 ## 许可证 MIT License