当两个脚本实例同时写入日志时,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脚本实例将并行写入同一日志文件.
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屋!