Skip to content

Commit 61af6b7

Browse files
authored
Merge pull request rails#50573 from KJTsanaktsidis/ktsanaktsidis/delay_flushing_rack_logger
Ensure that LogSubscriber.flush_all! is called after LogSubscribers run
2 parents 2bbdb7c + 8337a9b commit 61af6b7

File tree

2 files changed

+40
-8
lines changed

2 files changed

+40
-8
lines changed

railties/lib/rails/rack/logger.rb

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def call_app(request, env) # :doc:
3535

3636
logger.info { started_request_message(request) }
3737
status, headers, body = response = @app.call(env)
38-
body = ::Rack::BodyProxy.new(body, &handle.method(:finish))
38+
body = ::Rack::BodyProxy.new(body) { finish_request_instrumentation(handle) }
3939

4040
if response.frozen?
4141
[status, headers, body]
@@ -44,10 +44,8 @@ def call_app(request, env) # :doc:
4444
response
4545
end
4646
rescue Exception
47-
handle.finish
47+
finish_request_instrumentation(handle)
4848
raise
49-
ensure
50-
ActiveSupport::LogSubscriber.flush_all!
5149
end
5250

5351
# Started GET "/session/new" for 127.0.0.1 at 2012-09-26 14:51:42 -0700
@@ -75,6 +73,11 @@ def compute_tags(request) # :doc:
7573
def logger
7674
Rails.logger
7775
end
76+
77+
def finish_request_instrumentation(handle)
78+
handle.finish
79+
ActiveSupport::LogSubscriber.flush_all!
80+
end
7881
end
7982
end
8083
end

railties/test/rack_logger_test.rb

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@
55
require "active_support/test_case"
66
require "rails/rack/logger"
77
require "logger"
8+
require "active_support/log_subscriber/test_helper"
89

910
module Rails
1011
module Rack
1112
class LoggerTest < ActiveSupport::TestCase
13+
include ActiveSupport::LogSubscriber::TestHelper
14+
1215
class TestLogger < Rails::Rack::Logger
1316
NULL = ::Logger.new File::NULL
1417

@@ -43,16 +46,16 @@ def finish(name, id, payload)
4346
end
4447
end
4548

46-
attr_reader :subscriber, :notifier
49+
attr_reader :subscriber
4750

4851
def setup
52+
super
4953
@subscriber = Subscriber.new
50-
@notifier = ActiveSupport::Notifications.notifier
51-
@subscription = notifier.subscribe "request.action_dispatch", subscriber
54+
@subscription = ActiveSupport::Notifications.notifier.subscribe "request.action_dispatch", subscriber
5255
end
5356

5457
def teardown
55-
notifier.unsubscribe @subscription
58+
ActiveSupport::Notifications.notifier.unsubscribe @subscription
5659
end
5760

5861
def test_notification
@@ -90,6 +93,32 @@ def test_logger_does_not_mutate_app_return
9093
end
9194
end
9295
end
96+
97+
def test_logger_is_flushed_after_request_finished
98+
logger_middleware = TestLogger.new { }
99+
100+
flush_count_in_request_event = nil
101+
block_sub = @notifier.subscribe "request.action_dispatch" do |_event|
102+
flush_count_in_request_event = ActiveSupport::LogSubscriber.logger.flush_count
103+
end
104+
105+
# Assert that we don't get a logger flush when we finish the response headers
106+
response_body = nil
107+
assert_no_difference("ActiveSupport::LogSubscriber.logger.flush_count") do
108+
response_body = logger_middleware.call("REQUEST_METHOD" => "GET").last
109+
end
110+
111+
# Assert that we _do_ get a logger flush when we finish the response body
112+
assert_difference("ActiveSupport::LogSubscriber.logger.flush_count") do
113+
response_body.close
114+
end
115+
116+
# And that the flush happens _after_ any LogSubscribers etc get run.
117+
flush_count = ActiveSupport::LogSubscriber.logger.flush_count
118+
assert_equal(1, flush_count - flush_count_in_request_event, "flush_all! should happen after event")
119+
ensure
120+
@notifier.unsubscribe block_sub
121+
end
93122
end
94123
end
95124
end

0 commit comments

Comments
 (0)