PHP日志格式无全局“格式参数”,需按来源分三类配置:PHP内置错误日志格式固定不可改,仅能通过error_log()手动拼接;ThinkPHP需继承File驱动重写write方法定制JSON结构;Monolog等库依赖Formatter(如JsonFormatter)精细控制字段;Web服务器日志(Nginx/Apache)则通过log_format或LogFormat独立配置。

PHP日志格式本身没有直接的“格式参数”可全局配置,它的呈现方式取决于日志来源和所用组件。核心分三类:PHP自身错误日志、Web服务器访问/错误日志、应用框架(如ThinkPHP)或日志库(如Monolog)的日志输出。每类需分别配置,不能靠单一参数统一控制。
PHP内置错误日志:靠error_log +自定义触发
PHP原生不提供日志内容格式化选项,log_errors = On仅决定是否记录,error_log只指定写入位置。格式固定为:[时间] [错误类型] 错误消息 in 文件名 on 行号,不可更改。
- 若需自定义内容,必须用
error_log($message, 3, $file)手动写入,自己拼接字段,例如:error_log(date('Y-m-d H:i:s') . " [INFO] User login: uid=123\n", 3, '/var/log/app.log'); - 注意:这种方式无级别过滤、无上下文支持,适合简单场景,不适合结构化需求
ThinkPHP日志:通过json开关+自定义驱动
ThinkPHP 6 的'json' => true配置项仅开启基础JSON封装(把整条日志包成一个JSON对象),但字段扁平、不可控。真要定制字段顺序、添加trace_id或IP等,必须扩展日志驱动:
- 新建类继承
think\log\driver\File,重写write()方法,在调用parent::write()前组装字符串或数组 - 关键细节:传给父方法的
$context必须为空数组[],否则会二次格式化;避免在$context中传资源句柄或大对象 - 若需严格单行JSON日志(适配ELK),确保
json_encode()时加JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES,且不换行
Monolog等日志库:用Formatter精细控制
使用Monolog时,格式完全由Formatter决定,这才是最灵活的方式:
立即学习“PHP免费学习笔记(深入)”;
- 内置
JsonFormatter可输出标准JSON,字段包括message、level、context、datetime等,天然适配日志平台 - 可继承
JsonFormatter重写format(),插入自定义字段(如server_ip、request_uri) - 搭配
StreamHandler或RotatingFileHandler,格式与存储完全解耦
Web服务器日志:Nginx/Apache自定义log_format
访问日志(access log)的格式由Web服务器控制,与PHP无关:
- Nginx中用
log_format定义变量组合,例如:log_format main '$time_iso8601 $remote_addr "$request" $status $body_bytes_sent'; - Apache用
LogFormat指令,支持%t %a %U %s %b等占位符 - 这些格式影响的是HTTP请求层面记录,不是PHP脚本内部日志



















