Laravel7 logging 使用 daily日志保留 7 天是怎么实现的

如题,为了搞明白这个,熬了个夜,我的头发啊
场景: 控制器直接 throw New \Exception(123);
调用堆栈:

  1. app/Exceptions/Handler.php:39行,调用方法:report

  2. /vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php:122行,调用方法:error

  3. /vendor/laravel/framework/src/Illuminate/Log/LogManager.php:547行,调用方法:error()->driver():96行 ->get() :115行 ->resolve():187行 -> createDailyDriver():275行

  4. createDailyDriver() 内实例化了 vendor/monolog/monolog/src/Monolog/Handler/RotatingFileHandler.php 在构造函数中得到 nextRotation 是明天的时间,并且从配置文件读取并赋值了日志文件保留个数

  5. /vendor/laravel/framework/src/Illuminate/Log/Logger.php:174行,调用方法:error()->addRecord() 在addRecord 中 获取了当前的时间戳 赋值给 $record[‘datetime’]

  6. /vendor/monolog/monolog/src/Monolog/Logger.php:323行,调用方法:handle()

  7. 最终调用了 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);
      }
  8. 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() 126if (true === $this->mustRotate) {
             $this->rotate();
         }
     }

    在 rotate() 方法中 校验maxFiles 然后获取所有日志文件(glob)并排序,最终删除旧的日志文件,并重置 循环标识。 到此 daily 渠道的 日志保留个数就完成了,撒花~

之前看了很多次没明白,今天熬个夜才搞明白,debug能力还是太差了,有这个时间,搂着媳妇睡觉不香么?嘿嘿嘿,睡觉

本作品采用《CC 协议》,转载必须注明作者和本文链接
呦,写bug呢?
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
讨论数量: 6

所以该怎么设置日志保留天数呢?

1年前 评论
Pendant59 (楼主) 1年前
弓长 (作者) 1年前
qingyan233 10个月前
Pendant59 (楼主) 10个月前
qingyan233 9个月前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!