PHP框架日志不能直接用rm -rf logs/*,因当前日志文件被进程占用,删除会导致“Text file busy”、写入失败或权限异常;应使用logrotate等系统级工具安全轮转。
PHP框架日志文件为什么不能直接用 rm -rf logs/*?
多数 PHP 框架(Laravel、ThinkPHP、Symfony)默认使用轮转日志(如 laravel.log + laravel-2024-06-15.log),且当前日志文件正被 file_put_contents 或 Monolog 持有写入句柄。直接 rm 可能触发「Text file busy」错误,或导致新日志写入失败、丢失。
- Linux 下删除正在被进程打开的文件,inode 未立即释放,磁盘空间不回收
- 部分框架(如 Laravel)在日志轮转时依赖文件存在性判断,删空目录可能干扰
RotatingFileHandler行为 - 误删正在写的
laravel.log后,框架可能静默创建新文件但权限异常(尤其配合www-data用户时)
Laravel 日志按天清理:用 logrotate 而非脚本遍历
硬编码循环 find logs/ -name "*.log" -mtime +7 -delete 风险高——它不区分主日志和归档日志,且无法保证轮转原子性。推荐系统级 logrotate,与框架解耦、更可靠。
- 配置示例:
/var/www/myapp/storage/logs/*.log { daily missingok rotate 30 compress delaycompress notifempty create 644 www-data www-data sharedscripts postrotate if [ -f /var/run/php/php8.1-fpm.pid ]; then kill -USR1 `cat /var/run/php/php8.1-fpm.pid` fi endscript } -
sharedscripts+postrotate确保所有日志轮转完成后才通知 FPM 重载句柄 - 避免在 Laravel 的
Kernel.php中写Artisan::call('log:clear')—— 该命令只清空当前laravel.log,不处理历史归档
ThinkPHP 日志路径与清理边界要手动对齐
ThinkPHP 默认日志路径是 runtime/log/,但具体子目录由 app_debug 和 log.level 决定(如 runtime/log/202406/ 或 runtime/log/error/)。盲目清理整个 log/ 可能误删正在使用的会话或缓存临时文件。