mirror of
https://github.com/mperham/sidekiq.git
synced 2022-11-09 13:52:34 -05:00
Implement optional backtrace storage [#155]
This commit is contained in:
parent
ab0a1bbf26
commit
e65efd5f0a
6 changed files with 56 additions and 0 deletions
10
Changes.md
10
Changes.md
|
@ -1,6 +1,16 @@
|
|||
1.2.0
|
||||
-----------
|
||||
|
||||
- Error backtraces can optionally be stored as part of the retry,
|
||||
for display in the web UI if you aren't using an error service. [#155]
|
||||
|
||||
```ruby
|
||||
class Worker
|
||||
include Sidekiq::Worker
|
||||
sidekiq_options :backtrace => true || 10
|
||||
end
|
||||
```
|
||||
|
||||
- Add Timeout middleware to optionally kill a worker after N seconds,
|
||||
just configure like so. (blackgold9)
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ module Sidekiq
|
|||
# class - the worker class to call, required
|
||||
# args - an array of simple arguments to the perform method, must be JSON-serializable
|
||||
# retry - whether to retry this job if it fails, true or false, default true
|
||||
# backtrace - whether to save any error backtrace, default false
|
||||
#
|
||||
# All options must be strings, not symbols. NB: because we are serializing to JSON, all
|
||||
# symbols in 'args' will be converted to strings.
|
||||
|
@ -43,6 +44,10 @@ module Sidekiq
|
|||
item['retry'] = !!worker_class.get_sidekiq_options['retry']
|
||||
queue = item['queue'] || worker_class.get_sidekiq_options['queue'] || 'default'
|
||||
|
||||
if !item['backtrace'] && worker_class.get_sidekiq_options['backtrace']
|
||||
item['backtrace'] = worker_class.get_sidekiq_options['backtrace']
|
||||
end
|
||||
|
||||
if !item['timeout'] && worker_class.get_sidekiq_options['timeout']
|
||||
item['timeout'] = worker_class.get_sidekiq_options['timeout']
|
||||
end
|
||||
|
|
|
@ -42,6 +42,12 @@ module Sidekiq
|
|||
msg['retry_count'] = 0
|
||||
end
|
||||
|
||||
if msg['backtrace'] == true
|
||||
msg['error_backtrace'] = e.backtrace
|
||||
elsif msg['backtrace'].to_i != 0
|
||||
msg['error_backtrace'] = e.backtrace[0..msg['backtrace'].to_i]
|
||||
end
|
||||
|
||||
if count <= MAX_COUNT
|
||||
delay = DELAY.call(count)
|
||||
logger.debug { "Failure! Retry #{count} in #{delay} seconds" }
|
||||
|
|
|
@ -37,6 +37,8 @@ module Sidekiq
|
|||
# :queue - use a named queue for this Worker, default 'default'
|
||||
# :retry - enable the RetryJobs middleware for this Worker, default *true*
|
||||
# :timeout - timeout the perform method after N seconds, default *nil*
|
||||
# :backtrace - whether to save any error backtrace in the retry payload to display in web UI,
|
||||
# can be true, false or an integer number of lines to save, default *false*
|
||||
def sidekiq_options(opts={})
|
||||
@sidekiq_options = get_sidekiq_options.merge(stringify_keys(opts || {}))
|
||||
end
|
||||
|
|
|
@ -25,6 +25,34 @@ class TestRetry < MiniTest::Unit::TestCase
|
|||
assert_equal msg, msg2
|
||||
end
|
||||
|
||||
it 'saves backtraces' do
|
||||
@redis.expect :zadd, 1, ['retry', String, String]
|
||||
msg = { 'class' => 'Bob', 'args' => [1,2,'foo'], 'retry' => true, 'backtrace' => true }
|
||||
handler = Sidekiq::Middleware::Server::RetryJobs.new
|
||||
c = nil
|
||||
assert_raises RuntimeError do
|
||||
handler.call('', msg, 'default') do
|
||||
c = caller(0); raise "kerblammo!"
|
||||
end
|
||||
end
|
||||
assert msg["error_backtrace"]
|
||||
assert_equal c, msg["error_backtrace"]
|
||||
end
|
||||
|
||||
it 'saves partial backtraces' do
|
||||
@redis.expect :zadd, 1, ['retry', String, String]
|
||||
msg = { 'class' => 'Bob', 'args' => [1,2,'foo'], 'retry' => true, 'backtrace' => 3 }
|
||||
handler = Sidekiq::Middleware::Server::RetryJobs.new
|
||||
c = nil
|
||||
assert_raises RuntimeError do
|
||||
handler.call('', msg, 'default') do
|
||||
c = caller(0)[0..3]; raise "kerblammo!"
|
||||
end
|
||||
end
|
||||
assert msg["error_backtrace"]
|
||||
assert_equal c, msg["error_backtrace"]
|
||||
end
|
||||
|
||||
it 'handles a new failed message' do
|
||||
@redis.expect :zadd, 1, ['retry', String, String]
|
||||
msg = { 'class' => 'Bob', 'args' => [1,2,'foo'], 'retry' => true }
|
||||
|
@ -38,6 +66,7 @@ class TestRetry < MiniTest::Unit::TestCase
|
|||
assert_equal 'kerblammo!', msg["error_message"]
|
||||
assert_equal 'RuntimeError', msg["error_class"]
|
||||
assert_equal 0, msg["retry_count"]
|
||||
refute msg["error_backtrace"]
|
||||
assert msg["failed_at"]
|
||||
@redis.verify
|
||||
end
|
||||
|
|
|
@ -23,6 +23,10 @@ header
|
|||
tr
|
||||
th Error Message
|
||||
td= msg['error_message']
|
||||
- if !msg['error_backtrace'].nil?
|
||||
tr
|
||||
th Error Backtrace
|
||||
td== msg['error_backtrace'].join("<br/>")
|
||||
- if msg['retry_count'] > 0
|
||||
tr
|
||||
th Retry Count
|
||||
|
|
Loading…
Reference in a new issue