# encoding: utf-8 module OneApm module Agent module Instrumentation module Rails3 module ActionController # determine the path that is used in the metric name for # the called controller action def oneapm_metric_path(action_name_override = nil) action_part = action_name_override || action_name if action_name_override || self.class.action_methods.include?(action_part) "#{self.class.controller_path}/#{action_part}" else "#{self.class.controller_path}/(other)" end end def process_action(*args) perform_action_with_oneapm_trace(:category => :controller, :name => self.action_name, :path => oneapm_metric_path, :params => request.filtered_parameters, :class_name => self.class.name) do super end end end module ActionView module OneApm extend self def template_metric(identifier, options = {}) if options[:file] "file" elsif identifier.nil? OneApm::Transaction::OA_UNKNOWN_METRIC elsif identifier.include? '/' # this is a filepath identifier.split('/')[-2..-1].join('/') else identifier end end def render_type(file_path) file = File.basename(file_path) if file.starts_with?('_') return 'Partial' else return 'Rendering' end end end end end end end end LibraryDetection.defer do @name = :rails3_controller depends_on do defined?(::Rails) && ::Rails::VERSION::MAJOR.to_i == 3 end depends_on do defined?(ActionController) && defined?(ActionController::Base) end executes do OneApm::Manager.logger.info 'Installing Rails 3 Controller instrumentation' end executes do class ActionController::Base include OneApm::Agent::Instrumentation::TransactionBase include OneApm::Agent::Instrumentation::Rails3::ActionController end end end LibraryDetection.defer do @name = :rails30_view depends_on do defined?(::Rails) && ::Rails::VERSION::MAJOR.to_i == 3 && ::Rails::VERSION::MINOR.to_i == 0 end depends_on do !OneApm::Manager.config[:disable_view_instrumentation] end executes do OneApm::Manager.logger.info 'Installing Rails 3.0 view instrumentation' end executes do ActionView::Template.class_eval do include OneApm::Support::MethodTracer def render_with_oneapm(*args, &block) options = if @virtual_path && @virtual_path.starts_with?('/') # file render {:file => true } else {} end template_metric = OneApm::Agent::Instrumentation::Rails3::ActionView::OneApm.template_metric(@identifier, options) render_type = OneApm::Agent::Instrumentation::Rails3::ActionView::OneApm.render_type(@identifier) str = "View/#{template_metric}/#{render_type}" trace_execution_scoped str do render_without_oneapm(*args, &block) end end alias_method :render_without_oneapm, :render alias_method :render, :render_with_oneapm end end end LibraryDetection.defer do @name = :rails31_view # We can't be sure that this will work with future versions of Rails 3. # Currently enabled for Rails 3.1 and 3.2 depends_on do defined?(::Rails) && ::Rails::VERSION::MAJOR.to_i == 3 && ([1,2].member?(::Rails::VERSION::MINOR.to_i)) end depends_on do !OneApm::Manager.config[:disable_view_instrumentation] end executes do OneApm::Manager.logger.info 'Installing Rails 3.1/3.2 view instrumentation' end executes do ActionView::TemplateRenderer.class_eval do include OneApm::Support::MethodTracer # namespaced helper methods def render_with_oneapm(context, options) # This is needed for rails 3.2 compatibility @details = extract_details(options) if respond_to? :extract_details, true identifier = determine_template(options) ? determine_template(options).identifier : nil scope_name = "View/#{OneApm::Agent::Instrumentation::Rails3::ActionView::OneApm.template_metric(identifier, options)}/Rendering" trace_execution_scoped scope_name do render_without_oneapm(context, options) end end alias_method :render_without_oneapm, :render alias_method :render, :render_with_oneapm end ActionView::PartialRenderer.class_eval do include OneApm::Support::MethodTracer def instrument_with_oneapm(name, payload = {}, &block) identifier = payload[:identifier] scope_name = "View/#{OneApm::Agent::Instrumentation::Rails3::ActionView::OneApm.template_metric(identifier)}/Partial" trace_execution_scoped(scope_name) do instrument_without_oneapm(name, payload, &block) end end alias_method :instrument_without_oneapm, :instrument alias_method :instrument, :instrument_with_oneapm end end end