特定のコントローラー#アクションのフィルター(コールバック関数)の実行時間をNew Relicにレポートするためのinitializerファイルを書いた

- コントローラのbefore_actionとかで指定されているfilter(callback関数)の実行時間をNew Relicに送信するためのinitializerファイル
- callback関数がProcで指定されている場合の処理がキツかった。(結局ProcをProcで挟み込むことで対応)
- 黒魔術に黒魔術を重ねてます。動作確認はしていますが、正確な保証はないです。

```rb:config/initializers/trace_controller_filters.rb
# This initializer is to make a configuration to report the execution time of filters(callbacks)
# for all actions of specified Controller class.
#
# Controller(s) to be traced can be configurable by environment variable 'FILTER_TRACED_CONTROLLERS'
# Set it this way, say in .env file:
# (Ex) FILTER_TRACED_CONTROLLERS="ProjectsController Api::V2::ProjectsController UsersController"

Rails.application.config.after_initialize do
  if ENV['NEW_RELIC_ENABLED'] && ENV['FILTER_TRACED_CONTROLLERS'].present?
    traced_controllers = []
    ENV['FILTER_TRACED_CONTROLLERS'].split.each do |controller_str|
      begin
        traced_controllers << controller_str.constantize
      rescue
        puts "===== #{controller_str} in FILTER_TRACED_CONTROLLERS has not been found ====="
      end
    end

    traced_controllers.each do |controller|
      begin
        controller.class_eval do
          self.include ::NewRelic::Agent::MethodTracer
          self._process_action_callbacks().send(:chain).each do |callback|
            case callback.raw_filter
            when Symbol
              self.add_method_tracer callback.raw_filter
            when Proc
              unless callback.instance_variable_get(:@_already_wrapped)
                callback.instance_variable_set(:@_already_wrapped, true)
                original_filter = callback.raw_filter
                wrapped_filter = Proc.new{
                  # execution time of 'original_filter' should be traced only if 'self' (= a Controller instance
                  # which is executing current Proc) is an instance of one of FILTER_TRACED_CONTROLLERS.
                  if traced_controllers.include? self.class
                    self.class.trace_execution_scoped("Custom/ProcFilter/Proc_#{original_filter.source_location[0].gsub('/', ':')}}") do
                      # execute 'original_filter' in the context of 'self' (= a Controller instance which is executing current proc),
                      # which is not in the context of current 'wrapped_filter' Proc.
                      # just as is done originally in ActiveSupport::Callbacks#run_callbacks.
                      # See: https://github.com/rails/rails/blob/master/activesupport/lib/active_support/callbacks.rb#L645-L647
                      self.instance_exec(&original_filter)
                    end
                  else
                    self.instance_exec(&original_filter)
                  end
                }
                callback.instance_variable_set(:@filter, wrapped_filter)
                callback.instance_variable_set(:@key, callback.send(:compute_identifier, callback.raw_filter))
              end
            end
          end
        end
        puts "===== Filters of actions for #{controller} will be reported to New Relic ====="
      rescue
        puts "===== #{controller} in FILTER_TRACED_CONTROLLERS has not been found ====="
      end
    end
  end
end
```