从Rails 3中的默认ActionController LogSubscriber修改日志格式和内容 [英] Modify log format and content from default ActionController LogSubscriber in Rails 3
问题描述
上下文:
在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:
- 创建一个继承
ActionController::LogSubscriber
的LogSubscriber
. - 仅覆盖
start_processing
和process_action
方法. - 退订原始的
ActionController::LogSubscriber
,该类会在加载类后立即进行注册. 这是我坚持的步骤. - 使用
attach_to
将我的自定义订户附加到:action_controller
.
- Create a
LogSubscriber
inheritingActionController::LogSubscriber
. - Override only the
start_processing
andprocess_action
methods. - Unsubscribe the original
ActionController::LogSubscriber
, which (sadly) registers itself as soon as the class is loaded. This is the step I'm stuck on. - Attach my custom subscriber to
:action_controller
, usingattach_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.
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屋!