From 59982acd632dbfa2b41818b35f81ca65731b5519 Mon Sep 17 00:00:00 2001 From: Jason Rudolph Date: Wed, 4 May 2011 18:46:24 -0400 Subject: [PATCH 1/2] Always flush logger at exit Prior to this change, running code via script/runner would demonstrate different logging behavior than running the same code via a rake task. In production mode the script/runner approach would always flush the logger, but the rake-based approach would not automatically flush the logger. This discrepancy violates the principle of least surprise, and it could lead to the loss of important production logging data. This change removes special-case code in the "runner" command, and replaces it with a general solution to ensure that the logger gets flushed at exit. This solution works for "runner", "console", "server", rake tasks, and any other process that loads the Rails environment. --- railties/lib/rails/application/bootstrap.rb | 1 + railties/lib/rails/commands/runner.rb | 22 ++++++++------------- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/railties/lib/rails/application/bootstrap.rb b/railties/lib/rails/application/bootstrap.rb index 9c9d85eed6..0c02e5758e 100644 --- a/railties/lib/rails/application/bootstrap.rb +++ b/railties/lib/rails/application/bootstrap.rb @@ -37,6 +37,7 @@ module Rails ) logger end + at_exit { Rails.logger.flush if Rails.logger.respond_to?(:flush) } end # Initialize cache early in the stack so railties can make use of it. diff --git a/railties/lib/rails/commands/runner.rb b/railties/lib/rails/commands/runner.rb index 1a91d477ec..ddd08a32ee 100644 --- a/railties/lib/rails/commands/runner.rb +++ b/railties/lib/rails/commands/runner.rb @@ -39,18 +39,12 @@ ENV["RAILS_ENV"] = options[:environment] require APP_PATH Rails.application.require_environment! -begin - if code_or_file.nil? - $stderr.puts "Run '#{$0} -h' for help." - exit 1 - elsif File.exist?(code_or_file) - $0 = code_or_file - eval(File.read(code_or_file), nil, code_or_file) - else - eval(code_or_file) - end -ensure - if defined? Rails - Rails.logger.flush if Rails.logger.respond_to?(:flush) - end +if code_or_file.nil? + $stderr.puts "Run '#{$0} -h' for help." + exit 1 +elsif File.exist?(code_or_file) + $0 = code_or_file + eval(File.read(code_or_file), nil, code_or_file) +else + eval(code_or_file) end From cb2d811ebbf3c3c9941618813f73261b3449eecf Mon Sep 17 00:00:00 2001 From: Jason Rudolph Date: Thu, 5 May 2011 16:51:29 -0400 Subject: [PATCH 2/2] Add test to verify production rake tasks flush logger on exit --- railties/test/application/rake_test.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/railties/test/application/rake_test.rb b/railties/test/application/rake_test.rb index a8bcf7beaf..d77c2d14ab 100644 --- a/railties/test/application/rake_test.rb +++ b/railties/test/application/rake_test.rb @@ -73,6 +73,19 @@ module ApplicationTests assert_match 'custom_assets GET /custom/assets(.:format)', Dir.chdir(app_path){ `rake routes` } end + def test_logger_is_flushed_when_exiting_production_rake_tasks + add_to_config <<-RUBY + rake_tasks do + task :log_something => :environment do + Rails.logger.error("Sample log message") + end + end + RUBY + + output = Dir.chdir(app_path){ `rake log_something RAILS_ENV=production && cat log/production.log` } + assert_match "Sample log message", output + end + def test_model_and_migration_generator_with_change_syntax Dir.chdir(app_path) do `rails generate model user username:string password:string`