Skip to content

Commit 41702d6

Browse files
authored
fix: rack span class naming (#1555)
1 parent ca00ab0 commit 41702d6

File tree

2 files changed

+28
-31
lines changed

2 files changed

+28
-31
lines changed

instrumentation/action_pack/lib/opentelemetry/instrumentation/action_pack/handlers/action_controller.rb

Lines changed: 26 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,34 @@ def initialize(config)
2323
# @param payload [Hash] the payload passed as a method argument
2424
# @return [Hash] the payload passed as a method argument
2525
def start(_name, _id, payload)
26-
span_name, attributes = to_span_name_and_attributes(payload)
26+
request = payload[:request]
27+
# It seems that there are cases in Rails functional tests where it bypasses the routing system and the `action_dispatch.route_uri_pattern` header not being set.
28+
# Our Test suite executes the routing system so we are unable to recreate this error case.
29+
# https://github.com/rails/rails/blob/747f85f200e7bb2c1a31b4e26e5a5655e2dc0cdc/actionpack/lib/action_dispatch/http/request.rb#L160
30+
http_route = request.route_uri_pattern&.chomp('(.:format)') if request.respond_to?(:route_uri_pattern)
31+
32+
attributes = {
33+
OpenTelemetry::SemanticConventions::Trace::CODE_NAMESPACE => String(payload[:controller]),
34+
OpenTelemetry::SemanticConventions::Trace::CODE_FUNCTION => String(payload[:action])
35+
}
36+
attributes[OpenTelemetry::SemanticConventions::Trace::HTTP_ROUTE] = http_route if http_route
37+
attributes[OpenTelemetry::SemanticConventions::Trace::HTTP_TARGET] = request.filtered_path if request.filtered_path != request.fullpath
2738

2839
span = OpenTelemetry::Instrumentation::Rack.current_span
40+
span_name = if @span_naming == :semconv
41+
if http_route
42+
"#{request.method} #{http_route}"
43+
else
44+
"#{request.method} /#{payload.dig(:params, :controller)}/#{payload.dig(:params, :action)}"
45+
end
46+
# If there is an exception we want to keep the original span name
47+
# so it is easier to see where the request was routed to.
48+
elsif request.env['action_dispatch.exception']
49+
span.name
50+
else
51+
"#{payload[:controller]}##{payload[:action]}"
52+
end
53+
2954
span.name = span_name
3055
span.add_attributes(attributes)
3156
rescue StandardError => e
@@ -44,35 +69,6 @@ def finish(_name, _id, payload)
4469
rescue StandardError => e
4570
OpenTelemetry.handle_error(exception: e)
4671
end
47-
48-
private
49-
50-
# Extracts the span name and attributes from the payload
51-
#
52-
# @param payload [Hash] the payload passed from ActiveSupport::Notifications
53-
# @return [Array<String, Hash>] the span name and attributes
54-
def to_span_name_and_attributes(payload)
55-
request = payload[:request]
56-
# It seems that there are cases in Rails functional tests where it bypasses the routing system and the `action_dispatch.route_uri_pattern` header not being set.
57-
# Our Test suite executes the routing system so we are unable to recreate this error case.
58-
# https://github.com/rails/rails/blob/747f85f200e7bb2c1a31b4e26e5a5655e2dc0cdc/actionpack/lib/action_dispatch/http/request.rb#L160
59-
http_route = request.route_uri_pattern&.chomp('(.:format)') if request.respond_to?(:route_uri_pattern)
60-
61-
attributes = {
62-
OpenTelemetry::SemanticConventions::Trace::CODE_NAMESPACE => String(payload[:controller]),
63-
OpenTelemetry::SemanticConventions::Trace::CODE_FUNCTION => String(payload[:action])
64-
}
65-
attributes[OpenTelemetry::SemanticConventions::Trace::HTTP_ROUTE] = http_route if http_route
66-
attributes[OpenTelemetry::SemanticConventions::Trace::HTTP_TARGET] = request.filtered_path if request.filtered_path != request.fullpath
67-
68-
if @span_naming == :semconv
69-
return ["#{request.method} #{http_route}", attributes] if http_route
70-
71-
return ["#{request.method} /#{payload.dig(:params, :controller)}/#{payload.dig(:params, :action)}", attributes]
72-
end
73-
74-
["#{payload[:controller]}##{payload[:action]}", attributes]
75-
end
7672
end
7773
end
7874
end

instrumentation/action_pack/test/opentelemetry/instrumentation/action_pack/handlers/action_controller_test.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,11 +215,12 @@
215215

216216
describe 'when the application has exceptions_app configured' do
217217
let(:rails_app) { AppConfig.initialize_app(use_exceptions_app: true) }
218+
let(:config) { { span_naming: :class } }
218219

219220
it 'does not overwrite the span name from the controller that raised' do
220221
get 'internal_server_error'
221222

222-
_(span.name).must_match(/^GET/)
223+
_(span.name).must_equal 'ExampleController#internal_server_error'
223224
_(span.kind).must_equal :server
224225
_(span.status.ok?).must_equal false
225226

0 commit comments

Comments
 (0)