HCRM博客

CentOS下PHP-FPM多站点日志分离与error_log配置指南

CentOS PHP-FPM多池日志分离,error_log按站点切割配置

线上跑着十几个站点的服务器,一到排障就头大:所有PHP报错全挤在/var/log/php-fpm/error.log里,grep半天也揪不出是哪台虚拟主机在闹脾气。把日志按站点切开,既能缩短定位时间,又能避免单个刷屏站点把磁盘打满。下面这套办法,在CentOS Stream 8、AlmaLinux 9实测通过,php-fpm版本8.1,同样适用于7.4,老掉牙的5.4也能照抄,只要注意路径差别。

CentOS下PHP-FPM多站点日志分离与error_log配置指南-图1

为什么要做多池日志分离

默认的php-fpm.conf只启了一个[www]池,所有站点的请求混在一个池里,错误自然写进同一个文件。想分账,就得给每个站点单独开池,再让各池把日志写到自己的目录。好处立竿见影:

1. 排障时直接tail对应站点的error.log,再也不用awk过滤域名。

日志轮转可以按站点维度做,不同业务保留周期不同,不怕“一刀切”。

某个池爆内存或IO,只影响它自己,别的站点稳如老狗。

配合ELK/Graylog采集,字段里自带pool名称,检索速度翻倍。

CentOS下PHP-FPM多站点日志分离与error_log配置指南-图2

前置准备:目录与权限

先给日志安个家,习惯放在/home/logs下,磁盘大就挂单独分区:

mkdir -p /home/logs/{siteA,siteB,siteC}/php

chown -R php-fpm:php-fpm /home/logs

chmod 750 /home/logs/*

SELinux开着就别忘打上下文:

CentOS下PHP-FPM多站点日志分离与error_log配置指南-图3

semanage fcontext -a -t httpdlogt "/home/logs(/.*)?"

restorecon -Rv /home/logs

拆池:给每个站点单独写conf

php-fpm支持通配包含,把单个池文件丢进/etc/php-fpm.d/即可。以siteA为例,新建/etc/php-fpm.d/siteA.conf:

[siteA]

user = siteA

group = siteA

listen = /run/php-fpm/siteA.sock

listen.owner = nginx

listen.group = nginx

pm = dynamic

pm.max_children = 50

pm.start_servers = 5

pm.minspareservers = 5

pm.maxspareservers = 15

;关键行:错误日志独立

tabphpadminvalue[error_log] = /home/logs/siteA/php/error.log

tabphpadminflag[log_errors] = on

tabphpadminflag[display_errors] = off

;慢日志也顺手切

tabphpadminvalue[slowlog] = /home/logs/siteA/php/slow.log

tabrequestslowlogtimeout = 3s

siteB、siteC照抄,改池名和路径即可。reload php-fpm后,ps aux | grep php-fpm能看到三个pool已经各跑各的。

Nginx虚拟主机对接不同sock

server块里把fastcgi_pass指到对应socket,日志自然就分开:

server {

server_name siteA.example.com;

root /home/siteA/web;

access_log /home/logs/siteA/nginx/access.log main;

error_log /home/logs/siteA/nginx/error.log warn;

location ~ \.php$ {

fastcgi_pass unix:/run/php-fpm/siteA.sock;

include fastcgi_params;

}

}

reload nginx,访问故意写错的代码,立即能在/home/logs/siteA/php/error.log里看到Fatal error,别的池纹丝不动。

轮转策略:logrotate按站点配置

新建/etc/logrotate.d/php-fpm-sites:

/home/logs//php/.log {

daily

rotate 14

compress

delaycompress

missingok

notifempty

sharedscripts

postrotate

/usr/bin/systemctl reload php-fpm > /dev/null 2>&1 || true

endscript

}

用通配符一次管所有子目录,reload信号让php-fpm重新打开文件句柄,零丢失。

踩坑汇总

1. 权限拒绝:error_log路径必须让php-fpm用户可写,SELinux没打标签也会报Permission denied。

2. 值覆盖顺序:phpadminvalue优先级高于php.ini,如果之前把error_log设成syslog,这里不改成文件就永远写不进去。

3. 磁盘打爆:某个站点若疯狂报错,单文件也能涨到几十G,建议加inotify脚本实时告警,或者直接上lograte的maxsize 100M。

4. 池名重复:两段配置里如果都写[www],后加载的会覆盖前者,排障时一脸懵。

5. 日志丢失:reload和restart区别很大,改完配置直接restart会中断当前请求,用reload更平滑。

一键检查脚本

把下面内容存成checkfpmlog.sh,跑完就能知道哪些池没写日志:

#!/bin/bash

for pool in /etc/php-fpm.d/*.conf; do

name=$(awk -F'[][]' '/^\[.*\]$/{print $2}' "$pool")

err=$(awk -F'= *' '$1=="phpadminvalue[error_log]"{print $2}' "$pool")

if [[ -n "$err" ]]; then

printf "%-15s error_log=%s\n" "$name" "$err"

tail -n1 "$err" 2>/dev/null || echo " file not writable"

else

echo "$name missing error_log"

fi

done

多池+独立error_log,其实就是“分家”思路:让各自站点自己管自己,排障不用翻山越岭,磁盘告警也能精准到人。配置一次,省心一年,下次再遇到白屏,直接tail对应站点的日志,三十秒就能定位是哪行代码在作妖。

本站部分图片及内容来源网络,版权归原作者所有,转载目的为传递知识,不代表本站立场。若侵权或违规联系Email:zjx77377423@163.com 核实后第一时间删除。 转载请注明出处:https://blog.huochengrm.cn/pc/41697.html

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
请登录后评论...
游客游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~