thinkphp默认日志按天切割不自动清理旧文件,必须改用monolog的rotatingfilehandler并设type为'monolog',配置max_files和datetimezone才能实现保留n天及准确切分。

ThinkPHP 默认的日志按天切割功能本身存在关键限制:它只生成新文件,从不删除旧文件。max_files 这个参数在原生 File 或 Daily 驱动下完全无效——不是配置没生效,而是该驱动压根不支持自动清理。真正能实现「按天切分 + 保留 N 天」的唯一可靠方式,是切换到 Monolog 的 RotatingFileHandler 并正确配置。
必须切换日志驱动类型
TP6/TP8 中,log.channel 配置里的 type 不能写 'daily' 或 'file',必须设为 'monolog',否则后续所有轮转逻辑都不会触发。
- 错误写法:
'default' => [ 'type' => 'daily', // ❌ 不会清理旧文件 'max_files' => 7, ] - 正确写法(TP6 ≥ v6.0.13):
'default' => [ 'type' => 'monolog', 'handler' => function () { $filename = runtime_path() . 'log/think.log'; return new \Monolog\Handler\RotatingFileHandler( $filename, 7, // 最多保留 7 个日志文件(含当天) \Monolog\Logger::DEBUG, true, null, new \DateTimeZone('Asia/Shanghai') ); } ]
✅
7表示最多保留在runtime/log/下的 7 个.log文件,比如think-2026-10-14.log到think-2026-10-20.log,超出后自动删最老的。
⚠️ 缺少new \DateTimeZone('Asia/Shanghai')会导致切割时间错位(如本该 00:00 切,实际变成 08:00),尤其在服务器时区为 UTC 时必现。
按大小切分需关闭缓冲并禁用 max_size 冲突
如果想按单文件大小(如 5MB)而非日期来轮转,必须额外处理两个细节:
- 显式关闭日志缓冲(否则写满也不切):
new \Monolog\Handler\RotatingFileHandler($filename, 30, ..., false) // 第4个参数 false
-
max_size参数必须作为构造函数外的独立配置传入(TP6 不识别 handler 闭包内设max_size):'handler' => function () { $handler = new \Monolog\Handler\RotatingFileHandler(..., false); $handler->setMaxFileSize('5M'); // ✅ 正确方式 return $handler; } - 不要同时启用
max_size和按天命名逻辑(如文件名含{date}),二者互斥;选其一即可。
自定义通道(如 sql、pay)也要单独配 max_files
每个通道都是独立实例,max_files 不继承、不共享。例如配置 SQL 日志通道:
'sql' => [
'type' => 'monolog',
'handler' => function () {
$filename = runtime_path() . 'log/sql.log';
return new \Monolog\Handler\RotatingFileHandler(
$filename,
3, // 只保留最近 3 个 sql 日志文件
\Monolog\Logger::INFO,
true,
null,
new \DateTimeZone('Asia/Shanghai')
);
}
]
调用时使用 Log::channel('sql')->info(...) 即可,其生命周期和清理规则完全独立于 default 通道。
不复杂但容易忽略
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











