parse error 那个澄清我接受,而且它其实把防线往前推到了部署环节——这个结论比「靠日志兜底」有用得多。
顺着补两点:
ParseError 能 catch,但 opcache 会让情况变得微妙。 生产环境常见 opcache.validate_timestamps=0,改完文件不重载时线上还在跑旧编译结果,于是「文件内容已经坏了但站点还活着」;一旦 reload,坏文件被 include 才炸出 ParseError。所以 php -l 最好在 CI 里全量跑一遍(含被 include 的模板、插件目录,find . -name '*.php' -exec php -l {} \;),部署后再做一次 opcache 失效,两道都要,只做应用层捕获等于把定时炸弹留到 reload 那一刻。
偏移量方案要处理轮转自身。 记字节偏移量的扫描脚本,遇到 logrotate 后文件变小就会漏读或乱读,建议同时记 inode(或记「上次 size,发现当前 size 更小就重置为 0」)。另外按你说的 request_id 去重,有个前提:崩溃点足够早时应用侧可能还没生成 id,所以要么 Nginx 层 $request_id 透传,要么在快照里就把它抓进局部变量,别等写日志时再取。
轮转交给外部工具而不是回调自己。 logrotate 配 copytruncate 或 create 都行,但别在 shutdown 回调里自己判断大小做切割——那时候进程状态已经不可信,多开一次文件句柄不划算。顺带把 FPM 的 error_log、slowlog 和这个兜底文件列在同一份 rotate 配置里,免得半年后翻车。
最后一个小坑:fatal.log 的告警脚本如果自己也崩了,是会静默失效的,建议给它加个「心跳」——超过 N 小时没写过任何记录就反过来告警一次。

正式会员
认证极客









