繁体   English   中英

当两个脚本实例同时写入日志时,由Monolog编写的日志行如何不会被弄乱/混淆?

[英]How come log lines written by Monolog don't get messed/mixed up when two script instances are writing to log concurrently?

当将Monolog与StreamHandler一起使用时,通常情况是几个PHP脚本实例将并行写入同一日志文件。

(例如,在我的Symfony应用程序中,当多个用户同时打开“登录页面”时,这将导致我的应用脚本( app.php )的多个实例运行,因此两个Monolog StreamHandler实例将写入同一app/logs/prod.log 。)

尽管同时写入文件,但每个日志行在中间没有被破坏却弄乱了,怎么会这样呢? 以下情况永远不会发生:

  • StreamHanler的instance1只写了一半的日志行,
  • StreamHanler的instance2写下了前半部分
  • instance1写入了日志行的后一半
  • instance2写入了日志行的后一半
  • 现在我们的日志文件一团糟,因为两行混合在一起。

我尝试查看StreamHanler的源代码https://github.com/Seldaek/monolog/blob/master/src/Monolog/Handler/StreamHandler.php#L93

但是我看不到任何适当的并发控制,有一个flock()但它似乎在默认(Symfony)配置中被禁用( ->useLocking=false ),并且似乎没有它就可以了...

    if ($this->useLocking) {
        // ignoring errors here, there's not much we can do about them
        flock($this->stream, LOCK_EX);
    }
    fwrite($this->stream, (string) $record['formatted']);
    if ($this->useLocking) {
        flock($this->stream, LOCK_UN);
    }

但是为什么原木神奇地好呢?

当我使用日志记录时,我希望底层组件能够正常工作。 它不是确保并发访问的任何容器。

我读过,主流操作系统使用线程安全的io调用,这些调用也不可中断,并且存在非线程安全的调用。

您可以在此处阅读,但我认为标记的答案根本不正确: fwrite是原子的吗?

换句话说,我从来没有任何破损的日志。 就像在数据库中INSERT 是否插入行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM