日志配置生效需同时满足level为非空字符串数组、trace显式设为true、path为绝对路径,且必须在生产环境显式配置;sql级别日志在app_debug=false时无效;自定义通道save()必须返回true。

日志配置不是“开了就能用”,关键在 level、type、trace 三个配置项的组合是否生效,且必须在生产环境(APP_DEBUG = false)下显式设置,否则 runtime/log 目录空着完全正常。
log.php 中必须显式配置 level 才会写入
ThinkPHP 默认在生产环境跳过所有日志记录逻辑,哪怕 type => 'File' 已配好,只要 level 是空数组或未定义,就不会生成任何日志文件。
-
level必须是字符串数组,例如['error', 'sql', 'notice'];只写'error'(字符串)或留空都会失效 -
sql级别在生产环境默认不记录——它依赖APP_DEBUG = true,即使你把它加进level也无效 - 若用环境变量控制(如
LOG_LEVEL=error,notice),必须在public/index.php中require框架前就putenv()或通过.env加载,否则框架启动时读不到
type 和 path 要同时存在且路径为绝对路径
type => 'File' 单独存在没用,path 缺失或为相对路径(如 '../runtime/log/')会导致不同运行模式(FPM/CLI/Swoole)下日志静默丢失。
- 推荐写法:
'path' => runtime_path() . 'log' . DIRECTORY_SEPARATOR,确保末尾有斜杠 - 验证是否真为绝对路径:在控制器里执行
echo realpath(config('log.channels.file.path'));,输出应是完整路径(如/var/www/app/runtime/log/) - 不要依赖 config/app.php 里的
log配置——TP6+ 的日志系统只认 config/log.php 中的channels定义
trace => true 决定错误日志有没有堆栈
开了日志但只看到 [ error ] xxx 一行,没有文件名、行号、变量上下文?基本是 trace 关着。
- 该选项只对
error和notice级别生效,info级别开了也没堆栈 - TP6.1+ 默认为
false,必须在 config/log.php 的 channel 配置里显式设为true - 开启后单条 error 日志体积可能翻倍,线上排查期临时启用即可,别长期开着
手动调用 Log::record() 没反应?时机和驱动没初始化
在中间件、命令行或 App 初始化前调用 Log::record(),大概率白写——日志驱动还没加载,消息只是进队列,但最终不会落盘。
- 确保调用发生在
App::init()之后(比如控制器方法、事件监听器内) - 想立刻写入文件,改用
Log::save(),但它会强制刷盘,高频调用会拖慢响应 - 自定义通道(如数据库驱动)时,
save()方法必须返回true,否则框架直接跳过后续处理
最常被忽略的是:日志配置生效 ≠ 日志内容可用。堆栈是否完整、时间是否准确、级别是否匹配问题严重性,全卡在 level + trace + 绝对 path 这三者的组合上,少一个,日志就只剩个空壳。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











