ThinkPHP6.0默认开启日志但不写入文件或控制台,需在app/config/log.php中配置驱动(如'file'或'console')、级别(如['error','info'])及路径;Log::info()无效常见于环境不匹配、app_debug关闭、引入错误或编码问题。

ThinkPHP6.0 默认开启日志记录,但**不写入文件或控制台,除非你显式配置了日志驱动和级别**——这是最常被忽略的前提。
日志配置在哪改?app/config/log.php
TP6 的日志配置独立于 app/config/app.php,必须在 app/config/log.php 中调整。默认该文件可能不存在,需手动创建或从 thinkphp/config/ 复制模板。
-
'default' => 'file':指定默认驱动,可选'file'、'trace'、'error_log'等 -
'level' => ['error', 'info', 'debug']:只记录等于或高于该级别的日志(注意:'debug'在生产环境会自动降级为'notice') -
'path' => runtime_path('log/'):确保目录存在且可写,否则日志静默失败 - 若用
'file'驱动,'single' => true会强制所有日志写入单个文件(如log.log),否则按日期分文件(如2026-05-08.log)
Log::info() 不生效?检查运行时环境与级别匹配
开发时调用 Log::info('test') 却没生成日志,大概率是以下原因:
- 当前环境为
production,而'level'配置中未包含'info'(默认只保留['error', 'notice']) -
app_debug关闭时,debug级别日志会被跳过,即使配置了也无效 - 使用了
think\facade\Log,但未在控制器/命令中正确引入(应use think\facade\Log;,不是think\Log) - 日志内容含非 UTF-8 字符(如 GBK 编码的字符串),会导致写入中断,建议先用
mb_convert_encoding($str, 'UTF-8', 'auto')过滤
如何临时输出到控制台(调试专用)?用 console 驱动
TP6 原生支持 'console' 日志驱动,适合 CLI 或 Swoole 场景下的即时反馈:
立即学习“PHP免费学习笔记(深入)”;
- 在
log.php中设置'default' => 'console' - 确保终端支持 ANSI 颜色(Linux/macOS 默认支持,Windows CMD 需启用虚拟终端)
- 该驱动不会写文件,也不受
runtime_path()影响,但会丢失历史记录——仅限调试,不可用于生产 - 若配合
think-queue或命令行任务,加Log::channel('console')->info(...)可避免污染主日志流
自定义日志格式与上下文:用 formatter 和 context
默认日志只含时间、级别、消息,想追加请求 ID、用户 UID 或 SQL 耗时,需扩展 formatter:
- 在
log.php的驱动配置中添加:'formatter' => \think\log\formatter\Simple::class(或自定义类) - 调用时传入上下文:
Log::info('SQL executed', ['sql' => $sql, 'time' => $ms]),该数组会序列化进日志行末尾 - 注意:
Simple格式器对嵌套数组支持有限,深层结构会被转成Array字符串;如需完整结构,建议继承并重写format()方法 - 频繁写入大体积上下文(如 dump 整个 Request 对象)会显著拖慢响应,尤其在高并发下
真正难的不是打开日志,而是让日志在出问题时能精准还原现场——比如异步任务里漏掉 Log::channel() 切换,或者中间件中提前终止了请求却没 flush 日志缓冲区。这些细节比配置本身更容易导致“日志写了但找不到”。



















