重定向Rails 4中特定控制器的记录器输出

Str*_*ine 16 logging rack ruby-on-rails ruby-on-rails-4

我已经根据我之前的问题中的答案构建了一个解决方案.Rails 3 for 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
Run Code Online (Sandbox Code Playgroud)

在上面:

Rails.getger = Rails 3 getterRails::logger.instance_variable_get(:@logger).instance_variable_get(:@log)

用于Rails.logger的Rails 3 setter(设置为@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)回报为零.

检查Rails 4控制台,我确实看到了Rails.instance_variable_get(:@logger)返回#<ActiveSupport::Logger:0x007f84ff503a08 ....>

我试着更换吸气Rails.instance_variable_get(:@logger),并与二传手Rails.instance_variable_set(:@logger,my_logger)和几乎似乎工作.活动的第一部分,"已启动..."转到新的日志文件,但之后的所有内容都转到默认日志文件(中间件更改之前的Rails.logger).

无论Rails.instance_variable_get(:@logger)是不是水平相当于最低的轨道4到Rails 3中Rails::logger.instance_variable_get(:@logger).instance_variable_get(:@log)获取/设置的Rails.logger或出现在我的中间件后程别的东西后来被覆盖在此之后我将它设置.

有线索吗?

更新:

为了澄清,上面发布的解决方案在Rails 3中按预期工作.在特殊环境中可能会或可能不会有任何限制(例如,如果解决方案可能无法在线程服务器环境中工作,如果是这种情况)在这一点上是正常的,因此,在这个问题的Rails 4解决方案中,这些相同的限制也没有成为障碍.

Jag*_*ngh 6

在攻击Rails代码一天后,我想我已经找到了解决问题的黑客解决方案.

您需要编辑call方法和initialize方法如下:

def initialize(app)
  @app = app
  @logger = Rails.instance_variable_get(:@logger)
  @reports_api_controller_logger = Logger.new(
      Rails.root.join('log', REPORTS_API_CONTROLLER_LOGFILE),
      10, 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
Run Code Online (Sandbox Code Playgroud)

这实际上是一个黑客解决方案,并根据您的需要修改正则表达式.

告诉我这是否对你不起作用.


bbo*_*ozo -1

为 1 个控制器使用不同的日志类的方法有一个缺点,即它无法在线程服务器上工作,线程服务器现在不仅在 JRuby 中很流行,而且在Heroku 的帮助下, MRI 也很流行

经过一周的思考后,到目前为止我唯一的想法是将日志通过管道传输到 syslog 并使用 syslog 的工具将它们分割成单独的文件。

它仍然需要修补Logger以包含允许拆分的字符串(例如从跟踪#caller到日志文件添加格式化的行)。

B 计划是引入我自己的记录器,并简单地在该控制器中记录我需要的内容。例如,如果足够的话,您可以轻松转储参数和响应