Динамически переопределить файл назначения всех выходных данных Logger в Rails - PullRequest
0 голосов
/ 12 октября 2018

Я использую жемчужину квартиры для мультитенантного приложения Rails 5.2.Я не уверен, что это даже имеет значение для моего вопроса, но просто дает некоторый контекст.

Есть ли способ переопределить регистратор Rails и перенаправить каждую отдельную запись журнала в файл на основе арендатора (базы данных), который

Мышление ... есть ли способ, который я могу monkeypatch в Logger, который изменит файл, записываемый в динамически?

Пример: я хочу, чтобы каждое сообщение об ошибке было направлено в файл дляэтот день.Таким образом, в конце недели будет 7 динамически генерируемых файлов для ошибок, которые возникали в каждый конкретный день.

Другой пример: перед тем, как писать какое-либо сообщение журнала сервера, проверьте, не было ли оно до 13:00.Если это до 13:00, напишите это в /log/before_1.log ... если это после 13:00, напишите это в /log/after_1.log

Глупые примеры ... но я хочу такой динамический контрольдо того, как написана какая-либо строка журнала.

Спасибо!

1 Ответ

0 голосов
/ 12 октября 2018

Обычно регистратор обычно настраивается для каждого сервера (или действительно для каждой среды), в то время как квартира устанавливает арендаторов для каждого запроса - это означает, что на практике это не очень хорошо работает.

Вы можете установить регистратор налюбой точке, назначив Rails.logger экземпляру регистратора.

Rails.logger = Logger.new(Rails.root.join('log/foo.log'), File::APPEND)

# or for multiple loggers
Rails.logger.extend(Logger.new(Rails.root.join('log/foo.log'), File::APPEND))

Однако не все так просто - вы не можете просто бросить это в ApplicationController и думать, что все просто как надо - это будет называться поздно, и большинство записей с важными вещаминапример, запрос или любые ошибки, которые всплывают до того, как контроллер попадет в журнал по умолчанию.

Что вы можете сделать, это написать собственный фрагмент middleware , который отключает журнал:

# app/middleware/tenant_logger.rb
class TenantLogger
  def initialize app
    @app = app
  end

  def call(env)
    file_name = "#{Appartment::Tenant.current}.log"
    Rails.logger = Logger.new(Rails.root.join('log', file_name), File::APPEND)
    @app.call(env)
  end
end

И смонтировать его после «лифта» в стеке промежуточного программного обеспечения:

Rails.application.config.middleware.insert_after Apartment::Elevators::Subdomain, TenantLogger

Однако, поскольку это довольно далеко в стеке промежуточного программного обеспечения, вы все равно пропустите довольно много важныхинформация, записанная промежуточным программным обеспечением, такая как Rails::Rack::Logger.

Использование тегированного регистратора, как предлагается в руководствах Rails с одним файлом, является гораздо лучшим решением.

...