thinkphp日志级别从低到高为:debug → info → notice → warning → error → critical → alert → emergency,严格遵循rfc 5424标准,其中debug仅开发环境启用,emergency和alert由框架异常处理器自动触发。

ThinkPHP日志级别从低到高怎么排?别记混了
ThinkPHP的日志级别共8级,按严重程度升序排列:debug → info → notice → warning → error → critical → alert → emergency。这不是随便列的,而是严格遵循RFC 5424标准,和Monolog、Laravel等主流日志系统对齐。
常见错误是把notice当成“不重要”就忽略,其实它常用于记录非致命但需关注的事件(比如缓存未命中、配置项缺失);更危险的是在生产环境还开着debug,不仅泄露敏感变量,还会让日志体积暴增数倍。
-
debug:只应在开发环境启用,记录变量值、执行路径等,上线必须关 -
sql不是标准级别,是ThinkPHP特有,仅在调试模式开启且app_debug=true时才生效 -
emergency和alert极少手动调用,通常由框架异常处理器自动触发
log.php里level和apart_level到底怎么配?
level是全局过滤器,决定哪些级别“允许写入”;apart_level是分流开关,指定某些级别单独成文件——两者逻辑不同,不能互相替代。
比如你设'level' => ['error', 'warning'],那info日志连内存都不会进;但若加'apart_level' => ['sql'],即使level没开sql,SQL语句仍会写进sql.log(前提是调试模式开启)。
立即学习“PHP免费学习笔记(深入)”;
- 开发环境推荐:
'level' => ['debug', 'info', 'warning', 'error'],'apart_level' => ['sql'] - 生产环境必须:
'level' => ['error', 'critical', 'alert', 'emergency'],禁用apart_level中所有非必要项 - 注意:
apart_level里的sql不走level判断,但受app_debug控制——这点极易踩坑
为什么Log::info()没写进文件?排查三步走
最常见原因不是代码错,而是配置或环境没对上。先看Log::info('test')是否真被调用(加个dump确认),再按顺序查:
- 检查
config/log.php中'default'通道是否为'file',且'channels.file.type'是'File'(大小写敏感) - 确认
'level'数组包含'info',且当前不是生产环境(APP_ENV=production时app_debug=false会屏蔽debug/info) - 运行
php think clear:log清空日志缓存,再试;有时runtime/log目录权限不足也会静默失败
如果用了'single' => true,日志会固定写入app.log而非按天分文件,别去2026-03-11.log里找。
自定义通道写数据库或邮件时,channel名写错会怎样?
调用Log::channel('db')->error('xxx')时,如果'db'不在config/log.php的'channels'里,ThinkPHP不会报错,而是降级回默认file通道——日志照写,但你完全不知道它没进数据库。
更隐蔽的问题是通道配置缺关键参数:比如database类型漏了'table',会直接抛InvalidArgumentException;而email类型若'receivers'为空,日志就丢进黑洞,连失败提示都没有。
- 务必在
channels里显式声明每个自定义通道,哪怕只是占位:'db' => ['type' => 'database', 'table' => 'logs'] - 测试自定义通道前,先用
Log::channel('db')->getChannel()确认返回对象非null - 邮件通道建议搭配
think-swoole或队列使用,避免阻塞主流程
日志配置里最容易被忽略的,其实是max_files和file_size的协同关系:设了max_files => 30却没设file_size,日志可能单日膨胀到GB级才轮转——磁盘告警往往来得比你想到的早。











