Redirecione a saída do criador de logs para um controlador específico no Rails 4
Criei uma solução com base na resposta da minha pergunta anteriorRedirecione a saída do criador de logs para um controlador específico no Rails 3 para Rails 3. Funciona muito bem, no entanto, agora estou tentando aplicar a mesma solução baseada em middleware a um projeto do Rails 4, mas existem algumas diferenças que impedem a mesma solução de funcionar.
A solução 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
acima:
Trilhos 3getter para Rails.logger =Rails::logger.instance_variable_get(:@logger).instance_variable_get(:@log)
Trilhos 3setter para Rails.logger (configurando para @my_logger) =Rails::logger.instance_variable_get(:@logger).instance_variable_set(:@log,@my_logger)
Uma coisa que notei imediatamente é que, no Rails 4, o acimaRails::logger.instance_variable_get(:@logger).instance_variable_get(:@log)
retorna nulo.
Fazendo check-in no console do Rails 4, vejo queRails.instance_variable_get(:@logger)
retorna#<ActiveSupport::Logger:0x007f84ff503a08 ....>
Eu tentei substituir ogetter comRails.instance_variable_get(:@logger)
e o levantador comRails.instance_variable_set(:@logger,my_logger)
e quase parece funcionar. A primeira parte da atividade, o "Iniciado ...", vai para o novo arquivo de log, mas tudo depois vai para o arquivo de log padrão (o Rails.logger antes do middleware o alterar).
OuRails.instance_variable_get(:@logger)
não é o nível mais baixo equivalente no Rails 4 para o Rails 3Rails::logger.instance_variable_get(:@logger).instance_variable_get(:@log)
paraobtendo / configurando o Rails.logger ou há algo mais adiante no processo após o meu middleware que está sobrescrevendo isso depois que eu o defini.
Alguma pista?
Atualizar:
Para esclarecer, a solução postada acima funciona conforme o esperado no Rails 3. Quaisquer limitações que possam ou não ter em ambientes especiais (como se a solução não funcionar em ambientes de servidor de threading, se for o caso) estão corretas neste momento e não foram experimentados como obstáculos no momento, portanto, essas mesmas limitações também são válidas em uma solução do Rails 4 para esta pergunta.