Laravel 日志写入时机的问题

最近写了个 artisan 命令,是要24小时跑的那种,不可避免的就需要用到 sleep() 在特定的时间点进行休眠,然后我发现,日志不会立即写入了,必须要当前的脚本跑完(也就是 sleep 结束后,sleep 在写日志后面)才会写入。

举个栗子,在8点的时候开始运行,这个时候会有写入一条记录到日志的操作,然后再判断时间不对,需要休眠1个小时再继续,写日志操作在休眠之前,但是实际写入是在休眠之后(1个小时后,9点)才进行。

有没有什么办法,可以强制即时写入日志呀?

附关键代码

...
public function handle()
{
    ...
    while (1) {
        ...
        try {
            ...
            Log::channel('xxx')->debug('xxxxx');
            // 执行到这里的时候,日志文件里面没有记录

            sleep($workTimeHandler->getWaitSecondsBeforeNextWork());
            ...
        } catch (\Exception $e) {
            Log::channel('xxx')->warning('xxx');
            sleep(10);
        }
    }
}

补充自定义日志 channel
config/logging

'channels' => [
        ...
        'xxx' => [
            'driver' => 'daily',
            'path' => storage_path('logs/xxx/xxx.log'),
            'level' => env('LOG_LEVEL', 'debug'),
            'days' => 180,
        ],
        ...
    ],
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
讨论数量: 11

关键代码贴一下吧,正常都是会即时写入的。

1年前 评论
快乐的皮拉夫 (作者) 1年前
快乐的皮拉夫 (作者) 1年前
tomcath (楼主) 1年前
tomcath (楼主) 1年前

我没有发现你这样的问题,测试是正常的。我得到的log都是实时记录

        Log::info('开始时间是 ' . now());
        sleep(60);
        Log::info('退出时间是 ' . now());

// log

[2023-07-21 04:10:45] local.INFO: 开始时间是 2023-07-21 04:10:45  
[2023-07-21 04:11:45] local.INFO: 退出时间是 2023-07-21 04:11:45  
1年前 评论
tomcath (楼主) 1年前
忆往昔弹指间 (作者) 1年前

为什么不使用 Queue 或者 Schedule

1年前 评论
tomcath (楼主) 1年前

在找到原因之前,如果对时间不那么精确要求,每个循环可以简单的固定 sleep 5s,没有达到执行的时间继续下个循环即可,或者动态调整睡眠时间的区间在较小的范围内。

while(1) {
 // ...
sleep(5)
}

while(1) {
 if () {
    // 如果执行时间距离现在小于 5 s
    sleep(实际的睡眠时间)
  } else {
    sleep(5)
  }
}
1年前 评论

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