Skip to content

Commit

Permalink
Fixed: ActionController patching conflict with other libraries that p…
Browse files Browse the repository at this point in the history
…atch #process_action
  • Loading branch information
delner committed Apr 6, 2018
1 parent 9dfc349 commit 9006641
Showing 1 changed file with 66 additions and 30 deletions.
96 changes: 66 additions & 30 deletions lib/ddtrace/contrib/rails/core_extensions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 9006641

Please sign in to comment.