ThinkPHP 6.1 通过配置多个 file 类型 channel 实现按级别分离日志,需在 config/log.php 中定义如 error_file、sql_file 等通道并指定 level 和 path,代码中显式调用 Log::channel('xxx')->level() 写入,SQL 日志还需 database.php 开启 logger.sql 并确保全局 level 包含 sql。

ThinkPHP 6.1 支持按日志级别分离写入不同文件,但不是靠“自动创建 level.log”实现的,而是通过配置多个日志通道(channel),每个通道绑定特定级别和独立文件路径。
配置独立级别文件的核心步骤
关键在于定义多个 file 类型的 channel,每个指定 不同的日志级别 和 唯一的日志文件名,再在业务中显式调用对应 channel 写入。
- 在
config/log.php中新增多个 channel,例如:'error_file' => ['type' => 'File', 'level' => ['error'], 'path' => runtime_path() . 'log/error/'],<br>'sql_file' => ['type' => 'File', 'level' => ['sql'], 'path' => runtime_path() . 'log/sql/'],<br>'debug_file' => ['type' => 'File', 'level' => ['debug'], 'path' => runtime_path() . 'log/debug/']
- 确保每个 channel 的
path目录存在且 PHP 进程有写权限(如chown -R www-data:www-data runtime/log/error) - 不修改全局
log.level,它只控制哪些级别允许进入日志系统;真正分流靠 channel 的level限定
如何在代码中使用指定级别通道
不能依赖 Log::record() 默认行为,必须显式指定 channel 名称:
Log::channel('error_file')->error('订单支付失败:' . $e->getMessage());Log::channel('sql_file')->sql('SELECT * FROM user WHERE id = ?', [$id]);Log::channel('debug_file')->debug('用户登录流程第3步:token生成完成');
SQL 日志要单独落盘需额外开启
仅配置 sql_file 通道还不够,数据库 SQL 才会进该通道:
立即学习“PHP免费学习笔记(深入)”;
- 在
config/database.php中设'logger' => ['sql' => true] - 确认全局日志等级包含
sql,即config/log.php中'level' => ['error', 'sql', 'debug'](否则 sql 级别日志被过滤) - 若用 Swoole 或 RoadRunner,SQL 日志仍会写入对应 channel 的文件,但不会实时刷屏,需查
runtime/log/sql/下的日期文件
生产环境注意事项
多通道会增加 I/O 开销,线上建议只对关键级别启用独立文件:
-
error_file必开,用于快速定位故障 -
sql_file可按需开启,排查慢查询时临时启用,避免长期高频率写入撑爆磁盘 - 避免为
info或notice单独建通道,它们更适合合并到主日志或关闭 - 所有自定义 channel 的
trace选项默认继承全局配置,如需堆栈,确保对应 channel 所在的trace配置为true



















