标准 PHP-FPM 原生配置中没有 log_rotation 参数,避免磁盘写满需依赖 Linux 系统自带的 logrotate 工具配合信号通知。适用所有主流 Linux 发行版,风险边界在于配置错误可能导致日志丢失或进程无法重新打开日志文件。
先说结论:PHP-FPM 自身不具备自动日志轮转功能,必须通过系统 logrotate 配置实现。
- 先确认:查找 PHP-FPM 日志实际存储路径
- 先准备:编写
/etc/logrotate.d/下的轮转配置文件 - 验收:手动执行轮转并检查新日志文件是否生成
命令速用版
以下配置片段可直接放入 /etc/logrotate.d/php-fpm,注意修改日志路径与实际环境一致。
/var/log/php-fpm/*.log {
daily
rotate 7
missingok
notifempty
compress
delaycompress
sharedscripts
postrotate
if [ -f /var/run/php-fpm/php-fpm.pid ]; then
kill -USR1 `cat /var/run/php-fpm/php-fpm.pid`
fi
endscript
}为什么会这样
PHP-FPM 进程启动后会长期持有日志文件的句柄,单纯移动或清空文件不会释放磁盘空间。
系统 logrotate 默认只是重命名日志文件,若不通知 PHP-FPM 主进程重新打开文件句柄,新日志会继续写入旧文件名对应的句柄中,导致磁盘空间无法回收。发送 SIGUSR1 信号是告诉 PHP-FPM 重新初始化日志文件的标准动作。
分步处理
步骤 1:确认日志路径
查看 php-fpm.conf 或池配置文件(如 www.conf)中的 php_admin_value[error_log] 设置,或使用命令 ps aux | grep php-fpm 查看启动参数。
步骤 2:创建轮转配置
在 /etc/logrotate.d/ 目录下新建文件,内容参考“命令速用版”中的代码块。确保 postrotate 中的 PID 文件路径与实际一致,常见路径包括 /var/run/php-fpm/php-fpm.pid 或 /run/php-fpm/php-fpm.pid。
步骤 3:测试配置语法
执行 logrotate -d /etc/logrotate.d/php-fpm 检查配置是否有语法错误,确认无报错后再正式启用。
怎么验证是否生效
手动强制执行一次轮转:logrotate -f /etc/logrotate.d/php-fpm。
检查日志目录,确认原日志文件已被重命名(如带有 .1 或日期后缀),且新生成了空的当前日志文件。
观察磁盘空间:df -h,确认空间不再持续增长。
常见坑
1. PID 文件路径错误:不同发行版 PID 文件位置不同,配置错误会导致信号发送失败,日志继续写入旧文件。
2. 权限不足:logrotate 通常由 root 运行,但需确保其有权限读取 PID 文件并发送信号给 PHP-FPM 进程。
3. 压缩配置冲突:若开启 compress 但未设 delaycompress,可能导致正在写入的日志被立即压缩而丢失部分内容。
常见问题
PHP-FPM 配置里有 log_rotation 开关吗?
标准上游版本中没有该参数,部分面板封装的功能实际是调用了系统 logrotate。
日志轮转后磁盘空间没释放怎么办?
通常是因为未发送 SIGUSR1 信号,进程仍持有旧文件句柄,检查 postrotate 脚本是否执行成功。
slowlog 需要单独配置轮转吗?
需要,slowlog 路径通常与 error_log 不同,需在 logrotate 配置中额外添加对应路径规则。
参考来源
- PHP Manual: Install FPM Configuration - https://www.php.net/manual/en/install.fpm.configuration.php
- Linux Man Pages: logrotate(8) - https://man7.org/linux/man-pages/man8/logrotate.8.html