frankenphp 默认不记录访问日志及请求耗时,需在 caddyfile 顶层显式配置 { log } 块并指定 format json 或自定义字段(如 duration)才能输出含耗时的结构化日志。

FrankenPHP 的访问日志默认不显示请求耗时
直接运行 frankenphp run 或用 Caddyfile 启动后,你看到的终端输出里只有启动提示、PHP 错误或 panic 信息——status、method、uri、duration 这类字段全都不出现。这不是漏配,而是 FrankenPHP(基于 Caddy)默认压根不记录访问日志,更别说带耗时了。
Caddyfile 中必须显式配置 log 块并启用格式化字段
FrankenPHP 的日志能力完全继承自 Caddy,没有 { log } 全局块,整个服务就静默;即使加了,也要手动指定字段才能显示耗时。
-
{ log }必须是顶层全局块,不能嵌套在localhost { ... }里,否则无效 - 默认日志格式只含基础字段,要显示耗时得用
format json或自定义format single_field - 最简可用配置示例:
{ log {
output stdout
format json
} }
localhost {
route {
php { root /var/www }
}
}
这样输出就是 JSON,其中 "duration" 字段单位为秒(如 "duration":0.023456)。如果坚持用文本格式,可写:
log {
output stdout
format single_field common_log {
duration
}
}
但注意:common_log 是占位名,实际生效的是你写的字段列表,不是 Apache 风格日志。
别混淆 PHP 错误日志和 HTTP 访问耗时日志
duration 只出现在 Caddy 层的访问日志中,它记录的是从收到请求首字节到发出响应最后一字节的总时间。它不包含:
- PHP 脚本内部的
microtime(true)差值(那是纯执行时间) - 数据库查询耗时(除非你用
HRTime\PerformanceCounter在 PDO 包装层打点) - PHP
error_log或php.ini中的error_log文件内容(那些只记 Warning/Fatal,不带 duration)
如果你看到某条日志有 "status":500 但 "duration" 很小(比如 0.002s),说明错误发生在 PHP 解析/启动阶段(如语法错误),根本没进业务逻辑;如果 duration 很大(>10s)且状态是 200,大概率是脚本里卡了 cURL 或 sleep,得去查 PHP 层计时。
Docker 或 systemd 环境下,duration 字段仍存在但需正确捕获
日志格式不受部署方式影响,但输出目标会影响你是否能看到 duration:
- Docker:确保 Caddyfile 中
output stdout(不是file /dev/null),然后docker logs -f myapp就能实时看到带duration的 JSON 行 - systemd:日志重定向到 journald 后,
journalctl -u frankenphp -o json才能保留结构化字段;用-o short会丢掉duration - 文件输出:用
output file /var/log/frankenphp/access.log时,确保磁盘可写且进程有权限,否则日志静默失败
最后提醒一句:Caddy 的 duration 是 wall-clock 时间,受系统时钟跳变、CPU 抢占、I/O 阻塞影响,它反映的是用户感知延迟,不是 PHP 的 CPU time。真要抠毫秒级执行瓶颈,得进 PHP 代码里用 HRTime\PerformanceCounter::getTicks() 打点,而不是只盯日志里的这个数字。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











