Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add exception_controller option to Rails #320

Merged
merged 3 commits into from
Jan 24, 2018
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 23 additions & 2 deletions lib/ddtrace/contrib/rails/action_controller.rb
Original file line number Diff line number Diff line change
@@ -37,8 +37,9 @@ def self.finish_processing(payload)
span.resource = "#{payload.fetch(:controller)}##{payload.fetch(:action)}"
end

# set the parent resource if it's a `rack.request` span
if !span.parent.nil? && span.parent.name == 'rack.request'
# Set the parent resource if it's a `rack.request` span,
# but not if its an exception contoller.
if !span.parent.nil? && span.parent.name == 'rack.request' && !exception_controller?(payload)
span.parent.resource = span.resource
end

@@ -66,6 +67,26 @@ def self.finish_processing(payload)
rescue StandardError => e
Datadog::Tracer.log.error(e.message)
end

def self.exception_controller?(payload)
exception_controller_class = Datadog.configuration[:rails][:exception_controller]
controller = payload.fetch(:controller)
headers = payload.fetch(:headers)

# If no exception controller class has been set,
# guess whether this is an exception controller from the headers.
if exception_controller_class.nil?
!headers[:request_exception].nil?
# If an exception controller class has been specified,
# check if the controller is a kind of the exception controller class.
elsif exception_controller_class.is_a?(Class) || exception_controller_class.is_a?(Module)
controller <= exception_controller_class
# Otherwise if the exception controller class is some other value (like false)
# assume that this controller doesn't handle exceptions.
else
false
end
end
end
end
end
7 changes: 6 additions & 1 deletion lib/ddtrace/contrib/rails/core_extensions.rb
Original file line number Diff line number Diff line change
@@ -150,8 +150,13 @@ def process_action_with_datadog(*args)
# signals; it propagates the request span so that it can be finished
# no matter what
payload = {
controller: self.class.name,
controller: self.class,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you provide more details about this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was only passing a string of the class name before. We need the actual constant now, so we can actually do type checking.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changing that doesn't have any side effect for the rest of the code, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, it was being used to tag the name on the span. Since "#{class}" is the same thing as class.name, it has no change.

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: {}
}

1 change: 1 addition & 0 deletions lib/ddtrace/contrib/rails/patcher.rb
Original file line number Diff line number Diff line change
@@ -12,6 +12,7 @@ module Patcher
option :database_service
option :distributed_tracing, default: false
option :template_base_path, default: 'views/'
option :exception_controller, default: nil
option :tracer, default: Datadog.tracer

@patched = false