Я построил решение, основанное на ответе в предыдущем вопросе Перенаправить вывод журнала для конкретного контроллера в Rails 3 для Rails 3. Он отлично работает, однако сейчас Я пытаюсь применить одно и то же решение на основе промежуточного программного обеспечения к проекту Rails 4, но есть некоторые отличия, позволяющие работать с одним и тем же решением.
Решение Rails 3:
module MyApp
class LoggerMiddleware
REPORTS_API_CONTROLLER_PATH = %r|\A/api/v.*/reports.*|
REPORTS_API_CONTROLLER_LOGFILE = "reports_controller.log"
def initialize(app)
@app = app
@logger = Rails::logger
.instance_variable_get(:@logger)
.instance_variable_get(:@log)
@reports_api_controller_logger = Logger.new(
Rails.root.join('log', REPORTS_API_CONTROLLER_LOGFILE),
10, 1000000)
end
def call(env)
Rails::logger
.instance_variable_get(:@logger)
.instance_variable_set(:@log,
case env['PATH_INFO']
when REPORTS_API_CONTROLLER_PATH then
@reports_api_controller_logger
else
@logger
end
)
@app.call(env)
end
end
end
Rails.application.middleware.insert_before Rails::Rack::Logger, MyApp::LoggerMiddleware
в приведенном выше примере:
Rails 3 getter для Rails.logger = Rails::logger.instance_variable_get(:@logger).instance_variable_get(:@log)
Rails 3 setter для Rails.logger(установка на @my_logger) = Rails::logger.instance_variable_get(:@logger).instance_variable_set(:@log,@my_logger)
Одна вещь, которую я сразу заметил, это то, что в Rails 4 выше Rails::logger.instance_variable_get(:@logger).instance_variable_get(:@log)
возвращает nil.
Проверка в консоли Rails 4, я вижу, что Rails.instance_variable_get(:@logger)
возвращает #<ActiveSupport::Logger:0x007f84ff503a08 ....>
Я попытался заменить геттер на Rails.instance_variable_get(:@logger)
и setter с помощью Rails.instance_variable_set(:@logger,my_logger)
, и он почти срабатывает. Первая часть действия "Начат..." переходит к новому файлу журнала, но все после этого переходит в файл журнала по умолчанию (Rails.logger до того, как промежуточное программное обеспечение изменило его).
Либо Rails.instance_variable_get(:@logger)
не является эквивалентом минимального уровня в Rails 4 для Rails 3 Rails::logger.instance_variable_get(:@logger).instance_variable_get(:@log)
для получения/установки Rails.logger, или есть что-то еще в этом процессе после моего промежуточного программного обеспечения, которое перезаписывает это после того, как я установите его.
Любые подсказки?
Update:
Чтобы уточнить, решение, опубликованное выше, работает как ожидается в Rails 3. Любые ограничения, которые он может или не может иметь в специальных средах (например, если решение может не работать в средах с серверами потоков, если это так), в порядке этот момент и не испытывал в это время препятствия, поэтому эти же ограничения также одобрены в решении Rails 4 для этого вопроса.