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 for Rails.logger = Rails :: logger.instance_variable_get(:@ logger).instance_variable_get(:@ log)
Rails 3 setter for 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)替换getter,几乎似乎工作.活动的第一部分“开始…”转到新的日志文件,但之后的所有内容都将转到默认日志文件(Rails.logger在中间件更改之前).
Rails.instance_variable_get(:@ logger)不是Rails 4中最低级别的Rails 3 Rails :: logger.instance_variable_get(:@ logger).instance_variable_get(:@ log)用于获取/设置Rails.logger或那里是在我的中间件在我设置之后覆盖它的过程中的其他事情.
任何线索?
更新:
要澄清,上面发布的解决方案按照Rails 3的预期工作.在特殊环境中可能或可能没有的限制(例如,如果解决方案可能无法在线程服务器环境中运行)在这一点上是可以的,在这个时候没有经验的障碍,因此在这个问题的Rails 4解决方案中,这些限制也是一样.
解决方法
def initialize(app) @app = app @logger = Rails.instance_variable_get(:@logger) @reports_api_controller_logger = Logger.new( Rails.root.join('log',1000000) end def call(env) if env['PATH_INFO'] =~ /api\/v.*\/reports.*/ Rails.instance_variable_set(:@logger,@reports_api_controller_logger) ActionController::Base.logger = @reports_api_controller_logger ActiveRecord::Base.logger = @reports_api_controller_logger ActionView::Base.logger = @reports_api_controller_logger else Rails.instance_variable_set(:@logger,@logger) ActionController::Base.logger = @logger ActiveRecord::Base.logger = @logger ActionView::Base.logger = @logger end @app.call(env) end
这真的是一个hack-ish解决方案,并根据您的需要修改正则表达式.
告诉我,如果这不适合你.