Laravel7 logging 使用 daily日志保留 7 天是怎么实现的
如题,为了搞明白这个,熬了个夜,我的头发啊
场景: 控制器直接 throw New \Exception(123);
调用堆栈:
app/Exceptions/Handler.php:39行,调用方法:report
/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php:122行,调用方法:error
/vendor/laravel/framework/src/Illuminate/Log/LogManager.php:547行,调用方法:error()->driver():96行 ->get() :115行 ->resolve():187行 -> createDailyDriver():275行
createDailyDriver() 内实例化了 vendor/monolog/monolog/src/Monolog/Handler/RotatingFileHandler.php 在构造函数中得到 nextRotation 是
明天
的时间,并且从配置文件读取并赋值了日志文件保留个数/vendor/laravel/framework/src/Illuminate/Log/Logger.php:174行,调用方法:error()->addRecord() 在addRecord 中 获取了
当前的时间戳
赋值给 $record[‘datetime’]/vendor/monolog/monolog/src/Monolog/Logger.php:323行,调用方法:handle()
最终调用了 vendor/monolog/monolog/src/Monolog/Handler/RotatingFileHandler.php 的108行 write()
protected function write(array $record): void { // on the first record written, if the log is new, we should rotate (once per day) if (null === $this->mustRotate) { # 这里判断$this->url 就是 当天的日志文件,不存在的话 循环标识就是 true 也就是标志 在rotate()方法 可以删除旧日志 只有当天第一次写入日志的时候会触发旧日志的删除 $this->mustRotate = !file_exists($this->url); } if ($this->nextRotation <= $record['datetime']) { # 没看懂这个if 因为获取的nextRotation时间永远是明天凌晨, # $record['datetime'] 永远是今天的当前时间 $this->mustRotate = true; $this->close(); } parent::write($record); }
RotatingFileHandler 继承自 StreamHandler 继承自 AbstractProcessingHandler 继承自 AbstractHandler 继承自 vendor/monolog/monolog/src/Monolog/Handler/Handler.php
在 抽象类 Handler 的析构方法中public function __destruct() { try { $this->close(); # 调用了 close() } catch (\Throwable $e) { // do nothing } }
回到 RotatingFileHandler 的close方法(60行)
/** * {@inheritdoc} */ public function close(): void { parent::close(); # 这里的 if 条件在当天第一次记录日志的时候是已经成立的,然后进入rotate() 126行 if (true === $this->mustRotate) { $this->rotate(); } }
在 rotate() 方法中 校验maxFiles 然后获取所有日志文件(glob)并排序,最终删除旧的日志文件,并重置 循环标识。 到此 daily 渠道的 日志保留个数就完成了,撒花~
之前看了很多次没明白,今天熬个夜才搞明白,debug能力还是太差了,有这个时间,搂着媳妇睡觉不香么?嘿嘿嘿,睡觉
本作品采用《CC 协议》,转载必须注明作者和本文链接
所以该怎么设置日志保留天数呢?