Linux PHP-FPM日志切割策略
一 推荐方案 logrotate
- 使用系统自带的 logrotate 对 PHP-FPM 的 access.log 与 error.log 进行按日/按大小轮转、压缩与保留管理,稳定可靠且易于维护。
- 建议将配置文件放在 /etc/logrotate.d/php-fpm,内容示例(按日轮转,保留 7 天,压缩,空文件不轮转,轮转后让 FPM 重新打开日志):
/var/log/php-fpm/*.log {
daily
missingok
rotate 7
compress
delaycompress
notifempty
create 640 www-data adm
sharedscripts
postrotate
if [ -f /var/run/php-fpm/php-fpm.pid ]; then
kill -USR1 $(cat /var/run/php-fpm/php-fpm.pid 2>/dev/null) 2>/dev/null || true
fi
endscript
}
- 关键参数说明:
- daily/weekly/monthly:轮转周期;也可用 size 100M 按大小触发。
- rotate N:保留 N 个归档。
- compress / delaycompress:压缩旧日志;delaycompress 常用于让最新一份保持未压缩以便读取。
- missingok / notifempty:文件缺失不报错;空文件不轮转。
- create 640 www-data adm:轮转后新建日志文件的权限与属主属组(按实际环境调整)。
- sharedscripts / postrotate … kill -USR1:所有匹配日志处理完后执行一次通知;向 PHP-FPM master 发送 USR1 让其重新打开日志文件,避免继续写入已重命名的旧文件。
二 手动或脚本切割方案
- 在无法使用 logrotate 或需自定义逻辑时,可用简单脚本配合 cron 执行:
#!/usr/bin/env bash
set -e
LOG_DIR="/var/log/php-fpm"
DATE=$(date -d "1 day ago" +"%Y%m%d")
cd "$LOG_DIR" || exit 1
[ -f php-fpm.log ] && mv php-fpm.log "php-fpm.log_${DATE}"
[ -f slow.log ] && mv slow.log "slow.log_${DATE}"
# 通知 PHP-FPM 重新打开日志
if [ -f /var/run/php-fpm/php-fpm.pid ]; then
kill -USR1 "$(cat /var/run/php-fpm/php-fpm.pid 2>/dev/null)" 2>/dev/null || true
fi
0 0 * * * /usr/local/bin/cut_php_fpm_logs.sh
- 要点:切割后必须通知 PHP-FPM master 重新打开日志(发送 USR1),否则进程会继续写入已被重命名的旧文件。
三 关键注意事项
- 信号选择:多数实践使用 USR1 触发日志重新打开;个别资料使用 USR2,两者在不同版本或发行版上均可见,关键是让 PHP-FPM 重新打开日志文件,建议先在测试环境验证所用信号是否有效。
- 路径与权限:确认 php-fpm.conf / www.conf 中的 error_log、access.log 路径与 logrotate 中一致;新建日志文件的 owner/group 与 mode 要与实际运行用户匹配(如 www-data:adm 或 root:adm),避免写入失败。
- 触发与测试:
- 手动测试:执行 logrotate -vf /etc/logrotate.d/php-fpm(必要时用 -f 强制执行)。
- 自动执行:系统通常通过 /etc/cron.daily/logrotate 每日运行,无需额外配置 cron。
- 压缩策略:使用 compress 与 delaycompress 可节省磁盘并保持最近一份可读性,便于排障。
四 日志体量优化建议
- 适度提升日志级别:在 php.ini 或 www.conf 中调整 error_reporting / log_errors,减少 NOTICE/DEBUG 等大量低级别日志;必要时仅记录 WARNING/ERROR。
- 慢请求日志:仅在排障时临时开启 slowlog,并配合合理的 request_slowlog_timeout,避免长期写入导致体量激增。
- 定期审计与清理:结合 rotate N 与监控告警,避免磁盘被历史日志占满。