При использовании Monolog с StreamHandler
, это нормальная ситуация, когда несколько экземпляров скрипта PHP будут записывать в один и тот же файл журнала параллельно.
(например, в моем приложении Symfony, когда несколько пользователей одновременно открывают «страницу входа», это может привести к нескольким экземплярам сценария моего приложения (app.php
) работает и таким образом два экземпляра монолога StreamHandler
будет писать в то же самое app/logs/prod.log
.)
Как получилось, что, несмотря на одновременную запись в файл, каждая строка журнала не разбита посередине и не перепутана? Как получается, что ситуация ниже никогда не случается:
Я попытался посмотреть на исходный код StreamHanler
https://github.com/Seldaek/monolog/blob/master/src/Monolog/Handler/StreamHandler.php#L93
Но я не вижу должного контроля параллелизма, есть flock()
но похоже отключен (->useLocking=false
) в конфигурации по умолчанию (Symfony), и кажется, что журналы без него хорошо …
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
в базе данных. Либо вставлена строка, либо нет.
Других решений пока нет …