FrankenPHP需双路配置JSON日志:Caddy层设CADDY_LOG_OUTPUT=stdout(仅0.19+有效),PHP层用error_log(json_encode($data), 4)写stderr单行JSON,采集端(Filebeat/Fluent Bit)必须启用原生JSON解析,三者缺一不可。

FrankenPHP 本身不提供开箱即用的 JSON 日志开关,必须分两路控制:Caddy 层访问日志走 stdout + JSON,PHP 应用层错误/业务日志走 error_log() 输出单行 JSON 到 stderr。缺一不可,否则采集端只能拿到半结构化日志。
CADDY_LOG_OUTPUT=stdout 必须设对版本和环境
FrankenPHP 内置 Caddy,但它的日志默认写文件(如 /var/log/caddy/access.log),不经过 stdout。想让 access log 变成 JSON 并进容器日志流,得靠环境变量驱动:
- 仅 FrankenPHP 0.19+ 支持
CADDY_LOG_OUTPUT=stdout;旧版设了也无效 - 启动容器时必须显式传入:
docker run -e CADDY_LOG_OUTPUT=stdout ... ghcr.io/dunglas/frankenphp - 若用 systemd 管理二进制,需在
[Service]段加Environment="CADDY_LOG_OUTPUT=stdout" - 生效后,
docker logs或journalctl里每行都是类似{"level":"info","msg":"handled request","status":200,"request_id":"abc123"}的 JSON
PHP 应用必须用 error_log($json, 4) 写 stderr
别指望 echo json_encode(...) 或 file_put_contents('app.log', ...) —— 前者可能被缓冲或混入 HTML,后者绕过日志采集路径。唯一可靠路径是 error_log() 直写 stderr:
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
- 用法必须是:
error_log(json_encode($logData, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), 4)(4表示 stderr) -
$logData至少含timestamp(建议(new DateTime())->format('c'))、level、message、context(纯数组,不含资源句柄或 $_POST 全量) - 绝对避免
JSON_PRETTY_PRINT或手动拼换行符——每条日志必须严格单行,否则 Logstash / Fluent Bit 会解析失败 - 如果用了 worker 模式,别用
date('c'),协程下可能时间漂移;改用(new DateTime())->format('c')
Filebeat / Fluent Bit 必须配 json 解析,不能靠 guess
即使 PHP 和 Caddy 都输出了合法 JSON,采集端若没明确启用 JSON 解析,照样当普通文本切分:
立即学习“PHP免费学习笔记(深入)”;
- Filebeat:在 input 配置里加
json.keys_under_root: true和json.add_error_key: true,且确认paths指向容器 stdout 对应的日志路径(K8s 中通常是/var/log/containers/*.log) - Fluent Bit:Parser 类型必须设为
Format json,不是regex;同时禁用Decode_Field_As对 message 的二次解码 - 验证方法:
docker logs <container> | head -n 5 | jq -R 'fromjson' 2>/dev/null,能无错输出即说明格式和采集配置都对 - 最常漏掉的是时间字段不统一:Caddy 日志用
time字段(ISO8601),PHP 自己打的日志若用microtime(true)就得手动转,否则 Kibana 里时间轴对不上
真正卡住人的地方不在代码怎么写,而在三处隐性耦合:FrankenPHP 版本是否 ≥0.19、stderr 是否真被采集器捕获(而非被重定向丢弃)、以及采集器是否把“每行 JSON”当成结构化数据而非字符串。任何一环断开,日志就退化成不可查的黑盒。


















