diff --git a/lib/ddtrace/contrib/rails/core_extensions.rb b/lib/ddtrace/contrib/rails/core_extensions.rb index ecd3f41cbc2..c2a9895d70f 100644 --- a/lib/ddtrace/contrib/rails/core_extensions.rb +++ b/lib/ddtrace/contrib/rails/core_extensions.rb @@ -157,40 +157,76 @@ def patch_action_controller def patch_process_action do_once(:patch_process_action) do - ::ActionController::Instrumentation.class_eval do - def process_action_with_datadog(*args) - # mutable payload with a tracing context that is used in two different - # signals; it propagates the request span so that it can be finished - # no matter what - payload = { - controller: self.class, - action: action_name, - headers: { - # The exception this controller was given in the request, - # which is typical if the controller is configured to handle exceptions. - request_exception: request.headers['action_dispatch.exception'] - }, - tracing_context: {} - } - - begin - # process and catch request exceptions - Datadog::Contrib::Rails::ActionController.start_processing(payload) - result = process_action_without_datadog(*args) - payload[:status] = response.status - result - rescue Exception => e - payload[:exception] = [e.class.name, e.message] - payload[:exception_object] = e - raise e + if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.0.0') + ::ActionController::Instrumentation.send(:prepend, ActionControllerPatch) + else + ::ActionController::Instrumentation.class_eval do + def process_action_with_datadog(*args) + # mutable payload with a tracing context that is used in two different + # signals; it propagates the request span so that it can be finished + # no matter what + payload = { + controller: self.class, + action: action_name, + headers: { + # The exception this controller was given in the request, + # which is typical if the controller is configured to handle exceptions. + request_exception: request.headers['action_dispatch.exception'] + }, + tracing_context: {} + } + + begin + # process and catch request exceptions + Datadog::Contrib::Rails::ActionController.start_processing(payload) + result = process_action_without_datadog(*args) + payload[:status] = response.status + result + rescue Exception => e + payload[:exception] = [e.class.name, e.message] + payload[:exception_object] = e + raise e + end + ensure + Datadog::Contrib::Rails::ActionController.finish_processing(payload) end - ensure - Datadog::Contrib::Rails::ActionController.finish_processing(payload) + + alias_method :process_action_without_datadog, :process_action + alias_method :process_action, :process_action_with_datadog end + end + end + end - alias_method :process_action_without_datadog, :process_action - alias_method :process_action, :process_action_with_datadog + module ActionControllerPatch + def process_action(*args) + # mutable payload with a tracing context that is used in two different + # signals; it propagates the request span so that it can be finished + # no matter what + payload = { + controller: self.class, + action: action_name, + headers: { + # The exception this controller was given in the request, + # which is typical if the controller is configured to handle exceptions. + request_exception: request.headers['action_dispatch.exception'] + }, + tracing_context: {} + } + + begin + # process and catch request exceptions + Datadog::Contrib::Rails::ActionController.start_processing(payload) + result = super(*args) + payload[:status] = response.status + result + rescue Exception => e + payload[:exception] = [e.class.name, e.message] + payload[:exception_object] = e + raise e end + ensure + Datadog::Contrib::Rails::ActionController.finish_processing(payload) end end end