resque-cleaner 0.2.12 → 0.3.0

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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZTcwYzM2YTgyOGI5ZDI2OWM0MzM2YjM5ODU2NGI4N2NiN2ZiZDFhYg==
4
+ MWNmOTljMTBiYjM2YzA4NmZjOTU2ZTY5NDYwODdhYTQwYmNkNjIzMQ==
5
5
  data.tar.gz: !binary |-
6
- NDc1YjU5MWYwNDk4MzJjOGZmZjFjOGQ2MzJkMmEyMzY5NDk0Y2JmZQ==
6
+ NjIzNzI2MGQ2YjMxNTYyZDZhZTE0NWI4NDViNTZiNTdiNDU1NmJmZg==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MzIzMTNjNmE5ZjMwZmE2YmM2YzJhYzJlNjQyMWRhMDU2NTUyM2JhYzc0MGUy
10
- NWRhZGI5ZTUyMWY5ZTVjMjBmNWJjNjdkYmEzNDIzODA2MzBjNzViZmRmYmMy
11
- ZjI2NWViZjJjMjFkYmQ4MGRkOGQ2MzdjNjdmODNhYjlkNTFmNzM=
9
+ Y2Q0NTQ3NWYwNzk2MDc5NjQ0MDVkOGMwZjZkYmUzZTY1MjlmZjRiMDcyNWQ3
10
+ ZTBlMzEyMWIxM2RmNzBkODBmNGFmOWQ2M2ZjZGJlYTRhNDIzZTYwMTVlMzQx
11
+ ZWU4ODViOGNhNjMxN2RkZGQwZmE2YzliNDA4YjcxOGUxM2I1ODA=
12
12
  data.tar.gz: !binary |-
13
- MDZlMTQyNzQ0Y2MyZWQyZDMzNjNjYzVlOGVhNjM4NWFjMDQ2MTEyNDE5NDY2
14
- NDdhM2U5MDk3YWYzNjY4M2E3MjU2MGMyZmRkY2Y4ZDA0MzdjMWQ5MGM3YmI1
15
- MGM2NGE1YzZkOGIwMjViZjAwMDY4NmNmNWMyZGM4ZDIzYjVlMjk=
13
+ YzkzNjI4NmExNTE3MmZkNzE2ZjNjZTVmNzRmZDRiYWQwY2VjZmEwN2MxZjUw
14
+ NjMxZmJjNzViZmM2ZDExMThlNjNmOTYyYjRjMzZhNDgzMDlmZmYyNWZmNzIx
15
+ YTE1N2Q5MzE0YWQ0Y2QxMjA1NmZlYTQyY2MyMGRlNWRiOWJlYTQ=
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## 0.3.0 (2014-05-27)
2
+
3
+ * Search by regex (#27)
4
+ * Show stats by exception (#29)
5
+ * Stop supporting ruby 1.8.x and 1.9.2
6
+ * Escape query parameters (#30)
7
+
1
8
  ## 0.2.12 (2013-12-03)
2
9
 
3
10
  * Remove Resque::Helpers include (#23)
data/README.md CHANGED
@@ -27,7 +27,7 @@ Resque-Web integration
27
27
  ----------------------
28
28
 
29
29
  ![Screen 1](https://github.com/ono/resque-cleaner/raw/master/misc/resque-cleaner-main.png)
30
- ![Screen 2](https://github.com/ono/resque-cleaner/raw/master/misc/resque-cleaner-list.png)
30
+ ![Screen 2](misc/resque-cleaner-list-with-regex.png)
31
31
 
32
32
 
33
33
  Configuration
@@ -117,6 +117,13 @@ e.g. Show stats only of jobs entered with some arguments:
117
117
  => {'2009/03/10' => 3, ...}
118
118
  ```
119
119
 
120
+ A convenience helper for searching for failed jobs which satisfy a
121
+ regular expression:
122
+
123
+ ```ruby
124
+ cleaner.select_by_regex(/Jason/) # => all failed jobs that have "Jason" in them
125
+ ```
126
+
120
127
  **Retry(Requeue) Jobs**
121
128
 
122
129
  You can retry all failed jobs with this method.
@@ -90,6 +90,12 @@ module Resque
90
90
  end
91
91
  alias :failure_jobs :select
92
92
 
93
+ def select_by_regex(regex)
94
+ select do |job|
95
+ job.to_s =~ regex
96
+ end
97
+ end
98
+
93
99
  # Clears every jobs for which block evaluates to true.
94
100
  def clear(&block)
95
101
  cleared = 0
@@ -103,6 +103,11 @@ module ResqueCleaner
103
103
  def show_job_args(args)
104
104
  Array(args).map { |a| a.inspect }.join("\n")
105
105
  end
106
+
107
+ def text_filter(id, name, value)
108
+ html = "<input id=\"#{id}\" type=\"text\" name=\"#{name}\" value=\"#{value}\">"
109
+ html += "</input>"
110
+ end
106
111
  end
107
112
 
108
113
  mime_type :json, 'application/json'
@@ -112,24 +117,27 @@ module ResqueCleaner
112
117
  load_cleaner_filter
113
118
 
114
119
  @jobs = cleaner.select
115
- @stats, @total = {}, {"total" => 0, "1h" => 0, "3h" => 0, "1d" => 0, "3d" => 0, "7d" => 0}
120
+ @stats = { :klass => {}, :exception => {} }
121
+ @total = Hash.new(0)
116
122
  @jobs.each do |job|
117
- klass = if job["payload"] && job["payload"]["class"]
118
- job["payload"]["class"]
119
- else
120
- "UNKNOWN"
121
- end
123
+ klass = job["payload"]["class"] || 'UNKNOWN'
124
+ exception = job["exception"] || 'UNKNOWN'
122
125
  failed_at = Time.parse job["failed_at"]
123
-
124
- @stats[klass] ||= {"total" => 0, "1h" => 0, "3h" => 0, "1d" => 0, "3d" => 0, "7d" => 0}
125
- items = [@stats[klass],@total]
126
-
127
- items.each{|a| a["total"] += 1}
128
- items.each{|a| a["1h"] += 1} if failed_at >= hours_ago(1)
129
- items.each{|a| a["3h"] += 1} if failed_at >= hours_ago(3)
130
- items.each{|a| a["1d"] += 1} if failed_at >= hours_ago(24)
131
- items.each{|a| a["3d"] += 1} if failed_at >= hours_ago(24*3)
132
- items.each{|a| a["7d"] += 1} if failed_at >= hours_ago(24*7)
126
+ @stats[:klass][klass] ||= Hash.new(0)
127
+ @stats[:exception][exception] ||= Hash.new(0)
128
+
129
+ [
130
+ @stats[:klass][klass],
131
+ @stats[:exception][exception],
132
+ @total
133
+ ].each do |stat|
134
+ stat[:total] += 1
135
+ stat[:h1] += 1 if failed_at >= hours_ago(1)
136
+ stat[:h3] += 1 if failed_at >= hours_ago(3)
137
+ stat[:d1] += 1 if failed_at >= hours_ago(24)
138
+ stat[:d3] += 1 if failed_at >= hours_ago(24*3)
139
+ stat[:d7] += 1 if failed_at >= hours_ago(24*7)
140
+ end
133
141
  end
134
142
 
135
143
  erb File.read(ResqueCleaner::Server.erb_path('cleaner.erb'))
@@ -138,14 +146,13 @@ module ResqueCleaner
138
146
  get "/cleaner_list" do
139
147
  load_library
140
148
  load_cleaner_filter
149
+ build_urls
141
150
 
142
151
  block = filter_block
143
152
 
144
153
  @failed = cleaner.select(&block).reverse
145
154
 
146
- url = "cleaner_list?c=#{@klass}&ex=#{@exception}&f=#{@from}&t=#{@to}"
147
- @dump_url = "cleaner_dump?c=#{@klass}&ex=#{@exception}&f=#{@from}&t=#{@to}"
148
- @paginate = Paginate.new(@failed, url, params[:p].to_i)
155
+ @paginate = Paginate.new(@failed, @list_url, params[:p].to_i)
149
156
 
150
157
  @klasses = cleaner.stats_by_class.keys
151
158
  @exceptions = cleaner.stats_by_exception.keys
@@ -157,6 +164,7 @@ module ResqueCleaner
157
164
  post "/cleaner_exec" do
158
165
  load_library
159
166
  load_cleaner_filter
167
+ build_urls
160
168
 
161
169
  if params[:select_all_pages]!="1"
162
170
  @sha1 = {}
@@ -172,7 +180,6 @@ module ResqueCleaner
172
180
  when "retry" then cleaner.requeue(false,{},&block)
173
181
  end
174
182
 
175
- @url = "cleaner_list?c=#{@klass}&ex=#{@exception}&f=#{@from}&t=#{@to}"
176
183
  erb File.read(ResqueCleaner::Server.erb_path('cleaner_exec.erb'))
177
184
  end
178
185
 
@@ -219,6 +226,20 @@ module ResqueCleaner
219
226
  @to = params[:t]=="" ? nil : params[:t]
220
227
  @klass = params[:c]=="" ? nil : params[:c]
221
228
  @exception = params[:ex]=="" ? nil : params[:ex]
229
+ @regex = params[:regex]=="" ? nil : params[:regex]
230
+ end
231
+
232
+ def build_urls
233
+ params = {
234
+ c: @klass,
235
+ ex: @exception,
236
+ f: @from,
237
+ t: @to,
238
+ regex: @regex
239
+ }.map {|key,value| "#{key}=#{URI.encode(value.to_s)}"}.join("&")
240
+
241
+ @list_url = "cleaner_list?#{params}"
242
+ @dump_url = "cleaner_dump?#{params}"
222
243
  end
223
244
 
224
245
  def filter_block
@@ -227,7 +248,8 @@ module ResqueCleaner
227
248
  (!@to || j.before?(hours_ago(@to))) &&
228
249
  (!@klass || j.klass?(@klass)) &&
229
250
  (!@exception || j.exception?(@exception)) &&
230
- (!@sha1 || @sha1[Digest::SHA1.hexdigest(j.to_json)])
251
+ (!@sha1 || @sha1[Digest::SHA1.hexdigest(j.to_json)]) &&
252
+ (!@regex || j.to_s =~ /#{@regex}/)
231
253
  }
232
254
  end
233
255
 
@@ -0,0 +1,44 @@
1
+ <table class="class_list">
2
+ <tr>
3
+ <th><%= type.gsub('klass','class').capitalize %></th>
4
+ <th>Failed</th>
5
+ <th>In last 1 hour</th>
6
+ <th>In last 3 hours</th>
7
+ <th>In last 24 hours</th>
8
+ <th>In last 3 days</th>
9
+ <th>In last 7 days</th>
10
+ </tr>
11
+ <% @stats[type.to_sym].each do |field,count| %>
12
+ <tr>
13
+ <% filter = "#{q}=#{URI.encode(field)}" %>
14
+ <td><%= field %></td>
15
+ <td class="number">
16
+ <a href="cleaner_list?<%=filter%>"><%= count[:total] %></a>
17
+ </td>
18
+ <td class="number">
19
+ <a href="cleaner_list?<%=filter%>&f=1"><%= count[:h1] %></a>
20
+ </td>
21
+ <td class="number">
22
+ <a href="cleaner_list?<%=filter%>&f=3"><%= count[:h3] %></a>
23
+ </td>
24
+ <td class="number">
25
+ <a href="cleaner_list?<%=filter%>&f=24"><%= count[:d1] %></a>
26
+ </td>
27
+ <td class="number">
28
+ <a href="cleaner_list?<%=filter%>&f=72"><%= count[:d3] %></a>
29
+ </td>
30
+ <td class="number">
31
+ <a href="cleaner_list?<%=filter%>&f=168"><%= count[:d7] %></a>
32
+ </td>
33
+ </tr>
34
+ <% end %>
35
+ <tr class="total">
36
+ <td>Total</td>
37
+ <td class="number"><a href="cleaner_list"><%= @total[:total] %></a></td>
38
+ <td class="number"><a href="cleaner_list?f=1"><%= @total[:h1] %></a></td>
39
+ <td class="number"><a href="cleaner_list?f=3"><%= @total[:h3] %></a></td>
40
+ <td class="number"><a href="cleaner_list?f=24"><%= @total[:d1] %></a></td>
41
+ <td class="number"><a href="cleaner_list?f=72"><%= @total[:d3] %></a></td>
42
+ <td class="number"><a href="cleaner_list?f=168"><%= @total[:d7] %></a></td>
43
+ </tr>
44
+ </table>
@@ -2,40 +2,22 @@
2
2
 
3
3
  <div class="cleaner">
4
4
  <div class="title clearfix">
5
- <h1>Job Classes Failed</h1>
5
+ <h1>Group by class</h1>
6
6
  </div>
7
7
 
8
- <table class="class_list">
9
- <tr>
10
- <th>Class</th>
11
- <th>Failed</th>
12
- <th>In last 1 hour</th>
13
- <th>In last 3 hours</th>
14
- <th>In last 24 hours</th>
15
- <th>In last 3 days</th>
16
- <th>In last 7 days</th>
17
- </tr>
18
- <% @stats.each do |klass,count| %>
19
- <tr>
20
- <td><%= klass %></td>
21
- <td class="number"><a href="cleaner_list?c=<%=klass%>"><%= count["total"] %></a></td>
22
- <td class="number"><a href="cleaner_list?c=<%=klass%>&f=1"><%= count["1h"] %></a></td>
23
- <td class="number"><a href="cleaner_list?c=<%=klass%>&f=3"><%= count["3h"] %></a></td>
24
- <td class="number"><a href="cleaner_list?c=<%=klass%>&f=24"><%= count["1d"] %></a></td>
25
- <td class="number"><a href="cleaner_list?c=<%=klass%>&f=72"><%= count["3d"] %></a></td>
26
- <td class="number"><a href="cleaner_list?c=<%=klass%>&f=168"><%= count["7d"] %></a></td>
27
- </tr>
28
- <% end %>
29
- <tr class="total">
30
- <td>Total</td>
31
- <td class="number"><a href="cleaner_list"><%= @total["total"] %></a></td>
32
- <td class="number"><a href="cleaner_list?f=1"><%= @total["1h"] %></a></td>
33
- <td class="number"><a href="cleaner_list?f=3"><%= @total["3h"] %></a></td>
34
- <td class="number"><a href="cleaner_list?f=24"><%= @total["1d"] %></a></td>
35
- <td class="number"><a href="cleaner_list?f=72"><%= @total["3d"] %></a></td>
36
- <td class="number"><a href="cleaner_list?f=168"><%= @total["7d"] %></a></td>
37
- </tr>
38
- </table>
8
+ <%= erb(
9
+ File.read(ResqueCleaner::Server.erb_path("_stats.erb")),
10
+ locals: {q: 'c', type: 'klass'}
11
+ ) %>
12
+
13
+ <div class="title clearfix">
14
+ <h1>Group by exception</h1>
15
+ </div>
16
+
17
+ <%= erb(
18
+ File.read(ResqueCleaner::Server.erb_path("_stats.erb")),
19
+ locals: {q: 'ex', type: 'exception'}
20
+ ) %>
39
21
 
40
22
  <% if @cleaner.limiter.on? %>
41
23
  <%= erb File.read(ResqueCleaner::Server.erb_path("_limiter.erb")) %>
@@ -3,6 +3,6 @@
3
3
  <div class="cleaner">
4
4
  <p class="message">Processed <%= @count %> jobs.</p>
5
5
  <p class="back_to_list">
6
- <a href="<%=@url%>">Back to List</a>
6
+ <a href="<%=@list_url%>">Back to List</a>
7
7
  </p>
8
8
  </div>
@@ -21,6 +21,9 @@
21
21
  <span class="time_filter">
22
22
  To: <%= time_filter("filter_to","t",@to)%>
23
23
  </span>
24
+ <span class="regex_filter">
25
+ Regex: <%= text_filter("filter_regex", "regex", Rack::Utils.escape_html(@regex))%>
26
+ </span>
24
27
  <input type="submit" value="Filter" />
25
28
  </form>
26
29
  </div>
@@ -28,6 +28,18 @@ context "ResqueCleaner" do
28
28
  @cleaner.print_message = false
29
29
  end
30
30
 
31
+ test "#select_by_regex returns only Jason jobs" do
32
+ ret = @cleaner.select_by_regex(/Jason/)
33
+ assert_equal 13, ret.size
34
+ end
35
+
36
+ test "#select_by_regex returns an empty array if passed a non-regex" do
37
+ ['string', nil, 13, Class.new].each do |non_regex|
38
+ ret = @cleaner.select_by_regex(nil)
39
+ assert_equal 0, ret.size
40
+ end
41
+ end
42
+
31
43
  test "#select returns failure jobs" do
32
44
  ret = @cleaner.select
33
45
  assert_equal 42, ret.size
@@ -10,6 +10,8 @@ def setup_some_failed_jobs
10
10
 
11
11
  @worker = Resque::Worker.new(:jobs,:jobs2)
12
12
 
13
+ create_and_process_jobs :jobs, @worker, 1, Time.now, BadJobWithSyntaxError, "great_args"
14
+
13
15
  10.times {|i|
14
16
  create_and_process_jobs :jobs, @worker, 1, Time.now, BadJob, "test_#{i}"
15
17
  }
@@ -24,8 +26,9 @@ context "resque-web" do
24
26
  end
25
27
 
26
28
  test "#cleaner should respond with success" do
27
- get "/cleaner_list"
28
- assert last_response.ok?, last_response.errors
29
+ get "/cleaner"
30
+ assert last_response.body.include?('BadJob')
31
+ assert last_response.body =~ /\bException\b/
29
32
  end
30
33
 
31
34
  test "#cleaner_list should respond with success" do
@@ -38,9 +41,16 @@ context "resque-web" do
38
41
  assert last_response.body.include?('BadJob')
39
42
  end
40
43
 
44
+ test "#cleaner_list shows the failed jobs when we use a select_by_regex" do
45
+ get "/cleaner_list", :regex => "BadJob*"
46
+ assert last_response.body.include?('"BadJobWithSyntaxError"')
47
+ assert last_response.body.include?('"BadJob"')
48
+ end
49
+
50
+
41
51
  test '#cleaner_exec clears job' do
42
52
  post "/cleaner_exec", :action => "clear", :sha1 => Digest::SHA1.hexdigest(@cleaner.select[0].to_json)
43
- assert_equal 9, @cleaner.select.size
53
+ assert_equal 10, @cleaner.select.size
44
54
  end
45
55
  test "#cleaner_dump should respond with success" do
46
56
  get "/cleaner_dump"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: resque-cleaner
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.12
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tatsuya Ono
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-12-03 00:00:00.000000000 Z
11
+ date: 2014-05-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: resque
@@ -43,6 +43,7 @@ files:
43
43
  - lib/resque_cleaner/server/public/cleaner.css
44
44
  - lib/resque_cleaner/server/views/_limiter.erb
45
45
  - lib/resque_cleaner/server/views/_paginate.erb
46
+ - lib/resque_cleaner/server/views/_stats.erb
46
47
  - lib/resque_cleaner/server/views/cleaner.erb
47
48
  - lib/resque_cleaner/server/views/cleaner_exec.erb
48
49
  - lib/resque_cleaner/server/views/cleaner_list.erb
@@ -65,7 +66,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
65
66
  requirements:
66
67
  - - ! '>='
67
68
  - !ruby/object:Gem::Version
68
- version: '0'
69
+ version: 1.9.3
69
70
  required_rubygems_version: !ruby/object:Gem::Requirement
70
71
  requirements:
71
72
  - - ! '>='