У меня есть приложение, которое должно регистрировать каждую транзакцию. Каждое сообщение журнала сбрасывается, потому что мы должны иметь запись о том, что произошло до сбоя. Мне и моим коллегам было любопытно, как добиться эффекта производительности буферизации, гарантируя, что сообщение журнала вышло из процесса.
Что мы придумали это:
- сделать FIFO, в который приложение может написать, и
- перенаправить содержимое этого FIFO в обычный файл через
cat
.
То есть то, что обычно было:
app --logfile logfile.txt
сейчас:
mkfifo logfifo
cat logfifo &> logfile.txt &
app --logfile logfifo
Есть ли какие-либо ошибки в этом подходе? Это сработало, когда мы протестировали его, но мы хотим быть абсолютно уверены, что сообщения попадут в файл перенаправления даже в случае сбоя исходного приложения.
(У нас нет исходного кода для приложения, поэтому о программных решениях не может быть и речи. Кроме того, приложение не будет записывать в него stdout
, поэтому вопрос о передаче напрямую другой команде исключен. Поэтому syslog
это невозможно .)
Обновление: я добавил награду. Принятый ответ будет не включать в себя logger
по той простой причине , что logger
это не то , что я спросил о. Как говорится в первоначальном вопросе, я ищу только ошибки в использовании FIFO.
Ответы:
Обратите внимание, что в программировании обычно требуется fifo, когда записанное количество может превышать считываемое.
Таким образом, fifo не будет работать абсолютно гладко, как вы ожидаете, но решит вашу главную проблему, представляя другую.
Есть три возможных предостережения.
Это будет означать, что ваша проблема (эмулировать буферизованный ввод-вывод при небуферизованной записи) будет решена. Это связано с тем, что новый «предел» в вашем FIFO фактически станет скоростью, с которой любая утилита записывает то, что находится в канале на диск (который, вероятно, будет буферизован для ввода-вывода).
Тем не менее, писатель становится зависимым от вашего читателя журнала для работы. Если читатель перестает внезапно читать, писатель будет блокировать. Если считыватель внезапно завершает работу (допустим, у вас заканчивается свободное место на диске), то пишущий SIGPIPE и, вероятно, завершит работу.
Еще один момент, который стоит упомянуть: если сервер паникует, а ядро перестает отвечать, вы можете потерять до 64 КБ данных, которые были в этом буфере.
Другой способ исправить это - записать логи в tmpfs (/ dev / shm в linux) и привязать вывод к фиксированному месту на диске. При этом существуют менее строгие ограничения на выделение памяти (не 64 КБ, как правило, 2 ГБ!), Но он может не сработать, если у автора нет динамического способа повторного открытия файлов журналов (вам придется периодически очищать журналы от tmpfs). Если сервер паникует в этом методе, вы можете потерять ОЧЕНЬ больше данных.
источник
/dev/shm
. Мы тоже обдумали это, хотя это ускользнуло от меняtail -f
.Что происходит, когда ваш
cat logfifo
процесс умирает, кто-то случайно его убивает или кто-то случайно указывает на неправильное место?Мой опыт показывает, что
app
он быстро заблокируется и зависнет. Я попробовал это с Tomcat, Apache и несколькими небольшими домашними приложениями и столкнулся с той же проблемой. Я никогда не исследовал очень далеко, потому чтоlogger
простое перенаправление ввода / вывода делало то, что я хочу. Я обычно не нуждаюсь в полноте регистрации, которую вы пытаетесь использовать. И, как вы говорите, вы не хотите регистратор.Существует некоторая дискуссия по этой проблеме в неблокирующем Linux fifo (по запросу) .
источник
Ваши возможности довольно ограничены приложением, но то, что вы тестировали, будет работать.
Мы делаем что-то похожее с лаками и varnishncsa, чтобы логи get где-то были нам полезны. У нас есть fifo, и мы просто читаем его с помощью syslog-ng и отправляем туда, где нам нужно. Мы обрабатываем около 50 ГБ и до сих пор не сталкивались с такой проблемой
источник
Среда - CentOS, и приложение записывает в файл ...
Вместо отправки в обычный файл, я бы отправил вывод в syslog и убедился, что сообщения syslog отправляются на центральный сервер, а также локально.
Вы должны быть в состоянии использовать скрипт оболочки следующим образом:
Вы также можете получить вход (в
logger
) изcat
илиtail -f
в трубу:Единственная проблема заключается в том, что оно не дифференцируется в зависимости от важности сообщения журнала (все это ЗАМЕЧАНИЕ ), но, по крайней мере, оно регистрируется и также отправляется вне хоста на центральный сервер.
Настройка системного журнала зависит от того, какой сервер вы используете. Есть
rsyslog
иsyslog-ng
(оба очень способные).РЕДАКТИРОВАТЬ : Пересмотрен после получения дополнительной информации от автора.
источник
stdout
. ОС - это CentOS (я пометил вопрос как linux , но, думаю, это легко пропустить). Все сообщения имеют одинаковую важность, поэтому нет разницы между уведомлением и ошибкой в этом приложении.Slow query detected
иDatabase halted
?Ты пишешь:
Вы пробовали войти в "файл"
/dev/stdout
? Это может позволить вам сделать что-то вроде:источник
Нет смысла записывать данные в fifo и затем записывать их в файл другим процессом. Просто пишите напрямую в файл, и как только он
write()
вернется, он в руках ядра; он все равно запишет его на диск в случае сбоя приложения.источник
fsync()
для ожидания каждой записи на диске, и вы не хотите, чтобы это произошло (риск потери в случае сбоя системы)?write()
возвращения приложение может аварийно завершить работу, если оно того захочет - данные попадут на диск до тех пор, пока не произойдет сбой ядра.