Skip to content

Commit 748314c

Browse files
authored
Merge pull request #4688 from DataDog/appsec-57809-make-http-route-available-within-request
[NO-TICKET] Improve tracing Rails route computation
2 parents cd8d817 + af17fe4 commit 748314c

File tree

2 files changed

+46
-41
lines changed

2 files changed

+46
-41
lines changed

lib/datadog/tracing/contrib/action_pack/action_dispatch/instrumentation.rb

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,23 @@ module ActionPack
99
module ActionDispatch
1010
# Instrumentation for ActionDispatch components
1111
module Instrumentation
12+
SCRIPT_NAME_KEY = 'SCRIPT_NAME'
13+
FORMAT_SUFFIX = '(.:format)'
14+
1215
module_function
1316

14-
def set_http_route_tags(route_spec, script_name)
17+
def set_http_route_tags(route_spec, route_path)
1518
return unless Tracing.enabled?
1619

1720
return unless route_spec
1821

1922
request_trace = Tracing.active_trace
2023
return unless request_trace
2124

22-
request_trace.set_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE, route_spec.to_s.gsub(/\(.:format\)\z/, ''))
25+
request_trace.set_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE, route_spec)
2326

24-
if script_name && !script_name.empty?
25-
request_trace.set_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE_PATH, script_name)
27+
if route_path && !route_path.empty?
28+
request_trace.set_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE_PATH, route_path)
2629
end
2730
end
2831

@@ -40,16 +43,17 @@ module Journey
4043
# Instrumentation for ActionDispatch::Journey::Router for Rails versions older than 7.1
4144
module Router
4245
def find_routes(req)
46+
# result is an array of [match, parameters, route] tuples
4347
result = super
48+
result.each do |_, _, route|
49+
next unless Instrumentation.dispatcher_route?(route)
4450

45-
# result is an array of [match, parameters, route] tuples
46-
routes = result.map(&:last)
51+
http_route = route.path.spec.to_s
52+
http_route.delete_suffix!(FORMAT_SUFFIX)
4753

48-
routes.each do |route|
49-
if Instrumentation.dispatcher_route?(route)
50-
Instrumentation.set_http_route_tags(route.path.spec, req.env['SCRIPT_NAME'])
51-
break
52-
end
54+
Instrumentation.set_http_route_tags(http_route, req.env[SCRIPT_NAME_KEY])
55+
56+
break
5357
end
5458

5559
result
@@ -62,7 +66,10 @@ module LazyRouter
6266
def find_routes(req)
6367
super do |match, parameters, route|
6468
if Instrumentation.dispatcher_route?(route)
65-
Instrumentation.set_http_route_tags(route.path.spec, req.env['SCRIPT_NAME'])
69+
http_route = route.path.spec.to_s
70+
http_route.delete_suffix!(FORMAT_SUFFIX)
71+
72+
Instrumentation.set_http_route_tags(http_route, req.env[SCRIPT_NAME_KEY])
6673
end
6774

6875
yield [match, parameters, route]

spec/datadog/tracing/contrib/action_pack/action_dispatch/instrumentation_spec.rb

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,9 @@
44
require 'datadog/tracing/contrib/action_pack/action_dispatch/instrumentation'
55

66
RSpec.describe Datadog::Tracing::Contrib::ActionPack::ActionDispatch::Instrumentation do
7-
describe '::set_http_route_tags' do
8-
let(:tracing_enabled) { true }
9-
10-
before do
11-
expect(Datadog::Tracing).to receive(:enabled?).and_return(tracing_enabled)
12-
end
13-
7+
describe '.set_http_route_tags' do
148
context 'when tracing is disabled' do
15-
let(:tracing_enabled) { false }
9+
before { expect(Datadog::Tracing).to receive(:enabled?).and_return(false) }
1610

1711
it 'sets no tags' do
1812
Datadog::Tracing.trace('rack.request') do |_span, trace|
@@ -24,37 +18,41 @@
2418
end
2519
end
2620

27-
it 'sets http.route and http.route.path tags on existing trace' do
28-
Datadog::Tracing.trace('rack.request') do |_span, trace|
29-
described_class.set_http_route_tags('/users/:id(.:format)', '/auth')
21+
context 'when tracing is enabled' do
22+
before { expect(Datadog::Tracing).to receive(:enabled?).and_return(true) }
3023

31-
expect(trace.send(:meta).fetch('http.route')).to eq('/users/:id')
32-
expect(trace.send(:meta).fetch('http.route.path')).to eq('/auth')
24+
it 'sets http.route and http.route.path tags on existing trace' do
25+
Datadog::Tracing.trace('rack.request') do |_span, trace|
26+
described_class.set_http_route_tags('/users/:id', '/auth')
27+
28+
expect(trace.send(:meta).fetch('http.route')).to eq('/users/:id')
29+
expect(trace.send(:meta).fetch('http.route.path')).to eq('/auth')
30+
end
3331
end
34-
end
3532

36-
it 'sets no http.route.path when script name is nil' do
37-
Datadog::Tracing.trace('rack.request') do |_span, trace|
38-
described_class.set_http_route_tags('/users/:id(.:format)', nil)
33+
it 'sets no http.route.path when script name is nil' do
34+
Datadog::Tracing.trace('rack.request') do |_span, trace|
35+
described_class.set_http_route_tags('/users/:id', nil)
3936

40-
expect(trace.send(:meta).fetch('http.route')).to eq('/users/:id')
41-
expect(trace.send(:meta)).not_to have_key('http.route.path')
37+
expect(trace.send(:meta).fetch('http.route')).to eq('/users/:id')
38+
expect(trace.send(:meta)).not_to have_key('http.route.path')
39+
end
4240
end
43-
end
4441

45-
it 'sets no tags when route spec is nil' do
46-
Datadog::Tracing.trace('rack.request') do |_span, trace|
47-
described_class.set_http_route_tags(nil, '/auth')
42+
it 'sets no tags when route spec is nil' do
43+
Datadog::Tracing.trace('rack.request') do |_span, trace|
44+
described_class.set_http_route_tags(nil, '/auth')
4845

49-
expect(trace.send(:meta)).not_to have_key('http.route')
50-
expect(trace.send(:meta)).not_to have_key('http.route.path')
46+
expect(trace.send(:meta)).not_to have_key('http.route')
47+
expect(trace.send(:meta)).not_to have_key('http.route.path')
48+
end
5149
end
52-
end
5350

54-
it 'does not create new traces when no active trace is present' do
55-
described_class.set_http_route_tags('/users/:id', '/auth')
51+
it 'does not create new traces when no active trace is present' do
52+
described_class.set_http_route_tags('/users/:id', '/auth')
5653

57-
expect(traces).to be_empty
54+
expect(traces).to be_empty
55+
end
5856
end
5957
end
6058
end

0 commit comments

Comments
 (0)