ruby-on-rails – 修改Rails 3中默认ActionController LogSubscriber的日志格式和内容

前端之家收集整理的这篇文章主要介绍了ruby-on-rails – 修改Rails 3中默认ActionController LogSubscriber的日志格式和内容前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
语境:

在rails 3项目中,我想(大量)自定义ActionController中“Processing”和“Completed in”日志行的格式和内容.这是为了让它们与旧版rails 2.3 app的(也是自定义)格式相匹配,允许重复使用各种分析工具.使它们成为固定字段(通过在必要时使用占位符)也可以更容易地使用(例如)awk对它们进行即席查询,或者在没有智能解析的情况下将它们加载到db或splunk中.

我通过分叉铁路和patching问题的LogSubscriber迅速而严厉地实现了这个目标,但我现在正在寻找以正确的方式做到这一点.

这是我想我想做的事情:

>创建一个继承ActionController :: LogSubscriber的LogSubscriber.
>仅覆盖start_processing和process_action方法.
>取消订阅原始的ActionController :: LogSubscriber,它(遗憾地)在加载类后立即注册.这是我坚持的步骤.
>使用attach_to将我的自定义订阅者附加到:action_controller.

我注意到,如果默认ActionController的日志订阅者的连接是作为配置步骤而不是on class load完成的,事情会更容易.

题:

假设上述方法合适,我如何取消订阅或取消附加默认日志订户ActionController::LogSubscriber?基类ActiveSupport::LogSubscriber提供attach_to但没有分离方法.

或者,在上面提到的类ActionController::LogSubscriber中,改变(或完全抑制)两种方法(start_processing,process_action)的行为的最简洁方法是什么.

当然,我也欢迎任何其他(可维护的)方法,它可以完全自由地定制所提到的两行的日志格式.

不合适的方法

>我的问题无法通过添加检测来解决,如documented nicely by mnutt所示.
>我想避免猴子修补,或者以一种可能在rails实现(不是接口)改变时破坏的方式进行黑客攻击.

参考文献:

> DocsSource for ActiveSupport::LogSubscriber
> Source for ActionController::LogSubscriber
> Docs,SourceRailsCast for ActiveSupport::Notifications

解决方法

我已经找到了以下解决方案.

我对它的各个方面并不特别满意(例如,必须取消订阅所有对’process_action.action_controller’的兴趣),我当然会接受更好的答案.

我们将以下内容添加为config / initializers / custom_ac_log_subscriber.rb

  1. module MyApp
  2. class CustomAcLogSubscriber < ActiveSupport::LogSubscriber
  3. INTERNAL_PARAMS = ActionController::LogSubscriber::INTERNAL_PARAMS
  4.  
  5. #Do your custom stuff here. (The following is much simplified).
  6. def start_processing(event)
  7. payload = event.payload
  8. params = payload[:params].except(*INTERNAL_PARAMS)
  9. info "Processing #{payload[:controller]}##{payload[:action]} (...)"
  10. info " Parameters: #{params.inspect}" unless params.empty?
  11. end
  12.  
  13. def process_action(event)
  14. payload = event.payload
  15. message = "Completed in %.0fms [#{payload[:path]}]" % event.duration
  16. info(message)
  17. end
  18.  
  19. def logger
  20. ActionController::Base.logger
  21. end
  22. end
  23. end
  24.  
  25. #Prevent ActionController::LogSubscriber from also acting on these notifications
  26. #Note that the following undesireably unregisters *everyone's*
  27. #interest in these. We can't target one LogSubscriber,it seems(?)
  28. %w(process_action start_processing).each do |evt|
  29. ActiveSupport::Notifications.unsubscribe "#{evt}.action_controller"
  30. end
  31.  
  32. #Register our own interest
  33. MyApp::CustomAcLogSubscriber.attach_to :action_controller

关于中止初始方法的说明:

我最初尝试了取消注册默认LogSubscriber的方法,意图是我们的自定义将继承并完成所有工作(无需重新注册).

但是,存在许多问题.

1)删除LogSubscriber是不够的,如下所示:

  1. ActiveSupport::LogSubscriber.log_subscribers.delete_if{ |ls|
  2. ls.instance_of? ActionController::LogSubscriber }

由于通知请求仍在注册.

2)此外,当您继承LogSubscriber并注册它时,似乎不会使用继承的实现调用任何未重写的方法.

猜你在找的Ruby相关文章