sidekiq-errors 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 735d5c9da4fe4e1d722939833442a43deabea9df
4
+ data.tar.gz: ee57f394e4e0f31bc215e7936b2c43f09d4cdb0b
5
+ SHA512:
6
+ metadata.gz: ddf8da896bb2ef46cab59c0dbd941d8e3f9673b2a7aa8c0ef54830b80f9ba38296ef0249a6f05d2df272f424989a3252183ac4982bd69a10e4576d359ab185d0
7
+ data.tar.gz: e7d9d06bbc44b531702cfad9eca4938ca6a7c453c854dd1b636952f8004373c1e386f0190c3c4d04e9118f4594f384ddb31803b21b10a815006616cd5bf5acb7
@@ -0,0 +1 @@
1
+ *.gem
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'sidekiq', ENV['SIDEKIQ_VERSION'] if ENV['SIDEKIQ_VERSION']
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2014 tech4gold, llc chris@tech4gold.com
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,9 @@
1
+ # Sidekiq::Errors
2
+
3
+ ## Installation
4
+
5
+ Add this line to your application's Gemfile:
6
+
7
+ ```ruby
8
+ gem 'sidekiq-errors'
9
+ ```
@@ -0,0 +1 @@
1
+ require "sidekiq/errors"
@@ -0,0 +1,28 @@
1
+ begin
2
+ require "sidekiq/web"
3
+ rescue LoadError
4
+ # client-only usage
5
+ end
6
+
7
+ require "sidekiq/api"
8
+ require "sidekiq/errors/version"
9
+ require "sidekiq/errors/web_extension"
10
+
11
+ module Sidekiq
12
+
13
+ def self.errors_max_count=(value)
14
+ @errors_max_count = value
15
+ end
16
+
17
+ def self.errors_max_count
18
+ return 10_000 if @errors_max_count.nil?
19
+
20
+ @errors_max_count
21
+ end
22
+
23
+ end
24
+
25
+ if defined?(Sidekiq::Web)
26
+ Sidekiq::Web.register Sidekiq::Errors::WebExtension
27
+ Sidekiq::Web.tabs["Errors"] = "errors"
28
+ end
@@ -0,0 +1,5 @@
1
+ module Sidekiq
2
+ module Errors
3
+ VERSION = "0.0.2"
4
+ end
5
+ end
@@ -0,0 +1,26 @@
1
+ <header class="row">
2
+ <div class="col-sm-5">
3
+ <h3><%= t('Errors') %></h3>
4
+ </div>
5
+ </header>
6
+
7
+ <% if @errors.size > 0 %>
8
+ <table class="table table-striped table-bordered table-white">
9
+ <thead>
10
+ <tr>
11
+ <th><%= t('class') %></th>
12
+ <th><%= t('JobCount') %></th>
13
+ </tr>
14
+ </thead>
15
+ <tbody>
16
+ <% @errors.each do |error, job_count| %>
17
+ <tr>
18
+ <td><a href="<%= root_path %>errors/<%= error %>"><%= error %></a></td>
19
+ <td><%= job_count %></td>
20
+ </tr>
21
+ <% end %>
22
+ </tbody>
23
+ </table>
24
+ <% else %>
25
+ <div class="alert alert-success">No <%= t('Failures') %></div>
26
+ <% end %>
@@ -0,0 +1,34 @@
1
+ <header class="row">
2
+ <div class="col-sm-5">
3
+ <h3><%= t('Errors') %> <%= @error_class %></h3>
4
+ </div>
5
+ </header>
6
+
7
+ <% if @error_messages.size > 0 %>
8
+ <table class="table table-striped table-bordered table-white">
9
+ <thead>
10
+ <tr>
11
+ <th><%= t('ErrorMessage') %></th>
12
+ <th><%= t('JobCount') %></th>
13
+ </tr>
14
+ </thead>
15
+ <tbody>
16
+ <% @error_messages.each do |error_message, job_count| %>
17
+ <tr>
18
+ <td><a href="<%= root_path %>errors/<%= @error_class %>/<%= Digest::MD5.hexdigest(error_message) %>"><%= h error_message %></a></td>
19
+ <td><%= job_count %></td>
20
+ </tr>
21
+ <% end %>
22
+ </tbody>
23
+ </table>
24
+
25
+ <form action="<%= root_path %>errors/<%= @error_class %>/delete" method="post">
26
+ <input class="btn btn-danger btn-xs pull-right" type="submit" name="delete" value="<%= t('DeleteAll') %>" data-confirm="<%= t('AreYouSure') %>" />
27
+ </form>
28
+ <form action="<%= root_path %>errors/<%= @error_class %>/retry" method="post">
29
+ <input class="btn btn-danger btn-xs pull-right" type="submit" name="retry" value="<%= t('RetryAll') %>" data-confirm="<%= t('AreYouSure') %>" />
30
+ </form>
31
+
32
+ <% else %>
33
+ <div class="alert alert-success">No <%= t('Failures') %></div>
34
+ <% end %>
@@ -0,0 +1,47 @@
1
+ <header class="row">
2
+ <div class="col-sm-5">
3
+ <h3><%= t('Errors') %> <%= @error_class %></h3>
4
+ </div>
5
+ </header>
6
+
7
+ <% if @retries.size > 0 %>
8
+ <table class="table table-striped table-bordered table-white">
9
+ <thead>
10
+ <tr>
11
+ <th><%= t('NextRetry') %></th>
12
+ <th><%= t('RetryCount') %></th>
13
+ <th><%= t('Queue') %></th>
14
+ <th><%= t('Job') %></th>
15
+ <th><%= t('Arguments') %></th>
16
+ <th><%= t('Error') %></th>
17
+ </tr>
18
+ </thead>
19
+ <% @retries.each do |entry| %>
20
+ <tr>
21
+ <td>
22
+ <a href="<%= root_path %>retries/<%= job_params(entry.item, entry.score) %>"><%= relative_time(entry.at) %></a>
23
+ </td>
24
+ <td><%= entry['retry_count'] %></td>
25
+ <td>
26
+ <a href="<%= root_path %>queues/<%= entry.queue %>"><%= entry.queue %></a>
27
+ </td>
28
+ <td><%= entry.display_class %></td>
29
+ <td>
30
+ <div class="args"><%= display_args(entry.display_args) %></div>
31
+ </td>
32
+ <td>
33
+ <div><%= h truncate("#{entry['error_class']}: #{entry['error_message']}", 200) %></div>
34
+ </td>
35
+ </tr>
36
+ <% end %>
37
+ </table>
38
+ <form action="<%= root_path %>errors/<%= @error_class %>/<%= @error_message %>/delete" method="post">
39
+ <input class="btn btn-danger btn-xs pull-right" type="submit" name="delete" value="<%= t('DeleteAll') %>" data-confirm="<%= t('AreYouSure') %>" />
40
+ </form>
41
+ <form action="<%= root_path %>errors/<%= @error_class %>/<%= @error_message %>/retry" method="post">
42
+ <input class="btn btn-danger btn-xs pull-right" type="submit" name="retry" value="<%= t('RetryAll') %>" data-confirm="<%= t('AreYouSure') %>" />
43
+ </form>
44
+
45
+ <% else %>
46
+ <div class="alert alert-success">No <%= t('Failures') %></div>
47
+ <% end %>
@@ -0,0 +1,83 @@
1
+ module Sidekiq
2
+ module Errors
3
+ module WebExtension
4
+ def self.registered(app)
5
+ view_path = File.join(File.expand_path("..", __FILE__), "views")
6
+
7
+ app.post "/errors/:error_class/:error_message/retry" do
8
+ @error_class = params[:error_class]
9
+ @error_message = params[:error_message]
10
+ Sidekiq::RetrySet.new.select do |retri|
11
+ retri.item['error_class'] == @error_class &&
12
+ Digest::MD5.hexdigest(retri.item['error_message']) == @error_message
13
+ end.map(&:retry).length
14
+ redirect "#{root_path}errors/#{@error_class}/#{@error_message}"
15
+ end
16
+
17
+ app.post "/errors/:error_class/:error_message/delete" do
18
+ @error_class = params[:error_class]
19
+ @error_message = params[:error_message]
20
+ Sidekiq::RetrySet.new.select do |retri|
21
+ retri.item['error_class'] == @error_class &&
22
+ Digest::MD5.hexdigest(retri.item['error_message']) == @error_message
23
+ end.map(&:delete).length
24
+ redirect "#{root_path}errors/#{@error_class}/#{@error_message}"
25
+ end
26
+
27
+ app.post "/errors/:error_class/retry" do
28
+ @error_class = params[:error_class]
29
+ Sidekiq::RetrySet.new.select do |retri|
30
+ retri.item['error_class'] == @error_class
31
+ end.map(&:retry).length
32
+ redirect "#{root_path}errors/#{@error_class}"
33
+ end
34
+
35
+ app.post "/errors/:error_class/delete" do
36
+ @error_class = params[:error_class]
37
+ Sidekiq::RetrySet.new.select do |retri|
38
+ retri.item['error_class'] == @error_class
39
+ end.map(&:delete).length
40
+ redirect "#{root_path}errors/#{@error_class}"
41
+ end
42
+
43
+ app.get "/errors/:error_class/:error_message" do
44
+ @error_class = params[:error_class]
45
+ @error_message = params[:error_message]
46
+ @retries = Sidekiq.redis {|c| c.zrange("retry", 0, Sidekiq.errors_max_count, :with_scores => true) }
47
+ @retries = @retries
48
+ .map {|msg, score| Sidekiq::SortedEntry.new(nil, score, msg) }
49
+ .select{|job| job['error_class'] == @error_class }
50
+ .select{|job| Digest::MD5.hexdigest(job['error_message']) == @error_message }
51
+ @total_size = @count = @retries.length
52
+ render(:erb, File.read(File.join(view_path, "errors_class_message.erb")))
53
+ end
54
+
55
+ app.get "/errors/:error_class" do
56
+ @error_class = params[:error_class]
57
+ @error_messages = Hash[
58
+ Sidekiq.redis {|c| c.zrange("retry", 0, Sidekiq.errors_max_count) }
59
+ .collect{|job| Sidekiq.load_json(job)}
60
+ .select{|job| job['error_class'] == @error_class }
61
+ .collect{|job| job['error_message'] }
62
+ .histogram.
63
+ sort_by{|k,v| v}
64
+ .reverse
65
+ ]
66
+ render(:erb, File.read(File.join(view_path, "errors_class.erb")))
67
+ end
68
+
69
+ app.get "/errors" do
70
+ @errors = Hash[
71
+ Sidekiq.redis {|c| c.zrange("retry", 0, Sidekiq.errors_max_count) }
72
+ .collect{|job| Sidekiq.load_json(job)['error_class']}
73
+ .histogram
74
+ .sort_by{|k,v| v}
75
+ .reverse
76
+ ]
77
+ render(:erb, File.read(File.join(view_path, "errors.erb")))
78
+ end
79
+
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,16 @@
1
+ require File.expand_path('../lib/sidekiq/errors/version', __FILE__)
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "sidekiq-errors"
5
+ spec.version = Sidekiq::Errors::VERSION
6
+ spec.summary = %q{better manage sidekiq retries}
7
+ spec.description = %q{relatively simple but more efficient way to manage a large number of sidekiq retries.}
8
+ spec.authors = ["christopher holt"]
9
+ spec.email = "chris@tech4gold.com"
10
+ spec.homepage = "https://github.com/tech4gold/sidekiq-errors/"
11
+ spec.license = "MIT"
12
+ spec.files = `git ls-files`.split($\)
13
+
14
+ spec.add_dependency 'sidekiq', '>= 3.2.4', '~>3.2'
15
+
16
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sidekiq-errors
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - christopher holt
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-09-17 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: 3.2.4
20
+ - - "~>"
21
+ - !ruby/object:Gem::Version
22
+ version: '3.2'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 3.2.4
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '3.2'
33
+ description: relatively simple but more efficient way to manage a large number of
34
+ sidekiq retries.
35
+ email: chris@tech4gold.com
36
+ executables: []
37
+ extensions: []
38
+ extra_rdoc_files: []
39
+ files:
40
+ - ".gitignore"
41
+ - Gemfile
42
+ - MIT-LICENSE
43
+ - README.md
44
+ - lib/sidekiq-errors.rb
45
+ - lib/sidekiq/errors.rb
46
+ - lib/sidekiq/errors/version.rb
47
+ - lib/sidekiq/errors/views/errors.erb
48
+ - lib/sidekiq/errors/views/errors_class.erb
49
+ - lib/sidekiq/errors/views/errors_class_message.erb
50
+ - lib/sidekiq/errors/web_extension.rb
51
+ - sidekiq-errors.gemspec
52
+ homepage: https://github.com/tech4gold/sidekiq-errors/
53
+ licenses:
54
+ - MIT
55
+ metadata: {}
56
+ post_install_message:
57
+ rdoc_options: []
58
+ require_paths:
59
+ - lib
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ requirements: []
71
+ rubyforge_project:
72
+ rubygems_version: 2.2.2
73
+ signing_key:
74
+ specification_version: 4
75
+ summary: better manage sidekiq retries
76
+ test_files: []
77
+ has_rdoc: