thinkphp按模块分离日志需在config/log.php预定义模块通道,并通过优先级-100中间件早期调用log::channel()切换,确保admin/pay/wechat等模块日志写入各自独立目录,path末尾须带/且目录需手动创建或授权。

ThinkPHP 默认不按模块自动分离日志,因为所有请求默认走 default 通道,模块信息在日志写入时已丢失。要实现「按业务模块(如 admin、api、pay、wechat)各自写入独立目录」,关键不是改日志内容或加判断,而是**在请求早期动态切换日志通道,并配合预配置的模块化通道**。
必须在 config/log.php 中提前定义模块通道
通道不能临时注册,必须显式写进配置。例如:
-
admin 模块:路径为
runtime/log/admin/,启用日期分文件 -
pay 模块:路径为
runtime/log/pay/,设'single' => true写入single.log -
wechat 模块:路径为
runtime/log/wechat/,单独设'level' => ['info', 'error']
注意:path 值末尾必须带 /,且目录需手动创建或确保运行用户有写权限;filename 在 single => true 时无效,固定生成 single.log。
用中间件在请求最早期切换通道
不能在控制器或 common.php 里调用 Log::channel()——此时日志可能已在路由解析、异常捕获阶段触发。正确做法是:
- 新建全局中间件(如
app\common\middleware\InitLogChannel) - 设置优先级为
-100,确保比语言包加载还早 - 从
$request->module()获取模块名,拼出通道名(如admin) - 执行
Log::channel($channel),后续所有Log::info()等调用即写入对应目录
避免常见失效场景
以下情况会导致模块日志仍写进默认目录:
- 通道名未在
config/log.php的'channels'数组中声明 → 报错Channel [xxx] is not exists - 中间件未注册或优先级不够高 → 模块上下文未建立就已触发日志
-
path配置漏掉末尾斜杠 → 日志可能写入上层目录或静默失败 - 目录不存在且无写权限 → 日志不报错,但文件始终不生成
进阶:同一模块内再按类型细分(如 pay_action / pay_callback)
若仅靠通道不够细,可在业务中传入类型标识,再通过自定义 File 驱动实现:
- 继承
think\log\driver\File,重写write()和getLogName() - 从
$log['type'](需调用时传入,如Log::record('xxx', 'callback'))提取分类 - 动态修改
$this->config['path'],追加子目录如$this->config['path'] .= 'callback/' - 确保
mkdir(..., 0755, true)自动创建嵌套目录
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











