diff options
-rw-r--r-- | activejob/CHANGELOG.md | 6 | ||||
-rw-r--r-- | activejob/lib/active_job/logging.rb | 13 | ||||
-rw-r--r-- | activejob/test/cases/logging_test.rb | 7 | ||||
-rw-r--r-- | activejob/test/jobs/rescue_job.rb | 2 | ||||
-rw-r--r-- | activesupport/lib/active_support/notifications.rb | 2 |
5 files changed, 26 insertions, 4 deletions
diff --git a/activejob/CHANGELOG.md b/activejob/CHANGELOG.md index 6b4f93df8b..ddfb926e02 100644 --- a/activejob/CHANGELOG.md +++ b/activejob/CHANGELOG.md @@ -1 +1,7 @@ +* Change logging instrumentation to log errors when a job raises an exception. + + Fixes #26848. + + *Steven Bull* + Please check [5-1-stable](https://github.com/rails/rails/blob/5-1-stable/activejob/CHANGELOG.md) for previous changes. diff --git a/activejob/lib/active_job/logging.rb b/activejob/lib/active_job/logging.rb index d7e2cd03e3..f46d5c68a8 100644 --- a/activejob/lib/active_job/logging.rb +++ b/activejob/lib/active_job/logging.rb @@ -74,9 +74,16 @@ module ActiveJob end def perform(event) - info do - job = event.payload[:job] - "Performed #{job.class.name} (Job ID: #{job.job_id}) from #{queue_name(event)} in #{event.duration.round(2)}ms" + job = event.payload[:job] + ex = event.payload[:exception_object] + if ex + error do + "Error performing #{job.class.name} (Job ID: #{job.job_id}) from #{queue_name(event)} in #{event.duration.round(2)}ms: #{ex.class} (#{ex.message}):\n" + Array(ex.backtrace).join("\n") + end + else + info do + "Performed #{job.class.name} (Job ID: #{job.job_id}) from #{queue_name(event)} in #{event.duration.round(2)}ms" + end end end diff --git a/activejob/test/cases/logging_test.rb b/activejob/test/cases/logging_test.rb index b37736f859..e1b546fae7 100644 --- a/activejob/test/cases/logging_test.rb +++ b/activejob/test/cases/logging_test.rb @@ -124,4 +124,11 @@ class LoggingTest < ActiveSupport::TestCase set_logger ::Logger.new(nil) OverriddenLoggingJob.perform_later "Dummy" end + + def test_job_error_logging + RescueJob.perform_later "other" + rescue RescueJob::OtherError + assert_match(/Performing RescueJob \(Job ID: .*?\) from .*? with arguments:.*other/, @logger.messages) + assert_match(/Error performing RescueJob \(Job ID: .*?\) from .*? in .*ms: RescueJob::OtherError \(Bad hair\):\n.*\brescue_job\.rb:\d+:in `perform'/, @logger.messages) + end end diff --git a/activejob/test/jobs/rescue_job.rb b/activejob/test/jobs/rescue_job.rb index ef8f777437..62add4271a 100644 --- a/activejob/test/jobs/rescue_job.rb +++ b/activejob/test/jobs/rescue_job.rb @@ -19,7 +19,7 @@ class RescueJob < ActiveJob::Base when "david" raise ArgumentError, "Hair too good" when "other" - raise OtherError + raise OtherError, "Bad hair" else JobBuffer.add("performed beautifully") end diff --git a/activesupport/lib/active_support/notifications.rb b/activesupport/lib/active_support/notifications.rb index 2df819e554..37dfdc0422 100644 --- a/activesupport/lib/active_support/notifications.rb +++ b/activesupport/lib/active_support/notifications.rb @@ -64,6 +64,8 @@ module ActiveSupport # If an exception happens during that particular instrumentation the payload will # have a key <tt>:exception</tt> with an array of two elements as value: a string with # the name of the exception class, and the exception message. + # The <tt>:exception_object</tt> key of the payload will have the exception + # itself as the value. # # As the previous example depicts, the class <tt>ActiveSupport::Notifications::Event</tt> # is able to take the arguments as they come and provide an object-oriented |