Skip to content

Commit 66c2ad1

Browse files
dingsdaxclaude
andauthored
fix(rails): Track request queue time in Rails middleware (#2877)
The Rails CaptureExceptions middleware subclass overrode start_transaction without calling super, so the http.server.request.time_in_queue attachment added in #2838 was silently skipped for all Rails apps. Extract queue time attachment into a private attach_queue_time method on the Rack base class so the Rails subclass can invoke it explicitly while keeping its own options hash (preserving the correct SPAN_ORIGIN constant "auto.http.rails" via lexical scoping). Fixes #2873 Co-authored-by: Claude <[email protected]>
1 parent faa2853 commit 66c2ad1

File tree

3 files changed

+38
-9
lines changed

3 files changed

+38
-9
lines changed

sentry-rails/lib/sentry/rails/capture_exceptions.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,12 @@ def start_transaction(env, scope)
4343
origin: SPAN_ORIGIN
4444
}
4545

46-
if @assets_regexp && scope.transaction_name.match?(@assets_regexp)
47-
options.merge!(sampled: false)
48-
end
46+
options.merge!(sampled: false) if @assets_regexp && scope.transaction_name.match?(@assets_regexp)
4947

5048
transaction = Sentry.continue_trace(env, **options)
51-
Sentry.start_transaction(transaction: transaction, custom_sampling_context: { env: env }, **options)
49+
transaction = Sentry.start_transaction(transaction: transaction, custom_sampling_context: { env: env }, **options)
50+
attach_queue_time(transaction, env)
51+
transaction
5252
end
5353

5454
def show_exceptions?(exception, env)

sentry-rails/spec/sentry/rails/tracing_spec.rb

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,33 @@
110110

111111
expect(transport.events.count).to eq(1)
112112
end
113+
114+
context "with X-Request-Start header" do
115+
it "attaches queue time to the Rails transaction" do
116+
p = Post.create!
117+
timestamp = Time.now.to_f - 0.05 # 50ms ago
118+
119+
get "/posts/#{p.id}", headers: { "X-Request-Start" => "t=#{timestamp}" }
120+
121+
expect(response).to have_http_status(:ok)
122+
transaction = transport.events.last
123+
queue_time = transaction.contexts.dig(:trace, :data, "http.server.request.time_in_queue")
124+
expect(queue_time).not_to be_nil
125+
expect(queue_time).to be >= 0
126+
end
127+
128+
it "does not attach queue time when capture_queue_time is disabled" do
129+
p = Post.create!
130+
timestamp = Time.now.to_f - 0.05
131+
132+
Sentry.configuration.capture_queue_time = false
133+
get "/posts/#{p.id}", headers: { "X-Request-Start" => "t=#{timestamp}" }
134+
135+
transaction = transport.events.last
136+
queue_time = transaction.contexts.dig(:trace, :data, "http.server.request.time_in_queue")
137+
expect(queue_time).to be_nil
138+
end
139+
end
113140
end
114141

115142
context "with report_rescued_exceptions and public error pages" do

sentry-ruby/lib/sentry/rack/capture_exceptions.rb

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,15 @@ def start_transaction(env, scope)
7373

7474
transaction = Sentry.continue_trace(env, **options)
7575
transaction = Sentry.start_transaction(transaction: transaction, custom_sampling_context: { env: env }, **options)
76+
attach_queue_time(transaction, env)
77+
transaction
78+
end
7679

77-
# attach queue time if available
78-
if transaction && (queue_time = extract_queue_time(env))
79-
transaction.set_data(Span::DataConventions::HTTP_QUEUE_TIME_MS, queue_time)
80-
end
80+
def attach_queue_time(transaction, env)
81+
return unless transaction
82+
return unless (queue_time = extract_queue_time(env))
8183

82-
transaction
84+
transaction.set_data(Span::DataConventions::HTTP_QUEUE_TIME_MS, queue_time)
8385
end
8486

8587

0 commit comments

Comments
 (0)