resque-cleaner 0.2.12 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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
  - - ! '>='