ThinkPHP 8.0 日志默认不写入文件,需同时满足开启记录、配置有效通道、请求正常结束(或手动调用Log::save());仅调用Log::info()或Log::record()不会落盘。
ThinkPHP 8.0 的日志默认不写入文件,除非你显式开启记录、配置了有效通道,且请求正常结束(或手动触发
)。光靠
或
调用,日志只是暂存在内存里,不会落盘。
日志不写入文件的常见原因
最常踩的坑是:以为调用了就写了,结果 runtime/log/ 下空空如也。核心问题通常出在三处:
为
时,
中的
若为空数组(
),则所有级别日志都会被过滤掉 —— 这比
更隐蔽
未配置
,或路径不可写(如
目录不存在、权限不足、父目录无执行权限)
使用了
但没调用
,或在 CLI 命令中未手动保存(Web 请求结束会自动 save,CLI 不会)
配置 log.
php
时 level 和 channels 的关键写法
TP8 的日志配置以
为准,不再读取旧版
常量。正确写法必须明确指定级别数组和通道驱动:
必须是字符串数组,例如
;写成
字符串会被忽略
中的
通道必须显式启用,且
值为
(首字母大写,小写
会静默失败)
若想把 SQL 单独记到
,需额外定义一个
通道,并在模型或 Db 类中用
示例最小可用配置:
立即学习
“
PHP免费学习笔记(深入)
”;
PHP 8.5.5
PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。
下载
CLI 命令中写日志必须手动 save
在定时任务或自定义命令(如
)中,
不会自动落盘。因为 CLI 没有“请求结束”生命周期钩子。
必须在命令逻辑末尾加
,否则日志永远留在内存
若命令中途异常退出(未捕获的 Exception),
不会执行,已 record 的内容丢失
建议包裹在
中:
,确保无论成功失败都写一次
调试时快速验证日志是否生效
别等部署后翻日志文件。本地调试可直接用以下两行代码验证通路:
先确认路径可写:
返回
再强制写一条并立即保存:
立刻检查
是否新增一行 —— 注意日期文件名按天滚动,不是固定文件名
真正容易被忽略的是:日志通道名(
)、驱动类名(
)、级别写法(数组非字符串)、CLI 下的 save 时机 —— 这四点错一个,日志就静默消失。
Log::save()Log::info()Log::record()APP_DEBUGfalseconfig/log.php'level'[]LOG_RECORD=>false'path'runtime/log/Log::record()Log::save()config/log.phpLOG_LEVEL'level'['info', 'error', 'sql']'INFO,ERROR''channels''file''type''File''file'sql.log'sql'Log::channel('sql')->info(...)return [
'default' => 'file',
'level' => ['info', 'error', 'sql'],
'channels' => [
'file' => [
'type' => 'File',
'path' => runtime_path('log/'),
'single' => false,
'max_files' => 30,
],
],
];php think demo:taskLog::info()Log::save();Log::save()try...finallyfinally { Log::save(); }is_writable(runtime_path('log/'))trueLog::channel('file')->info('test at '.date('Y-m-d H:i:s')); Log::save();runtime/log/2026-05-08.log'file''File'