php 8.1自身不支持日志轮转,需依赖logrotate配合kill -usr2信号通知php-fpm平滑重开日志句柄;配置前须确认error_log路径和php-fpm worker用户(如www-data),并确保postrotate中信号发送正确、权限匹配、sharedscripts成对使用,否则日志仍写入旧文件。

PHP 8.1 自身不支持日志轮转,必须靠 logrotate 配合 USR2 信号通知 php-fpm 重开日志文件句柄;漏掉 postrotate 或信号发错,日志就还在往旧文件写,轮转等于白配。
确认 PHP 错误日志路径和 php-fpm 进程用户
先查清楚两个关键信息,否则后续所有配置都会失效:
-
error_log在php.ini或www.conf里设的是什么?常见路径如/var/log/php-fpm/www-error.log或/var/log/php/error.log - php-fpm worker 进程以谁的身份运行?用
ps aux | grep php-fpm看 USER 列,通常是www-data(Debian/Ubuntu)或nginx(CentOS/RHEL) - 对应的 pid 文件在哪?
/var/run/php/php8.1-fpm.pid是典型路径,但得ls /var/run/php/实际确认,别硬套版本号
编写 /etc/logrotate.d/php81 的最小可用配置
创建配置文件后,内容必须包含权限、轮转逻辑和信号通知三要素。以下是最简但可上线的模板:
/var/log/php-fpm/www-error.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 640 www-data adm
sharedscripts
postrotate
if [ -f /var/run/php/php8.1-fpm.pid ]; then
kill -USR2 $(cat /var/run/php/php8.1-fpm.pid)
fi
endscript
}
注意点:
-
create 640 www-data adm中的用户组必须匹配 php-fpm worker 用户,否则新日志无法写入,错误会静默丢弃 -
sharedscripts和postrotate必须成对出现,否则多个日志文件轮转时可能重复 reload,引发短时请求失败 - 不要用
systemctl reload php8.1-fpm替代kill -USR2:前者是重启进程,后者才是平滑重开日志,无请求中断
验证配置是否生效的三步检查法
别等 cron 自动跑,手动验证才能避开“以为配好了其实没生效”的坑:
- 语法检查:
logrotate -d /etc/logrotate.d/php81—— 看输出里有没有error:或warning: - 强制轮转一次:
logrotate -f /etc/logrotate.d/php81—— 检查旧日志是否被重命名(如www-error.log.1),新日志是否生成且权限正确 - 确认 php-fpm 是否切换了文件句柄:
lsof -p $(cat /var/run/php/php8.1-fpm.pid) | grep www-error—— 轮转后应只显示新文件名,如果还挂着.1就说明 USR2 没起作用
容器环境或 error_log = syslog 的特殊处理
这两种情况 logrotate 完全无效,必须换思路:
- 若 PHP 运行在 Docker 中,且日志输出到 stdout/stderr(推荐做法),轮转由容器运行时控制:
docker run --log-opt max-size=10m --log-opt max-file=3,PHP 自身不写文件 - 若
error_log = syslog,logrotate 对/dev/log无能为力;得改用 rsyslog 或 systemd-journald 的原生轮转机制,比如在/etc/rsyslog.d/50-php.conf里配$FileCreateMode 0640和$MaxFileSize - 若 Nginx 用
fastcgi_param PHP_VALUE "error_log=/var/log/nginx/php-error.log"动态指定路径,那这个/var/log/nginx/php-error.log才是 logrotate 的目标,且postrotate应该 reload nginx,不是 php-fpm
最容易被忽略的是:logrotate 不读取 PHP 配置,它只认你写的路径;而 php-fpm 收到 USR2 后是否真能打开新日志,取决于那个路径的父目录权限、SELinux 上下文(CentOS)、以及是否存在同名 symlink 指向不可写位置——这些都得在 postrotate 后手动验证一次。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











