Подтвердить что ты не робот

Может ли Ruby stdlib Logger класс безопасно обрабатывать писателей из нескольких процессов?

Я работаю над библиотекой Ruby, которая должна выполнять журналирование. В идеале я хотел бы, чтобы несколько рабочих процессов могли входить в один файл. Если посмотреть на источник класса Logger из стандартной библиотеки Ruby, я вижу, что прилагаются усилия для синхронизации записи в журнал из нескольких потоков (как указано в ответе Является ли Ruby's stdlib класс Logger с потоком-безопасностью?).

Кажется, существует аналогичная проблема, когда несколько процессов записывают в один и тот же файл журнала: в зависимости от того, как лежащие в основе слои решают блокировать/разделять записи, каждое сообщение журнала может не поддерживать его целостность.

Итак, существует ли способ использования стандартного класса Logger, позволяющего нескольким процессам безопасно регистрироваться в одном файле? Если нет, как это обычно выполняется в проектах Ruby?

Вот что я подразумеваю под "безопасно":

  • Каждая строка журнала "атомарная" - появляется полностью, без прерывания до начала следующего сообщения. например ничего как [1/1/2013 00:00:00] (PID N) LOGMESS[1/1/2013 00:00:01] (PID M) LOGMESSAGE2\nAGE1
  • Журнальные сообщения не обязательно должны строго упорядочиваться между процессами, пока метки времени, отображаемые в журнале, верны.

Обновление

Я решил взять совет оловянного человека и написать тест, который вы можете найти здесь: https://gist.github.com/4370423

Краткая версия: Winfield корректна, по крайней мере, при использовании Logger по умолчанию, это безопасно использовать из нескольких процессов одновременно (для определения "безопасный", приведенный выше).

Ключевым фактором является то, что если задан путь к файлу (вместо уже открытого объекта IO), Logger откроет файл с режимом WRONLY|APPEND и установит sync=true на нем. Сочетание этих двух вещей (по крайней мере, на моем тестировании в Mac OS X), похоже, позволяет безопасно регистрировать одновременно несколько процессов. Если вы хотите передать уже открытый объект ввода-вывода, просто убедитесь, что вы создали его таким же образом.

4b9b3361

Ответ 1

Да, вы можете безопасно записывать чередующиеся данные журнала в один файл журнала так, как вы описали.

Однако вам лучше регистрировать отдельный журнал для каждого процесса или использовать объединенную систему ведения журнала, такую ​​как syslog. Вот несколько причин, по которым:

  • Логарифмическое вращение/управление: обрезание/сканирование журналов затруднено, когда вам нужно координировать передачу сигналов несколькими процессами.
  • Данные с чередованием могут сбивать с толку, даже если вы вводите PID для устранения двусмысленности.

В настоящее время я управляю несколькими работниками Resque для каждой системы с одним файлом журнала и хочу, чтобы я разделил файл журнала для каждого рабочего. Это были трудные проблемы отладки и правильное управление журналами.