frankenphp worker日志必须为每个实例单独配置stderr路径,因worker进程独立常驻、不走http链路,caddy log指令对其无效;需用2>>重定向或systemd standarderror=指定唯一日志文件,并由应用层用monolog独立写入业务日志。

FrankenPHP 1.2 的 worker 模式日志不能靠 PHP 配置或 Caddyfile 统一收集,必须为每个 worker 实例单独绑定 stderr 输出路径——因为 worker 是独立常驻进程,不走 HTTP 请求链路,也不受 Caddy 日志指令影响。
必须显式重定向 stderr
worker 进程的所有底层错误(PHP 解析失败、扩展加载异常、panic 堆栈、var_dump()、error_log())默认输出到 stderr。systemd 或终端直接运行时若不重定向,多个实例日志会混在一起。
- 启动命令中用
2>>追加重定向:frankenphp-worker --script=/var/www/app1/worker.php --addr=:8081 2>> /var/log/frankenphp/app1-stderr.log - 避免使用
>(覆盖模式),防止日志被意外清空 - 确保目标目录存在且 frankenphp 进程用户有写权限(如
chown www-data:www-data /var/log/frankenphp)
systemd 服务中配置 StandardError
生产环境推荐用 systemd 管理,通过 StandardError= 指令接管 stderr,并配合日志轮转:
- 在 service 文件中添加:
StandardError=append:/var/log/frankenphp/site-a-worker.log - 启用自动轮转:
LogRateLimitIntervalSec=0LogRateLimitBurst=0StandardError=journal+console可选,但不推荐用于多实例场景 - 搭配
SystemMaxUse=100M和SystemMaxFileSize=10M防止日志撑爆磁盘
业务日志必须由应用层独立写入
PHP 应用产生的业务日志(如“队列任务开始”“订单已推送”)不能依赖 stderr 或 error_log(),否则会和系统级错误混杂,难以排查。
- 用 Monolog + StreamHandler 写入固定路径,例如:
$handler = new StreamHandler('/var/log/frankenphp/app1-app.log', Logger::INFO); - 避免把业务日志写进
error_log或2>>目标文件——两类日志语义不同、排查场景不同、轮转策略也应分离 - 不要在 worker 入口脚本开头用
error_log(..., 3, ...)强制重定向,它只捕获error_log()调用,漏掉致命错误和 panic
Caddyfile 的 log 指令完全无效
很多人误以为在 Caddyfile 里加 log { output file /path } 就能收 worker 日志,这是误区。
- Caddy 的
log指令仅作用于 HTTP 请求生命周期(即php_server处理的请求) - worker 是后台常驻进程,不经过 Caddy 的路由、中间件或 handler,Caddy 对其内部执行完全无感知
-
journalctl -u caddy也看不到 worker 错误——得查对应 systemd service 的 journal,如journalctl -u frankenphp-site-a
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











