php应用日志自动清理应由部署脚本统一控制,优先在部署完成、服务重启后执行find命令按时间清理共享目录下日志,避免运行时删除、路径错配或误删;laravel等框架推荐配合logrotate,ci中无需清理构建机日志。

部署时自动清理旧日志的常见做法
PHP 应用本身不提供日志自动清理机制,必须靠外部手段介入部署流程。最稳妥的方式不是在 PHP 运行时调用 unlink() 或 shell_exec('rm -f ...'),而是把清理逻辑交给部署脚本统一控制——避免权限、路径、时机错乱导致日志误删或残留。
- 清理动作应放在部署完成、新代码已生效、服务已重启之后(否则可能删掉正在写入的日志文件)
- 推荐用
find命令按修改时间筛选,比如保留最近 7 天:find /var/log/myapp/ -name "*.log" -mtime +7 -delete - 若用 Laravel 等框架,其
logrotate配置更可靠,但需确保部署脚本不覆盖或忽略该配置 - 禁止在
composer install前清理日志目录——某些框架(如 Symfony)会在cache:clear时尝试读取日志目录,目录不存在会报UnexpectedValueException
用 deployer.php 实现日志清理的典型写法
Deployer 是 PHP 生态中较常用的部署工具,它的任务链天然适合插入清理步骤。关键点在于:不能直接写 run('rm -rf {{release_path}}/storage/logs/*'),因为日志通常不在 release 目录下,而是在共享目录(shared_path)里。
- 确认日志路径是否共享:Laravel 默认是
{{shared_path}}/storage/logs,Docker 环境可能是挂载卷/var/log/php-app - 在
deploy:symlink后加自定义任务:after('deploy:symlink', 'app:cleanup-logs') - 清理任务内建议用
run("find {{shared_path}}/storage/logs -name '*.log' -mtime +3 -delete 2>/dev/null || true"),加|| true防止某次无匹配文件时整个部署中断 - 如果日志由 Nginx/Apache 生成(如
access.log),清理必须在系统级进行,不能依赖 PHP 部署脚本
systemd 服务中配合 logrotate 的注意事项
当 PHP 应用以 systemd 服务运行(如 php-fpm 或自定义 worker),日志清理不应由部署流程承担,而应交由 logrotate 管理。但部署脚本仍需检查它是否生效——很多人改了应用路径却忘了更新 /etc/logrotate.d/ 下的配置。
- 检查
logrotate是否启用:systemctl list-timers | grep logrotate - 确认配置文件中
create指令权限匹配 PHP 进程用户(如www-data),否则 rotate 后新日志无法写入 - 部署时若修改了日志路径(如从
/var/log/app.log改为/var/log/app/v2.log),必须同步更新logrotate配置,否则旧路径日志无人处理 -
postrotate中若执行kill -USR1通知服务重新打开日志,要确保该信号被正确处理(例如 php-fpm 支持,但某些自研 daemon 可能不支持)
CI/CD 流水线里清理日志的边界问题
GitHub Actions、GitLab CI 等环境容易误以为“构建机上的日志”需要清理——其实不需要。这些机器上的 storage/logs 是临时产物,容器销毁即消失。真正要清理的是目标服务器上的历史日志。
立即学习“PHP免费学习笔记(深入)”;
- CI 流程中执行
php artisan log:clear是无效操作,该命令只清当前进程所在目录下的日志,而 CI 构建目录不会同步到线上 - 如果使用 rsync 部署,注意排除日志目录:
--exclude='storage/logs/',否则可能把本地空目录覆盖线上日志目录 - Ansible 部署时,用
file模块删文件比用shell更安全,但同样要指定path为远程真实日志路径,而非 playbook 本地路径 - 任何清理操作前,建议先
ls -lt {{log_path}} | head -5打印最新几个日志文件,便于事后核查是否删错
日志清理看着简单,实际最容易出问题的是路径判断和执行时机——同一个 storage/logs 在本地开发、CI 构建、线上共享目录、容器卷挂载中可能指向完全不同的物理位置。每次部署前,花 10 秒确认当前环境的真实日志落盘路径,比写十个“通用清理脚本”都管用。











