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,
        ],
        ...
    ],
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 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年前 评论

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