从Rails 3中的默认ActionController LogSubscriber修改日志格式和内容 [英] Modify log format and content from default ActionController LogSubscriber in Rails 3

查看:74
本文介绍了从Rails 3中的默认ActionController LogSubscriber修改日志格式和内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

上下文:

在Rails 3项目中,我想(大量)自定义来自ActionController的处理"和已完成"日志行的格式和内容.这是为了使它们与较旧的Rails 2.3应用程序的(也是自定义)格式匹配,从而允许重复使用各种分析工具.将它们设置为固定字段(在必要时使用占位符)还使使用awk对它们进行即席查询,或将它们加载到db或splunk中而无需进行智能分析变得更加容易.

In a rails 3 project I want to customise (heavily) the format and content of the "Processing" and "Completed in" log lines from ActionController. This is in order to have them match the (also custom) format of an older rails 2.3 app, allowing re-use of various analysis tools. Making them fixed-field (by use of place-holders where necessary) also makes it far easier to do ad-hoc queries on them with (say) awk, or to load them into a db or splunk without smart parsing.

我通过分叉rails和修补来快速而繁重地实现了这一目标. LogSubscriber,但我现在正在寻求以正确的方式进行操作.

I've achieved this goal quickly and heavy-handedly by forking rails and patching the LogSubscriber in question, but I am now looking to do it the right way.

这是我想做的 :

Here's what I think I want to do:

  1. 创建一个继承ActionController::LogSubscriberLogSubscriber.
  2. 仅覆盖start_processingprocess_action方法.
  3. 退订原始的ActionController::LogSubscriber,该类会在加载类后立即进行注册. 这是我坚持的步骤.
  4. 使用attach_to将我的自定义订户附加到:action_controller.
  1. Create a LogSubscriber inheriting ActionController::LogSubscriber.
  2. Override only the start_processing and process_action methods.
  3. Unsubscribe the original ActionController::LogSubscriber, which (sadly) registers itself as soon as the class is loaded. This is the step I'm stuck on.
  4. Attach my custom subscriber to :action_controller, using attach_to.

我注意到,如果将默认ActionController的日志订阅者的连接作为配置步骤而不是

I note that things would be easier if the hook-up of the default ActionController's log subscriber were done as a config step, rather than on class load.

问题:

假设上述方法适用,我如何取消订阅或取消附加默认日志订阅者 ActiveSupport :: LogSubscriber 提供

Assuming the approach outlined above is suitable, how can I unsubscribe or unattach the default log subscriber ActionController::LogSubscriber? The base class, ActiveSupport::LogSubscriber provides attach_to but no means of detaching.

或者,改变上述类(a

Alternatively, what is the cleanest way of altering the behaviour of (or entirely suppressing) the two methods (start_processing, process_action) in the above mentioned class, ActionController::LogSubscriber.

当然,我也欢迎任何其他(可维护)方法,该方法可完全自定义上述两行的日志格式.

Of course, I'd also welcome any other (maintainable) approach which provides full freedom in customizing the log format of the two lines mentioned.

不合适的方法:

  • My problem cannot be solved by adding instrumentation, as documented nicely by mnutt.
  • I'd like to avoid monkey-patching, or hacking in a way that may break when the rails implementation (not interface) changes.

参考:

  • Docs and Source for ActiveSupport::LogSubscriber
  • Source for ActionController::LogSubscriber
  • Docs, Source, and RailsCast for ActiveSupport::Notifications

推荐答案

我已经制定了以下解决方案.

I have worked out the following solution.

我对此方面并不特别满意(例如,必须取消对"process_action.action_controller"的所有关注),我当然会接受更好的答案.

I'm not particularly happy with aspects of it (for example, having to unsubscribe ALL interest in 'process_action.action_controller'), and I'll certainly accept a better answer.

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

We add the following as config/initializers/custom_ac_log_subscriber.rb

module MyApp
  class CustomAcLogSubscriber < ActiveSupport::LogSubscriber
    INTERNAL_PARAMS = ActionController::LogSubscriber::INTERNAL_PARAMS

    #Do your custom stuff here. (The following is much simplified).
    def start_processing(event)
      payload = event.payload
      params  = payload[:params].except(*INTERNAL_PARAMS)
      info "Processing #{payload[:controller]}##{payload[:action]} (...)"
      info "  Parameters: #{params.inspect}" unless params.empty?
    end

    def process_action(event)
      payload   = event.payload
      message = "Completed in %.0fms [#{payload[:path]}]" % event.duration
      info(message)
    end

    def logger
      ActionController::Base.logger
    end
  end
end

#Prevent ActionController::LogSubscriber from also acting on these notifications
#Note that the following undesireably unregisters *everyone's*
#interest in these.  We can't target one LogSubscriber, it seems(?)
%w(process_action start_processing).each do |evt|
  ActiveSupport::Notifications.unsubscribe "#{evt}.action_controller"
end

#Register our own interest
MyApp::CustomAcLogSubscriber.attach_to :action_controller

关于中止初始方法的注意事项:

最初,我尝试取消注册默认LogSubscriber的方法,目的是让我们的自定义用户继承并完成所有工作(而无需重复).

I initially attempted an approach of unregistering the default LogSubscriber, with the intention that our custom one would inherit and do all the work (without having to reimpl).

但是,有很多问题.

1)仅按以下步骤删除LogSubscriber是不够的:

1) It's not enough to remove the LogSubscriber as follows:

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

由于通知请求仍处于注册状态.

As the request for notifications remains registered.

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

2) Further, when you inherit a LogSubscriber and register it, it appears any non-overridden methods will not be called using the inherited implementation.

这篇关于从Rails 3中的默认ActionController LogSubscriber修改日志格式和内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆