TP6移除了log.format,改用结构化日志,默认输出JSON;需自定义Handler才能还原TP5.1纯文本格式,且轮转逻辑由按大小变为按日期,不再自动清理旧日志。

ThinkPHP 6 的 log.format 不再支持占位符变量
TP6 把日志格式从「字符串模板」改成了「结构化字段映射」,log.format 配置项直接被移除了。你如果还在 TP5.1 里习惯写 '[date][level] [message]' 这类格式,升级后会发现完全不生效——因为 TP6 默认用 think\log\driver\Std 或 File 驱动,底层只认 log.file_format(仅控制文件名)和实际日志内容由 think\log\Logger 的 record() 方法按固定结构拼装。
常见错误现象:
• 日志文件里全是 JSON 格式,比如 {"time":"2024-03-15T10:23:45+08:00","level":"error","message":"SQL error","context":{}}
• 自定义 log.format 在 config/log.php 中无任何效果
• 试图用 %s、{time} 等占位符失败
- 真正能干预日志内容格式的地方是自定义日志处理器(Handler),比如继承
think\log\driver\File并重写save() - TP6 推荐用 PSR-3 兼容方式记录,
Log::info('msg', ['user_id' => 123])会自动把context写进 JSON 的context字段 - 若坚持要纯文本格式,必须关闭 JSON 输出:在
config/log.php中设'json' => false,但此时context数据会丢失,且仅限File驱动有效
TP5.1 的 log.format 支持哪些占位符?
TP5.1 的日志格式是字符串插值,靠 log.format 控制外观,但可用的占位符非常有限,文档没写全,容易试错踩坑。
常见错误现象:
• 写 [{datetime}]{level} {message} 结果 {datetime} 不解析,输出原样
• 用 %date% 或 $time$ 导致日志报错或空白
立即学习“PHP免费学习笔记(深入)”;
- 合法占位符只有:
{time}(格式化时间,受log.time_format控制)、{level}、{message}、{file}、{line} -
{time}默认用Y-m-d H:i:s,改它得配log.time_format,比如设为'H:i:s'后,{time}就只输出14:22:05 -
{file}和{line}在 CLI 模式下可能为空,因为调用栈深度不够,不是所有日志都带触发位置信息 - 别试图在
log.format里加 PHP 表达式或函数调用,它只是简单str_replace替换,不执行代码
TP6 如何还原 TP5.1 风格的纯文本日志?
不是不能,而是得绕过默认 JSON 流程,手动接管日志内容生成。关键点在于替换 Handler,而不是改配置。
使用场景:
• 日志要对接旧版 ELK 或 shell 脚本,依赖固定空格分隔格式
• 运维要求每行必须是 2024-03-15 14:22:05 ERROR User login failed 这种可 grep 的纯文本
- 新建类
app\log\TextFile,继承think\log\driver\File - 重写
save()方法,在里面用sprintf或strtr拼接字符串,例如:sprintf('[%s] %s %s', date('Y-m-d H:i:s'), $log['level'], $log['message']) - 在
config/log.php中指定驱动:'default' => 'text_file',并注册该驱动到'channels'数组里 - 注意:TP6 的
$log参数是数组,message是字符串,context是额外数组,若需打印 context,得手动json_encode($log['context'])或取特定 key
TP5.1 升级到 TP6 时日志路径和轮转行为变化
路径没变,但轮转逻辑变了——TP5.1 用文件大小 + 时间双条件轮转,TP6 默认只按日期轮转,且不自动清理旧文件。
性能影响:
• TP5.1 的 log.file_size 设为 2097152(2MB)时,单文件超限就切新文件,适合高频写入场景
• TP6 的 log.day_format 默认是 Y-m-d,每天一个文件,但如果某天没日志,就不会生成空文件;而 TP5.1 即使当天没日志,只要到了轮转时间点也会建空文件
- TP6 关闭日期轮转:设
'single' => true,日志写进单个文件,但不再自动切分,需自行处理归档 - TP6 想按大小轮转?必须自定义
think\log\driver\File子类,重写checkSize()和createNewFile() - TP5.1 的
log.backup_num(保留备份数)在 TP6 中失效,TP6 不提供自动清理,得用 crontab 或部署脚本定期find runtime/log -name "*.log" -mtime +30 -delete - 路径权限问题更敏感:TP6 默认日志目录是
runtime/log/,若 web 用户没写权限,会静默失败(不报错),只在php://stderr输出 warning,容易漏掉
context)在纯文本模式下不会自动展开,以及轮转后旧日志的清理完全甩给运维——框架不管。



















