sidekiq-jfails 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.travis.yml +10 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +60 -0
- data/LICENSE +20 -0
- data/README.md +66 -0
- data/Rakefile +12 -0
- data/lib/sidekiq-jfails.rb +1 -0
- data/lib/sidekiq/jfails/middleware.rb +30 -0
- data/lib/sidekiq/jfails/version.rb +5 -0
- data/lib/sidekiq/jfails/web.rb +22 -0
- data/lib/sidekiq/sidekiq.rb +61 -0
- data/sidekiq-jfails.gemspec +28 -0
- data/test/middleware_test.rb +58 -0
- data/test/sodekiq_test.rb +35 -0
- data/test/test_helper.rb +15 -0
- data/test/web_test.rb +85 -0
- data/web/views/fails_list.erb +60 -0
- metadata +136 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: d0431db9bb1e77466c89c7e087f817f6c01a2490
|
|
4
|
+
data.tar.gz: 637abd0c06fae1b2aa8b870a13a812244e479c62
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 131f5841a15dab460aed41bbd04f53431cd9feee60af575494e3613e4b7412a000bc5b9db73f409a182dfaffe16ec287216cb32ae9aa04b02bedec7ed970cdd7
|
|
7
|
+
data.tar.gz: a3f28cfeb5ac877c450b2f1a5f9fb93fb88ff110e819bb6262ef41097e7cadb324c612c7830a9ceb32b88c8da3e102fdba8da77ea6b47d64f69f87205a8534ec
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
sidekiq-jfails (0.0.2)
|
|
5
|
+
sidekiq (>= 2.17.0)
|
|
6
|
+
|
|
7
|
+
GEM
|
|
8
|
+
remote: https://rubygems.org/
|
|
9
|
+
specs:
|
|
10
|
+
celluloid (0.15.2)
|
|
11
|
+
timers (~> 1.1.0)
|
|
12
|
+
codeclimate-test-reporter (0.2.0)
|
|
13
|
+
simplecov (>= 0.7.1, < 1.0.0)
|
|
14
|
+
connection_pool (1.2.0)
|
|
15
|
+
docile (1.1.3)
|
|
16
|
+
hike (1.2.3)
|
|
17
|
+
json (1.8.1)
|
|
18
|
+
multi_json (1.8.4)
|
|
19
|
+
rack (1.5.2)
|
|
20
|
+
rack-protection (1.5.2)
|
|
21
|
+
rack
|
|
22
|
+
rack-test (0.6.2)
|
|
23
|
+
rack (>= 1.0)
|
|
24
|
+
rake (10.1.1)
|
|
25
|
+
redis (3.0.7)
|
|
26
|
+
redis-namespace (1.4.1)
|
|
27
|
+
redis (~> 3.0.4)
|
|
28
|
+
sidekiq (2.17.6)
|
|
29
|
+
celluloid (>= 0.15.2)
|
|
30
|
+
connection_pool (>= 1.0.0)
|
|
31
|
+
json
|
|
32
|
+
redis (>= 3.0.6)
|
|
33
|
+
redis-namespace (>= 1.3.1)
|
|
34
|
+
simplecov (0.8.2)
|
|
35
|
+
docile (~> 1.1.0)
|
|
36
|
+
multi_json
|
|
37
|
+
simplecov-html (~> 0.8.0)
|
|
38
|
+
simplecov-html (0.8.0)
|
|
39
|
+
sinatra (1.4.4)
|
|
40
|
+
rack (~> 1.4)
|
|
41
|
+
rack-protection (~> 1.4)
|
|
42
|
+
tilt (~> 1.3, >= 1.3.4)
|
|
43
|
+
sprockets (2.11.0)
|
|
44
|
+
hike (~> 1.2)
|
|
45
|
+
multi_json (~> 1.0)
|
|
46
|
+
rack (~> 1.0)
|
|
47
|
+
tilt (~> 1.1, != 1.3.0)
|
|
48
|
+
tilt (1.4.1)
|
|
49
|
+
timers (1.1.0)
|
|
50
|
+
|
|
51
|
+
PLATFORMS
|
|
52
|
+
ruby
|
|
53
|
+
|
|
54
|
+
DEPENDENCIES
|
|
55
|
+
codeclimate-test-reporter (= 0.2.0)
|
|
56
|
+
rack-test
|
|
57
|
+
rake
|
|
58
|
+
sidekiq-jfails!
|
|
59
|
+
sinatra
|
|
60
|
+
sprockets
|
data/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2014 Andrei Panamarenka
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
7
|
+
the Software without restriction, including without limitation the rights to
|
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
10
|
+
subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Sidekiq::Jfails [](https://travis-ci.org/sjke/sidekiq-jfails) [](https://codeclimate.com/repos/530ee9fde30ba068e0000d31/feed)
|
|
2
|
+
|
|
3
|
+
Keeps track of fails in Sidekiq jobs in web and provides detailed information on the fail
|
|
4
|
+
## Installation
|
|
5
|
+
|
|
6
|
+
Add this line to your application's Gemfile:
|
|
7
|
+
|
|
8
|
+
```ruby
|
|
9
|
+
gem 'sidekiq-jfails', git: 'git@github.com:sjke/sidekiq-jfails.git', tag: '0.0.1'
|
|
10
|
+
```
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
Simply having the gem in your Gemfile is enough to get you started.
|
|
14
|
+
Your failed jobs will be visible via a Job fails tab in the Web.
|
|
15
|
+
|
|
16
|
+
## Configuring
|
|
17
|
+
|
|
18
|
+
### Maximum Count Fails
|
|
19
|
+
|
|
20
|
+
This parameter sets the count of tracking fails.
|
|
21
|
+
Default of 10 000 maximum tracked fails.
|
|
22
|
+
|
|
23
|
+
To change the maximum count:
|
|
24
|
+
|
|
25
|
+
```ruby
|
|
26
|
+
Sidekiq.configure_server do |config|
|
|
27
|
+
config.jfails_max_count = 1590
|
|
28
|
+
end
|
|
29
|
+
```
|
|
30
|
+
To disable the limit entirely:
|
|
31
|
+
|
|
32
|
+
```ruby
|
|
33
|
+
Sidekiq.configure_server do |config|
|
|
34
|
+
config.jfails_max_count = 0
|
|
35
|
+
end
|
|
36
|
+
```
|
|
37
|
+
### Fails per page
|
|
38
|
+
|
|
39
|
+
This parameter sets the count of fails displayed per page.
|
|
40
|
+
Default of 10 fails per page.
|
|
41
|
+
|
|
42
|
+
To change the per page:
|
|
43
|
+
|
|
44
|
+
```ruby
|
|
45
|
+
Sidekiq.configure_server do |config|
|
|
46
|
+
config.fails_per_page = 15
|
|
47
|
+
end
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Dependencies
|
|
51
|
+
|
|
52
|
+
Depends on Sidekiq >= 2.17
|
|
53
|
+
|
|
54
|
+
## Contributing
|
|
55
|
+
|
|
56
|
+
1. Fork it
|
|
57
|
+
2. Create your feature branch (`git checkout -b feature-desc`)
|
|
58
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
|
59
|
+
4. Push to the branch (`git push origin feature-desc`)
|
|
60
|
+
5. Create new Pull Request
|
|
61
|
+
|
|
62
|
+
## License
|
|
63
|
+
|
|
64
|
+
Released under the MIT License. See the [LICENSE][license] file for further details.
|
|
65
|
+
|
|
66
|
+
[license]: https://github.com/sjke/sidekiq-jfails/blob/master/LICENSE
|
data/Rakefile
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require 'sidekiq/sidekiq'
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module Sidekiq
|
|
2
|
+
module Jfails
|
|
3
|
+
class Middleware
|
|
4
|
+
include Sidekiq::Util
|
|
5
|
+
attr_accessor :msg
|
|
6
|
+
|
|
7
|
+
def call(worker, msg, queue)
|
|
8
|
+
self.msg = msg
|
|
9
|
+
yield
|
|
10
|
+
rescue Exception => e
|
|
11
|
+
data = {
|
|
12
|
+
:date => Time.now.utc,
|
|
13
|
+
:exception => e.class.to_s,
|
|
14
|
+
:args => msg['args'],#.join(', '),
|
|
15
|
+
:error => e.message,
|
|
16
|
+
:backtrace => e.backtrace,
|
|
17
|
+
:worker => msg['class'],
|
|
18
|
+
:queue => queue
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
Sidekiq.redis do |conn|
|
|
22
|
+
conn.lpush(LIST_KEY, Sidekiq.dump_json(data))
|
|
23
|
+
conn.ltrim(LIST_KEY, 0, Sidekiq.jfails_max_count - 1) unless Sidekiq.jfails_max_count == 0
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
raise e
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module Sidekiq
|
|
2
|
+
module Jfails
|
|
3
|
+
module Web
|
|
4
|
+
|
|
5
|
+
def self.registered(app)
|
|
6
|
+
app.get '/jfails' do
|
|
7
|
+
view_path = File.expand_path(File.dirname(__FILE__) + '/../../../web/views')
|
|
8
|
+
|
|
9
|
+
@count = Sidekiq.fails_per_page
|
|
10
|
+
(@current_page, @total_size, @fails) = page('failed', params[:page], @count)
|
|
11
|
+
@fails = @fails.map { |msg| Sidekiq.load_json(msg) }
|
|
12
|
+
render :erb, File.read(File.join(view_path, 'fails_list.erb'))
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
app.post '/jfails/reset' do
|
|
16
|
+
Sidekiq::Jfails.reset(counter: params['counter'])
|
|
17
|
+
redirect back
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
require 'sidekiq/web'
|
|
2
|
+
require 'sidekiq/jfails/middleware'
|
|
3
|
+
require 'sidekiq/jfails/web'
|
|
4
|
+
|
|
5
|
+
module Sidekiq
|
|
6
|
+
|
|
7
|
+
# Sets the maximum number of fails to track
|
|
8
|
+
#
|
|
9
|
+
# If the number of failures exceeds this number the list will be trimmed (oldest
|
|
10
|
+
# failures will be purged).
|
|
11
|
+
#
|
|
12
|
+
# Defaults to 10 000
|
|
13
|
+
# Set to 0 to disable rotation
|
|
14
|
+
def self.jfails_max_count=(value)
|
|
15
|
+
@jfails_max_count = value
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.jfails_max_count
|
|
19
|
+
return 10000 unless @jfails_max_count
|
|
20
|
+
@jfails_max_count
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Sets the maximum fails per page
|
|
24
|
+
#
|
|
25
|
+
# Defaults to 10
|
|
26
|
+
def self.fails_per_page=(value)
|
|
27
|
+
@fails_per_page = value
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.fails_per_page
|
|
31
|
+
return 10 unless @fails_per_page
|
|
32
|
+
@fails_per_page
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
module Jfails
|
|
36
|
+
LIST_KEY = :failed
|
|
37
|
+
|
|
38
|
+
def self.reset(options = {})
|
|
39
|
+
Sidekiq.redis { |c|
|
|
40
|
+
c.multi do
|
|
41
|
+
c.del(LIST_KEY)
|
|
42
|
+
c.set('stat:failed', 0) if options[:counter] || options['counter']
|
|
43
|
+
end
|
|
44
|
+
}
|
|
45
|
+
end
|
|
46
|
+
def self.count
|
|
47
|
+
Sidekiq.redis {|r| r.llen(LIST_KEY) }
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
Sidekiq.configure_server do |config|
|
|
53
|
+
config.server_middleware do |chain|
|
|
54
|
+
chain.add Sidekiq::Jfails::Middleware
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
if defined?(Sidekiq::Web)
|
|
59
|
+
Sidekiq::Web.register Sidekiq::Jfails::Web
|
|
60
|
+
Sidekiq::Web.tabs['Job fails'] = 'jfails'
|
|
61
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
3
|
+
require 'sidekiq/jfails/version'
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |gem|
|
|
7
|
+
# Authors
|
|
8
|
+
gem.authors = ["Andrei Ponomarenko"]
|
|
9
|
+
gem.email = ["biglolko@gmail.com"]
|
|
10
|
+
# About gem
|
|
11
|
+
gem.name = "sidekiq-jfails"
|
|
12
|
+
gem.version = Sidekiq::Jfails::VERSION
|
|
13
|
+
gem.description = %q{Keep track of fails in Sidekiq jobs}
|
|
14
|
+
gem.summary = %q{Keeps track of fails in Sidekiq jobs in web and provides detailed information on the fail}
|
|
15
|
+
gem.homepage = "https://github.com/sjke/sidekiq-jfails/"
|
|
16
|
+
|
|
17
|
+
gem.files = `git ls-files`.split($\)
|
|
18
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
|
19
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
|
20
|
+
gem.require_paths = ["lib"]
|
|
21
|
+
|
|
22
|
+
# Dependencys
|
|
23
|
+
gem.add_dependency "sidekiq", ">= 2.17.0"
|
|
24
|
+
gem.add_development_dependency "rake"
|
|
25
|
+
gem.add_development_dependency "rack-test"
|
|
26
|
+
gem.add_development_dependency "sprockets"
|
|
27
|
+
gem.add_development_dependency "sinatra"
|
|
28
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
module Sidekiq
|
|
4
|
+
module Jfails
|
|
5
|
+
describe Middleware do
|
|
6
|
+
|
|
7
|
+
WorkerException = Class.new(Exception)
|
|
8
|
+
|
|
9
|
+
let(:msg) { {'class' => 'MockWorker', 'args' => ['custom_argument'], 'retry' => false} }
|
|
10
|
+
let(:handler){ Sidekiq::Jfails::Middleware.new }
|
|
11
|
+
|
|
12
|
+
before do
|
|
13
|
+
Sidekiq.redis = REDIS
|
|
14
|
+
Sidekiq.redis { |c| c.flushdb }
|
|
15
|
+
end
|
|
16
|
+
it 'records job fails by default jfails_max_count' do
|
|
17
|
+
assert_equal 0, jfails_count
|
|
18
|
+
|
|
19
|
+
10.times do
|
|
20
|
+
assert_raises WorkerException do
|
|
21
|
+
handler.call(MockWorker.new, msg, 'default') do
|
|
22
|
+
raise WorkerException.new 'test'
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
assert_equal 10, jfails_count
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it 'removes old job fails when jfails_max_count has been reached' do
|
|
31
|
+
assert_equal 0, jfails_count
|
|
32
|
+
Sidekiq.jfails_max_count= 3
|
|
33
|
+
|
|
34
|
+
10.times do
|
|
35
|
+
assert_raises WorkerException do
|
|
36
|
+
handler.call(MockWorker.new, msg, 'default') do
|
|
37
|
+
raise WorkerException.new 'test'
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
assert_equal 3, jfails_count
|
|
43
|
+
Sidekiq.jfails_max_count= nil
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def jfails_count
|
|
47
|
+
Sidekiq.redis { |redis| redis.llen('failed') } || 0
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
class MockWorker
|
|
51
|
+
include Sidekiq::Worker
|
|
52
|
+
|
|
53
|
+
def perform
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
|
|
2
|
+
require 'test_helper'
|
|
3
|
+
|
|
4
|
+
module Sidekiq
|
|
5
|
+
describe Jfails do
|
|
6
|
+
|
|
7
|
+
it 'defaults jfails_max_count to 10 000' do
|
|
8
|
+
assert_equal 10000, Sidekiq.jfails_max_count
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it 'defaults fails_per_page to 10' do
|
|
12
|
+
assert_equal 10, Sidekiq.fails_per_page
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it 'revert jfails_max_count by default when this set nil' do
|
|
16
|
+
assert_equal 10000, Sidekiq.jfails_max_count
|
|
17
|
+
|
|
18
|
+
Sidekiq.jfails_max_count= 10
|
|
19
|
+
assert_equal 10, Sidekiq.jfails_max_count
|
|
20
|
+
|
|
21
|
+
Sidekiq.jfails_max_count= nil
|
|
22
|
+
assert_equal 10000, Sidekiq.jfails_max_count
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it 'revert fails_per_page by default when this set nil' do
|
|
26
|
+
assert_equal 10, Sidekiq.fails_per_page
|
|
27
|
+
|
|
28
|
+
Sidekiq.fails_per_page= 1
|
|
29
|
+
assert_equal 1, Sidekiq.fails_per_page
|
|
30
|
+
|
|
31
|
+
Sidekiq.fails_per_page= nil
|
|
32
|
+
assert_equal 10, Sidekiq.fails_per_page
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
data/test/test_helper.rb
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require "minitest/autorun"
|
|
2
|
+
require "minitest/spec"
|
|
3
|
+
require "minitest/mock"
|
|
4
|
+
|
|
5
|
+
require "rack/test"
|
|
6
|
+
|
|
7
|
+
require "sidekiq"
|
|
8
|
+
require "sidekiq-jfails"
|
|
9
|
+
require "codeclimate-test-reporter"
|
|
10
|
+
|
|
11
|
+
Encoding.default_external = Encoding::UTF_8
|
|
12
|
+
Encoding.default_internal = Encoding::UTF_8
|
|
13
|
+
|
|
14
|
+
CodeClimate::TestReporter.start
|
|
15
|
+
REDIS = Sidekiq::RedisConnection.create(:url => "redis://localhost/15", :namespace => 'sidekiq_extension_test')
|
data/test/web_test.rb
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
require "test_helper"
|
|
2
|
+
require "sidekiq/web"
|
|
3
|
+
|
|
4
|
+
module Sidekiq
|
|
5
|
+
describe Web do
|
|
6
|
+
include Rack::Test::Methods
|
|
7
|
+
|
|
8
|
+
def app
|
|
9
|
+
Sidekiq::Web
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
before do
|
|
13
|
+
Sidekiq.redis = REDIS
|
|
14
|
+
Sidekiq.redis {|c| c.flushdb }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'can display Job fails tab' do
|
|
18
|
+
get '/'
|
|
19
|
+
|
|
20
|
+
last_response.status.must_equal 200
|
|
21
|
+
last_response.body.must_match /Sidekiq/
|
|
22
|
+
last_response.body.must_match /Job fails/
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it 'can display Job fails page without fails' do
|
|
26
|
+
get '/jfails'
|
|
27
|
+
last_response.status.must_equal 200
|
|
28
|
+
last_response.body.must_match /Job fails/
|
|
29
|
+
last_response.body.must_match /No failed jobs found/
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
describe 'when there are fails' do
|
|
33
|
+
before do
|
|
34
|
+
create_sample_fail
|
|
35
|
+
get '/jfails'
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it 'can display Job fails page with fails listed' do
|
|
39
|
+
last_response.body.wont_match /No failed jobs found/
|
|
40
|
+
last_response.body.must_match /HardWorker/
|
|
41
|
+
last_response.body.must_match /ArgumentError: Some new message/
|
|
42
|
+
last_response.body.must_match /default/
|
|
43
|
+
last_response.body.must_match /bob, 5/
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it 'can remove all Job fails' do
|
|
47
|
+
assert_equal failed_count, "1"
|
|
48
|
+
|
|
49
|
+
last_response.body.must_match /HardWorker/
|
|
50
|
+
|
|
51
|
+
post '/jfails/reset', counter: "true"
|
|
52
|
+
last_response.status.must_equal 302
|
|
53
|
+
|
|
54
|
+
get '/jfails'
|
|
55
|
+
last_response.status.must_equal 200
|
|
56
|
+
last_response.body.must_match /No failed jobs found/
|
|
57
|
+
|
|
58
|
+
assert_equal failed_count, "0"
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def create_sample_fail
|
|
63
|
+
data = {
|
|
64
|
+
:date => Time.now.strftime("%Y/%m/%d %H:%M:%S %Z"),
|
|
65
|
+
:args => ["bob", 5].join(', '),
|
|
66
|
+
:exception => "ArgumentError",
|
|
67
|
+
:error => "Some new message",
|
|
68
|
+
:backtrace => ["path/file1.rb", "path/file2.rb"],
|
|
69
|
+
:worker => 'HardWorker',
|
|
70
|
+
:queue => 'default'
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
Sidekiq.redis do |c|
|
|
74
|
+
c.multi do
|
|
75
|
+
c.rpush("failed", Sidekiq.dump_json(data))
|
|
76
|
+
c.set("stat:failed", 1)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def failed_count
|
|
82
|
+
Sidekiq.redis { |c| c.get("stat:failed") }
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/blitzer/jquery-ui.css" />
|
|
2
|
+
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
|
|
3
|
+
<header class="row">
|
|
4
|
+
<div class="col-sm-5">
|
|
5
|
+
<h3>Job fails</h3>
|
|
6
|
+
</div>
|
|
7
|
+
</header>
|
|
8
|
+
|
|
9
|
+
<% if @fails.size > 0 %>
|
|
10
|
+
<table class="table table-striped table-bordered table-white">
|
|
11
|
+
<thead>
|
|
12
|
+
<th style="width: 15%">Date</th>
|
|
13
|
+
<th style="width: 25%">Worker</th>
|
|
14
|
+
<th style="width: 30%">Exception</th>
|
|
15
|
+
<th style="width: 15%">Queue</th>
|
|
16
|
+
<th style="width: 15%">Args</th>
|
|
17
|
+
<th style="width: 15%">Details</th>
|
|
18
|
+
</thead>
|
|
19
|
+
<% @fails.each do |fail| %>
|
|
20
|
+
<tr>
|
|
21
|
+
<td><%= relative_time Time.parse(fail['date']) %></td>
|
|
22
|
+
<td><%= fail['worker'] %></td>
|
|
23
|
+
<td><%= h fail['exception'] %>: <%= h fail['error'] %></td>
|
|
24
|
+
<td><%= fail['queue'] %></td>
|
|
25
|
+
<td><%= fail['args'] %></td>
|
|
26
|
+
<td><a class='details' href="javascript:void(0);" data-details="<%= fail['backtrace'].join('</td></tr><tr><td>') %>">Show</a></td>
|
|
27
|
+
</tr>
|
|
28
|
+
<% end %>
|
|
29
|
+
</table>
|
|
30
|
+
<div id="dialog-modal" title="Fail details">
|
|
31
|
+
<div id="code" style="max-height: 350px;"></div>
|
|
32
|
+
</div>
|
|
33
|
+
<script>
|
|
34
|
+
$(function() {
|
|
35
|
+
$('.details').on('click', function() {
|
|
36
|
+
var dialog = $('#dialog-modal');
|
|
37
|
+
var table = '<table class="table table-striped table-bordered table-white"><tr><td>'
|
|
38
|
+
+ $('.details').attr('data-details')
|
|
39
|
+
+ '</td></tr></table>';
|
|
40
|
+
dialog.find('#code').html(table);
|
|
41
|
+
dialog.dialog({ width: '1200px', modal: true });
|
|
42
|
+
})
|
|
43
|
+
})
|
|
44
|
+
</script>
|
|
45
|
+
<div class="row">
|
|
46
|
+
<div class="col-sm-8">
|
|
47
|
+
<form class="form-inline" action="<%= "#{root_path}jfails/reset" %>" method="post" style="margin: 20px 0">
|
|
48
|
+
<input type="hidden" name="counter" value="true" />
|
|
49
|
+
<input class="btn btn-danger btn-small" type="submit" name="delete" value="Clear All" />
|
|
50
|
+
</form>
|
|
51
|
+
</div>
|
|
52
|
+
<% if @total_size > @count %>
|
|
53
|
+
<div class="col-sm-4">
|
|
54
|
+
<%= erb :_paging, :locals => { :url => "#{root_path}jfails#@name" } %>
|
|
55
|
+
</div>
|
|
56
|
+
<% end %>
|
|
57
|
+
</div>
|
|
58
|
+
<% else %>
|
|
59
|
+
<div class="alert alert-success">No failed jobs found.</div>
|
|
60
|
+
<% end %>
|
metadata
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: sidekiq-jfails
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.2
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Andrei Ponomarenko
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2014-02-27 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: sidekiq
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - '>='
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: 2.17.0
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - '>='
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: 2.17.0
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: rake
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - '>='
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - '>='
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: rack-test
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - '>='
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - '>='
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: sprockets
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - '>='
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - '>='
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '0'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: sinatra
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - '>='
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '0'
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - '>='
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '0'
|
|
83
|
+
description: Keep track of fails in Sidekiq jobs
|
|
84
|
+
email:
|
|
85
|
+
- biglolko@gmail.com
|
|
86
|
+
executables: []
|
|
87
|
+
extensions: []
|
|
88
|
+
extra_rdoc_files: []
|
|
89
|
+
files:
|
|
90
|
+
- .gitignore
|
|
91
|
+
- .travis.yml
|
|
92
|
+
- Gemfile
|
|
93
|
+
- Gemfile.lock
|
|
94
|
+
- LICENSE
|
|
95
|
+
- README.md
|
|
96
|
+
- Rakefile
|
|
97
|
+
- lib/sidekiq-jfails.rb
|
|
98
|
+
- lib/sidekiq/jfails/middleware.rb
|
|
99
|
+
- lib/sidekiq/jfails/version.rb
|
|
100
|
+
- lib/sidekiq/jfails/web.rb
|
|
101
|
+
- lib/sidekiq/sidekiq.rb
|
|
102
|
+
- sidekiq-jfails.gemspec
|
|
103
|
+
- test/middleware_test.rb
|
|
104
|
+
- test/sodekiq_test.rb
|
|
105
|
+
- test/test_helper.rb
|
|
106
|
+
- test/web_test.rb
|
|
107
|
+
- web/views/fails_list.erb
|
|
108
|
+
homepage: https://github.com/sjke/sidekiq-jfails/
|
|
109
|
+
licenses: []
|
|
110
|
+
metadata: {}
|
|
111
|
+
post_install_message:
|
|
112
|
+
rdoc_options: []
|
|
113
|
+
require_paths:
|
|
114
|
+
- lib
|
|
115
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
116
|
+
requirements:
|
|
117
|
+
- - '>='
|
|
118
|
+
- !ruby/object:Gem::Version
|
|
119
|
+
version: '0'
|
|
120
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
121
|
+
requirements:
|
|
122
|
+
- - '>='
|
|
123
|
+
- !ruby/object:Gem::Version
|
|
124
|
+
version: '0'
|
|
125
|
+
requirements: []
|
|
126
|
+
rubyforge_project:
|
|
127
|
+
rubygems_version: 2.1.11
|
|
128
|
+
signing_key:
|
|
129
|
+
specification_version: 4
|
|
130
|
+
summary: Keeps track of fails in Sidekiq jobs in web and provides detailed information
|
|
131
|
+
on the fail
|
|
132
|
+
test_files:
|
|
133
|
+
- test/middleware_test.rb
|
|
134
|
+
- test/sodekiq_test.rb
|
|
135
|
+
- test/test_helper.rb
|
|
136
|
+
- test/web_test.rb
|