当两个脚本实例同时写入日志时,Monolog编写的日志行如何不会被弄乱/混淆? [英] How come log lines written by Monolog don't get messed/mixed up when two script instances are writing to log concurrently?

查看:269
本文介绍了当两个脚本实例同时写入日志时,Monolog编写的日志行如何不会被弄乱/混淆?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

When using Monolog with StreamHandler, it is normal situation that several instances of PHP script would be writing to the same log file in parallel.

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

(eg. in my Symfony application, when mulitple users open "Login page" at the same time, it would result in multiple instances of my app script (app.php) running and thus two instances of Monolog StreamHandler would be writing into same app/logs/prod.log.)

为什么尽管同时写入文件,但每个日志行在中间都没有中断并弄乱了呢?以下情况永远不会发生:

How come that despite of concurrent writing to the file, each log lines is not broken in the middle and messed up? How come the situation below never happens:

    StreamHanler的
  • instance1 只写了一半的日志行
  • StreamHanler的
  • instance2 写下了上半场
  • instance1 写下了日志行的下半部分
  • instance2 写下了日志行的后半部分
  • 现在我们的日志文件一团糟,因为两行混合在一起.
  • instance1 of StreamHanler only wrote half of the log line,
  • instance2 of StreamHanler wrote it's first half
  • instance1 wrote second half of the log line
  • instance2 wrote second half of the log line
  • now our log file is a mess, because two lines are mixed.

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

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

But I do not see any proper concurrency control, there is a flock() but it seems to be disabled (->useLocking=false) in default (Symfony) configuration and it seems that logs are fine without it...

    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);
    }

但是为什么日志如此神奇呢?

But why are the logs magically fine?

推荐答案

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

When I use logging I would expect the underlying components to work correct. It's not any container you have to ensure concurrency access.

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

I've read, that the main stream operating systems use thread-safe io calls which are also not interruptable and there are non thread safe calls.

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

You can read here, but in my opinion the marked answer is not correct at all: Is fwrite atomic?

换句话说,我从未有过任何损坏的日志.就像数据库中的INSERT一样.是否插入了行.

In other words I've never had any broken logs. It's like INSERT in a database. Either there is a row inserted or not.

这篇关于当两个脚本实例同时写入日志时,Monolog编写的日志行如何不会被弄乱/混淆?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆