resque-cleanerer 0.5.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 +7 -0
- data/CHANGELOG.md +92 -0
- data/LICENSE +20 -0
- data/README.md +333 -0
- data/Rakefile +38 -0
- data/lib/resque-cleaner.rb +1 -0
- data/lib/resque_cleaner/server/views/_cleaner_styles.erb +63 -0
- data/lib/resque_cleaner/server/views/_limiter.erb +13 -0
- data/lib/resque_cleaner/server/views/_paginate.erb +54 -0
- data/lib/resque_cleaner/server/views/_stats.erb +44 -0
- data/lib/resque_cleaner/server/views/cleaner.erb +25 -0
- data/lib/resque_cleaner/server/views/cleaner_exec.erb +8 -0
- data/lib/resque_cleaner/server/views/cleaner_list.erb +179 -0
- data/lib/resque_cleaner/server.rb +258 -0
- data/lib/resque_cleaner.rb +309 -0
- data/test/redis-test.conf +115 -0
- data/test/resque_cleaner_test.rb +206 -0
- data/test/resque_web_test.rb +66 -0
- data/test/test_helper.rb +131 -0
- metadata +106 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 169e0b85f5b87c2b4fe7a19a763ab2b8a2db96f5625021b2a1888b71dd670e26
|
4
|
+
data.tar.gz: b3246d131619b8f8ff3612aa87b1958fe81df8b31f117a94681804dca3d56e35
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a4c8a7104f3251aa8dc3e25823265cb8d7c4cef6b070e9f9e3cdef652792928f95d237fd19f6f61c8c412f43ec4f09db4745a4c2e1f19917f43ac781adb25ce7
|
7
|
+
data.tar.gz: 5fb2ca512f0b3f06628e6a4f9b7a5044257a36c717ba107d06bd6ff45ef43b05a3c495e51cc02f2d1b5867018fdc496be968b7b2df0aa54b4a7f67cdf56c2fac
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
## 0.4.1 (2018-01-25)
|
2
|
+
|
3
|
+
* Remove Requeue version lock (#46)
|
4
|
+
|
5
|
+
## 0.4.0 (2017-11-20)
|
6
|
+
|
7
|
+
* Render CSS as ERB partial to make Rails 5 compatible (#45)
|
8
|
+
|
9
|
+
## 0.3.2 (2016-03-09)
|
10
|
+
|
11
|
+
* Handle failure JSON with nil on payload safely (#40)
|
12
|
+
|
13
|
+
## 0.3.1 (2016-01-28)
|
14
|
+
|
15
|
+
* Bug fix: fix the issue regex is not applied on bulk clearance (#36)
|
16
|
+
|
17
|
+
## 0.3.0 (2014-05-27)
|
18
|
+
|
19
|
+
* Search by regex (#27)
|
20
|
+
* Show stats by exception (#29)
|
21
|
+
* Stop supporting ruby 1.8.x and 1.9.2
|
22
|
+
* Escape query parameters (#30)
|
23
|
+
|
24
|
+
## 0.2.12 (2013-12-03)
|
25
|
+
|
26
|
+
* Remove Resque::Helpers include (#23)
|
27
|
+
* Tweak Gemspec (#24)
|
28
|
+
* Don't use yaml format to show arguments
|
29
|
+
* Tweak README
|
30
|
+
|
31
|
+
## 0.2.11 (2013-07-19)
|
32
|
+
|
33
|
+
* Use transaction for retry-and-clear (#22).
|
34
|
+
* Fix for CI
|
35
|
+
|
36
|
+
## 0.2.10 (2012-10-15)
|
37
|
+
|
38
|
+
* Bug fix: use URL helper to support resque-web which is not hosted under '/'.
|
39
|
+
|
40
|
+
## 0.2.9 (2012-05-10)
|
41
|
+
|
42
|
+
* Make limiter configurable on resque-web.
|
43
|
+
|
44
|
+
## 0.2.8 (2012-03-19)
|
45
|
+
|
46
|
+
* UI tweak (#15)
|
47
|
+
|
48
|
+
## 0.2.7 (2012-01-17)
|
49
|
+
|
50
|
+
* Support Travis CI
|
51
|
+
* Support failure jobs without payload information (#11).
|
52
|
+
|
53
|
+
## 0.2.6 (2011-08-23)
|
54
|
+
|
55
|
+
* Follow the latest resque for date format.
|
56
|
+
|
57
|
+
## 0.2.5 (2011-05-05)
|
58
|
+
|
59
|
+
* BUGFIX: Pagination has been broken.
|
60
|
+
* Dump a list as JSON format.
|
61
|
+
|
62
|
+
## 0.2.4 (2011-04-19)
|
63
|
+
|
64
|
+
* BUGFIX: "Select All" ignores exception filter.
|
65
|
+
|
66
|
+
## 0.2.3 (2011-04-11)
|
67
|
+
|
68
|
+
* Exception filter.
|
69
|
+
|
70
|
+
## 0.2.2 (2011-04-07)
|
71
|
+
|
72
|
+
* Changed a way to load yajl/json\_gem.
|
73
|
+
|
74
|
+
## 0.2.1 (2011-04-06)
|
75
|
+
|
76
|
+
* BUGFIX: Bulk action didn't work properly when you select all jobs.
|
77
|
+
* Removed absolute paths from html.
|
78
|
+
|
79
|
+
## 0.2.0 (2011-04-06)
|
80
|
+
|
81
|
+
* Extended with resque-web
|
82
|
+
|
83
|
+
## 0.1.1 (2010-12-30)
|
84
|
+
|
85
|
+
* Fixed for ruby 1.9.2
|
86
|
+
* Fixed a bug on #retried? method
|
87
|
+
|
88
|
+
## 0.1.0 (2010-11-24)
|
89
|
+
|
90
|
+
* First official release
|
91
|
+
|
92
|
+
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Tatsuya Ono
|
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.
|
data/README.md
ADDED
@@ -0,0 +1,333 @@
|
|
1
|
+
ResqueCleaner
|
2
|
+
=============
|
3
|
+
|
4
|
+
[github.com/ono/resque-cleaner](https://github.com/ono/resque-cleaner)
|
5
|
+
|
6
|
+
This project is not active.
|
7
|
+
Please read [this](https://github.com/ono/resque-cleaner/issues/47) before you use the library.
|
8
|
+
|
9
|
+
Description
|
10
|
+
-----------
|
11
|
+
|
12
|
+
ResqueCleaner is a [Resque](https://github.com/defunkt/resque) plugin which
|
13
|
+
aims to help you to clean up failed jobs on Resque by:
|
14
|
+
|
15
|
+
* Showing stats of failed jobs
|
16
|
+
* Retrying failed jobs
|
17
|
+
* Removing failed jobs
|
18
|
+
* Filtering failed jobs
|
19
|
+
|
20
|
+
|
21
|
+
Installation
|
22
|
+
------------
|
23
|
+
|
24
|
+
Install as a gem:
|
25
|
+
|
26
|
+
$ gem install resque-cleaner
|
27
|
+
|
28
|
+
|
29
|
+
Resque-Web integration
|
30
|
+
----------------------
|
31
|
+
|
32
|
+

|
33
|
+

|
34
|
+
|
35
|
+
|
36
|
+
Configuration
|
37
|
+
-------------
|
38
|
+
|
39
|
+
At first, you have to load ResqueCleaner to enable the Cleaner tab. Here is
|
40
|
+
an example step.
|
41
|
+
|
42
|
+
1. Create a configuration file for resque-web
|
43
|
+
<br/>```touch [app_dir]/config/resque-web.rb```
|
44
|
+
|
45
|
+
2. Add the following line into the file
|
46
|
+
<br/>```require 'resque-cleaner'```
|
47
|
+
|
48
|
+
3. Then pass the file when you start resque-web
|
49
|
+
<br/>```% resque-web [app_dir]/config/resque-web.rb```
|
50
|
+
|
51
|
+
You can also configure [limiter](https://github.com/ono/resque-cleaner#limiter)
|
52
|
+
in the file.
|
53
|
+
|
54
|
+
e.g.
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
require 'resque-cleaner'
|
58
|
+
module Resque::Plugins
|
59
|
+
ResqueCleaner::Limiter.default_maximum = 10_000
|
60
|
+
end
|
61
|
+
```
|
62
|
+
|
63
|
+
Console
|
64
|
+
-------
|
65
|
+
|
66
|
+
Hopefully a situation of your failed jobs is simple enough to get figured out through
|
67
|
+
the web interface. But, if not, a powerful filtering feature of ResqueCleaner may help
|
68
|
+
you to understand what is going on with your console(irb).
|
69
|
+
|
70
|
+
**Create Instance**
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
> cleaner = Resque::Plugins::ResqueCleaner.new
|
74
|
+
```
|
75
|
+
|
76
|
+
**Show Stats**
|
77
|
+
|
78
|
+
Shows stats of failed jobs grouped by date.
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
> cleaner.stats_by_date
|
82
|
+
2009/03/13: 6
|
83
|
+
2009/11/13: 14
|
84
|
+
2010/08/13: 22
|
85
|
+
total: 42
|
86
|
+
=> {'2009/03/10' => 6, ...}
|
87
|
+
```
|
88
|
+
|
89
|
+
You could also group them by class.
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
> cleaner.stats_by_class
|
93
|
+
BadJob: 3
|
94
|
+
HorribleJob: 7
|
95
|
+
total: 10
|
96
|
+
=> {'BadJob' => 3, ...}
|
97
|
+
```
|
98
|
+
|
99
|
+
Or you could also group them by exception.
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
> cleaner.stats_by_exception
|
103
|
+
RuntimeError: 35
|
104
|
+
SyntaxError: 7
|
105
|
+
total: 42
|
106
|
+
=> {'RuntimeError' => 35, ...}
|
107
|
+
```
|
108
|
+
|
109
|
+
You can get the ones filtered with a block: it targets only jobs which the block
|
110
|
+
evaluates true.
|
111
|
+
|
112
|
+
e.g. Show stats only of jobs entered with some arguments:
|
113
|
+
|
114
|
+
```ruby
|
115
|
+
> cleaner.stats_by_date {|j| j["payload"]["args"].size > 0}
|
116
|
+
2009/03/13: 3
|
117
|
+
2009/11/13: 7
|
118
|
+
2010/08/13: 11
|
119
|
+
total: 22
|
120
|
+
=> {'2009/03/10' => 3, ...}
|
121
|
+
```
|
122
|
+
|
123
|
+
A convenience helper for searching for failed jobs which satisfy a
|
124
|
+
regular expression:
|
125
|
+
|
126
|
+
```ruby
|
127
|
+
cleaner.select_by_regex(/Jason/) # => all failed jobs that have "Jason" in them
|
128
|
+
```
|
129
|
+
|
130
|
+
**Retry(Requeue) Jobs**
|
131
|
+
|
132
|
+
You can retry all failed jobs with this method.
|
133
|
+
|
134
|
+
```ruby
|
135
|
+
> cleaner.requeue
|
136
|
+
```
|
137
|
+
|
138
|
+
Of course, you can filter jobs with a block; it requeues only jobs which the
|
139
|
+
block evaluates true.
|
140
|
+
|
141
|
+
e.g. Retry only jobs with some arguments:
|
142
|
+
|
143
|
+
```ruby
|
144
|
+
> cleaner.requeue {|j| j["payload"]["args"].size > 0}
|
145
|
+
```
|
146
|
+
|
147
|
+
The job hash is extended with a module which defines some useful methods. You
|
148
|
+
can use it in the block.
|
149
|
+
|
150
|
+
e.g. Retry only jobs entered within a day:
|
151
|
+
|
152
|
+
```ruby
|
153
|
+
> cleaner.requeue {|j| j.after?(1.day.ago)}
|
154
|
+
```
|
155
|
+
|
156
|
+
e.g. Retry EmailJob entered with arguments within 3 days:
|
157
|
+
|
158
|
+
```ruby
|
159
|
+
> cleaner.requeue {|j| j.after?(3.days.ago) && j.klass?(EmailJob) && j["payload"]["args"].size>0}
|
160
|
+
```
|
161
|
+
|
162
|
+
See Helper Methods section bellow for more information.
|
163
|
+
|
164
|
+
NOTE:
|
165
|
+
[1.day.ago](https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/numeric/time.rb)
|
166
|
+
is not in standard library. Using it for making explanation more understandable. It is equivalent to `Time.now - 60*60*24*3`.
|
167
|
+
|
168
|
+
**Clear Jobs**
|
169
|
+
|
170
|
+
You can clear all failed jobs with this method:
|
171
|
+
|
172
|
+
```ruby
|
173
|
+
> cleaner.clear
|
174
|
+
```
|
175
|
+
|
176
|
+
Like you can do with the retry method, the clear method takes a block. Here are
|
177
|
+
some examples:
|
178
|
+
|
179
|
+
```ruby
|
180
|
+
> cleaner.clear {|j| j.retried?}
|
181
|
+
=> clears all jobs already retried and returns number of the jobs.
|
182
|
+
|
183
|
+
> cleaner.clear {|j| j.queue?(:low) && j.before?('2010-10-10')}
|
184
|
+
=> clears all jobs entried in :low queue before 10th October, 2010.
|
185
|
+
|
186
|
+
> cleaner.clear {|j| j.exception?("RuntimeError") && j.queue?(:low)}
|
187
|
+
=> clears all jobs raised RuntimeError and queued :low queue
|
188
|
+
```
|
189
|
+
|
190
|
+
**Retry and Clear Jobs**
|
191
|
+
|
192
|
+
You can retry(requeue) and clear failed jobs at the same time; just pass true
|
193
|
+
as an argument.
|
194
|
+
|
195
|
+
e.g. Retry EmailJob and remove from failed jobs:
|
196
|
+
|
197
|
+
```ruby
|
198
|
+
> cleaner.requeue(true) {|j| j.klass?(EmailJob)}
|
199
|
+
```
|
200
|
+
|
201
|
+
**Retry with other queue**
|
202
|
+
|
203
|
+
You can requeue failed jobs into other queue. In this way, you can retry failed
|
204
|
+
jobs without blocking jobs being entered by your service running in the live.
|
205
|
+
|
206
|
+
e.g. Retry failed jobs on :retry queue
|
207
|
+
|
208
|
+
```ruby
|
209
|
+
> cleaner.requeue(false, :queue => :retry)
|
210
|
+
```
|
211
|
+
|
212
|
+
Don't forget to launch resque worker for the queue.
|
213
|
+
|
214
|
+
% QUEUE=retry rake resque:work
|
215
|
+
|
216
|
+
**Select Jobs**
|
217
|
+
|
218
|
+
You can just select the jobs of course. Here are some examples:
|
219
|
+
|
220
|
+
```ruby
|
221
|
+
> cleaner.select {|j| j["payload"]["args"][0]=="Johonson"}
|
222
|
+
> cleaner.select {|j| j.after?(2.days.ago)}
|
223
|
+
> cleaner.select #=> returns all jobs
|
224
|
+
```
|
225
|
+
|
226
|
+
**Helper Methods**
|
227
|
+
|
228
|
+
Here is a list of methods a failed job retained through ResqueCleaner has:
|
229
|
+
|
230
|
+
retried?: returns true if the job has already been retried.
|
231
|
+
requeued?: alias of retried?.
|
232
|
+
before?(time): returns true if the job failed before the time.
|
233
|
+
after?(time): returns true if the job failed after the time.
|
234
|
+
klass?(klass_or_name): returns true if the class of job matches.
|
235
|
+
queue?(queue_name): returns true if the queue of job matches.
|
236
|
+
exception?(exception_name): returns true if the exception matches.
|
237
|
+
|
238
|
+
|
239
|
+
Failed Job
|
240
|
+
-----------
|
241
|
+
|
242
|
+
Here is a sample of failed jobs:
|
243
|
+
|
244
|
+
{"failed_at": "2009/03/13 00:00:00",
|
245
|
+
"payload": {"args": ["Johnson"], "class": "BadJob"},
|
246
|
+
"queue": "jobs",
|
247
|
+
"worker": "localhost:7327:jobs,jobs2",
|
248
|
+
"exception": "RuntimeError",
|
249
|
+
"error": "Bad job, Johnson",
|
250
|
+
"backtrace":
|
251
|
+
["./test/test_helper.rb:108:in `perform'",
|
252
|
+
"/opt/local/lib/ruby/gems/1.8/gems/resque-1.10.0/lib/resque/job.rb:133:in `perform'",
|
253
|
+
"/opt/local/lib/ruby/gems/1.8/gems/resque-1.10.0/lib/resque/worker.rb:157:in `perform'",
|
254
|
+
"/opt/local/lib/ruby/gems/1.8/gems/resque-1.10.0/lib/resque/worker.rb:124:in `work'",
|
255
|
+
"....(omitted)....",
|
256
|
+
"./test/test_helper.rb:41",
|
257
|
+
"test/resque_cleaner_test.rb:3"]
|
258
|
+
}
|
259
|
+
|
260
|
+
|
261
|
+
Limiter
|
262
|
+
-------
|
263
|
+
|
264
|
+
ResqueCleaner expects a disaster situation like a huge number of failed jobs are
|
265
|
+
out there. Since ResqueCleaner's filter function is running on your application
|
266
|
+
process but on your Redis, it would not respond ages if you try to deal with all
|
267
|
+
of those jobs.
|
268
|
+
|
269
|
+
ResqueCleaner supposes recent jobs are more important than old jobs. Therefore
|
270
|
+
ResqueCleaner deals with **ONLY LAST X(default=1000) JOBS**. In this way, you
|
271
|
+
could avoid slow responses. You can change the number through `limiter` attribute.
|
272
|
+
|
273
|
+
Let's see how it works with an following example.
|
274
|
+
|
275
|
+
**Sample Situation**
|
276
|
+
|
277
|
+
* Number of failed jobs: 100,000
|
278
|
+
|
279
|
+
Default limiter is 1000 so that the limiter returns 1000 as a count.
|
280
|
+
|
281
|
+
```ruby
|
282
|
+
> cleaner.limiter.count
|
283
|
+
=> 1,000
|
284
|
+
> cleaner.failure.count
|
285
|
+
=> 100,000
|
286
|
+
```
|
287
|
+
|
288
|
+
You could know if the limiter is on with on? method.
|
289
|
+
|
290
|
+
```ruby
|
291
|
+
> cleaner.limiter.on?
|
292
|
+
=> true
|
293
|
+
```
|
294
|
+
|
295
|
+
You can change the maximum number of the limiter with maximum attribute.
|
296
|
+
|
297
|
+
```ruby
|
298
|
+
> cleaner.limiter.maximum = 3000
|
299
|
+
=> 3,000
|
300
|
+
> cleaner.limiter.count
|
301
|
+
=> 3,000
|
302
|
+
> cleaner.limiter.on?
|
303
|
+
=> true
|
304
|
+
```
|
305
|
+
|
306
|
+
With limiter, ResqueCleaner's filtering targets only the last X(3000 in this
|
307
|
+
sample) failed jobs.
|
308
|
+
|
309
|
+
```ruby
|
310
|
+
> cleaner.select.size
|
311
|
+
=> 3,000
|
312
|
+
```
|
313
|
+
|
314
|
+
The clear\_stale method deletes all jobs entered prior to the last X(3000 in
|
315
|
+
this sample) failed jobs. This calls Redis API and no iteration occurs on Ruby
|
316
|
+
application; it should be quick even if there are huge number of failed jobs.
|
317
|
+
|
318
|
+
```ruby
|
319
|
+
> cleaner.clear_stale
|
320
|
+
> cleaner.failure.count
|
321
|
+
=> 3,000
|
322
|
+
> cleaner.limiter.count
|
323
|
+
=> 3,000
|
324
|
+
> cleaner.limiter.on?
|
325
|
+
=> false
|
326
|
+
```
|
327
|
+
|
328
|
+
Many Thanks!
|
329
|
+
------------
|
330
|
+
|
331
|
+
To our [Contributors](https://github.com/ono/resque-cleaner/contributors)
|
332
|
+
|
333
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
#
|
2
|
+
# Setup
|
3
|
+
#
|
4
|
+
|
5
|
+
# load 'tasks/redis.rake'
|
6
|
+
#require 'rake/testtask'
|
7
|
+
|
8
|
+
$LOAD_PATH.unshift 'lib'
|
9
|
+
#require 'resque/tasks'
|
10
|
+
|
11
|
+
def command?(command)
|
12
|
+
system("type #{command} > /dev/null 2>&1")
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
#
|
17
|
+
# Tests
|
18
|
+
#
|
19
|
+
|
20
|
+
task :default => :test
|
21
|
+
|
22
|
+
desc "Run the test suite"
|
23
|
+
task :test do
|
24
|
+
rg = command?(:rg)
|
25
|
+
Dir['test/**/*_test.rb'].each do |f|
|
26
|
+
rg ? sh("rg #{f}") : ruby(f)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
if command? :kicker
|
31
|
+
desc "Launch Kicker (like autotest)"
|
32
|
+
task :kicker do
|
33
|
+
puts "Kicking... (ctrl+c to cancel)"
|
34
|
+
exec "kicker -e rake test lib examples"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'resque_cleaner'
|
@@ -0,0 +1,63 @@
|
|
1
|
+
<style type="text/css" media="screen">
|
2
|
+
#main .cleaner .title h1 { float: left }
|
3
|
+
|
4
|
+
#main .cleaner .sub_header {color: #888; font-size: 80%; font-weight: bold}
|
5
|
+
|
6
|
+
#main .cleaner .control_panel {
|
7
|
+
margin: 5px 0 10px; padding: 5px; background: #eee; display: inline-block;
|
8
|
+
-webkit-border-radius:5px; border:1px solid #ccc;
|
9
|
+
}
|
10
|
+
|
11
|
+
#main .cleaner #exec { color: black; }
|
12
|
+
#main .cleaner #exec select { margin-right: 20px }
|
13
|
+
#main .cleaner #exec a { margin-right: 5px}
|
14
|
+
#main .cleaner #exec a.disabled { color: #aaa}
|
15
|
+
|
16
|
+
#main .cleaner table.class_list { width: auto }
|
17
|
+
#main .cleaner td.number { text-align: right }
|
18
|
+
#main .cleaner tr.total { border-top: 3px double #ccc}
|
19
|
+
|
20
|
+
#main .cleaner form { float: none; margin: 0}
|
21
|
+
|
22
|
+
#main .cleaner .warning { margin: 30px 0; padding: 10px; background: #fdd; display: inline-block; }
|
23
|
+
|
24
|
+
#main .clearfix:after {
|
25
|
+
content: ".";
|
26
|
+
display: block;
|
27
|
+
height: 0;
|
28
|
+
clear: both;
|
29
|
+
visibility: hidden;
|
30
|
+
}
|
31
|
+
#main .cleaner ul.failed {
|
32
|
+
margin-bottom: 10px
|
33
|
+
}
|
34
|
+
|
35
|
+
#main .cleaner .list_info{
|
36
|
+
color: #999; text-align: center;
|
37
|
+
}
|
38
|
+
#main .cleaner .list_info a{
|
39
|
+
color: #666
|
40
|
+
}
|
41
|
+
#main .cleaner .list_info .list_summary{
|
42
|
+
vertical-align: baseline;
|
43
|
+
display: inline-block;
|
44
|
+
margin: 0; padding:0;
|
45
|
+
}
|
46
|
+
#main .cleaner ul.pagination {
|
47
|
+
display: inline-block;
|
48
|
+
vertical-align: baseline;
|
49
|
+
margin:0; padding:0;
|
50
|
+
}
|
51
|
+
#main .cleaner ul.pagination li {
|
52
|
+
list-style:none; float: left; padding: 0 3px;
|
53
|
+
}
|
54
|
+
#main .cleaner ul.pagination li.current {
|
55
|
+
color: #333; font-weight: bold;
|
56
|
+
}
|
57
|
+
#main .cleaner ul.pagination li.summary{
|
58
|
+
padding-right: 10px
|
59
|
+
}
|
60
|
+
#main .cleaner div.dump{
|
61
|
+
float: right
|
62
|
+
}
|
63
|
+
</style>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<div class="warning">
|
2
|
+
<p>
|
3
|
+
There are more than <%= @cleaner.limiter.maximum%> jobs. ResqueCleaner handles only recent <%= @cleaner.limiter.maximum %> jobs. See the Limiter section on <a href="https://github.com/ono/resque-cleaner" target="_blank">README</a> for more detail.
|
4
|
+
</p>
|
5
|
+
<p>
|
6
|
+
<form method="post" action="cleaner_stale">
|
7
|
+
<input type="hidden" name="action" value="clear_stale" />
|
8
|
+
<input type="submit" onclick="return confirm('Are you sure?')" value="Clear all jobs older than <%= @cleaner.limiter.count %>th job."/>
|
9
|
+
(<%= @cleaner.failure.count - @cleaner.limiter.maximum %> jobs will be cleared)
|
10
|
+
</form>
|
11
|
+
</p>
|
12
|
+
</div>
|
13
|
+
|
@@ -0,0 +1,54 @@
|
|
1
|
+
<div class="list_info clearfix">
|
2
|
+
|
3
|
+
<ul class="pagination">
|
4
|
+
<li class="summary">
|
5
|
+
<%= @paginate.first_index%> - <%= @paginate.last_index%> / <%= @paginate.total_size%>
|
6
|
+
</li>
|
7
|
+
<% if @paginate.max_page>1 %>
|
8
|
+
<% if @paginate.first_page? %>
|
9
|
+
<li class="prev off"><<newer</li>
|
10
|
+
<% else %>
|
11
|
+
<li class="prev"><a href="<%= @paginate.page_url(:prev)%>"><<newer</a></li>
|
12
|
+
<% end %>
|
13
|
+
|
14
|
+
<% 1.upto(6<@paginate.max_page ? 6 : @paginate.max_page) do |pg| %>
|
15
|
+
<% if @paginate.page==pg %>
|
16
|
+
<li class="current"><%=pg%></li>
|
17
|
+
<% else %>
|
18
|
+
<li><a href="<%= @paginate.page_url(pg)%>"><%=pg%></a></li>
|
19
|
+
<% end %>
|
20
|
+
<% end %>
|
21
|
+
|
22
|
+
<% if @paginate.max_page > 6 %>
|
23
|
+
<% if @paginate.max_page!=@paginate.page %>
|
24
|
+
<% if @paginate.page>7 %>
|
25
|
+
<li class="off">...</li>
|
26
|
+
<% end %>
|
27
|
+
<% if @paginate.page>6 %>
|
28
|
+
<li class="current"><%=@paginate.page%></li>
|
29
|
+
<% end %>
|
30
|
+
<% end %>
|
31
|
+
<% if @paginate.max_page>7 && @paginate.page+1!=@paginate.max_page %>
|
32
|
+
<li class="off">...</li>
|
33
|
+
<% end %>
|
34
|
+
|
35
|
+
<% if @paginate.max_page==@paginate.page %>
|
36
|
+
<li class="current"><%=@paginate.max_page%></li>
|
37
|
+
<% else %>
|
38
|
+
<li><a href="<%= @paginate.page_url(@paginate.max_page)%>"><%=@paginate.max_page%></a></li>
|
39
|
+
<% end %>
|
40
|
+
<% end %>
|
41
|
+
|
42
|
+
<% if @paginate.last_page? %>
|
43
|
+
<li class="next off">older>></li>
|
44
|
+
<% else %>
|
45
|
+
<li class="next"><a href="<%= @paginate.page_url(:next)%>">older>></a></li>
|
46
|
+
<% end %>
|
47
|
+
<% end %>
|
48
|
+
|
49
|
+
</ul>
|
50
|
+
<div class="dump">
|
51
|
+
<a href="<%= @dump_url%>" target="_blank">Dump</a>
|
52
|
+
</div>
|
53
|
+
</div>
|
54
|
+
|
@@ -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}=#{CGI.escape(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>
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<%= erb File.read(ResqueCleaner::Server.erb_path("_cleaner_styles.erb")) %>
|
2
|
+
|
3
|
+
<div class="cleaner">
|
4
|
+
<div class="title clearfix">
|
5
|
+
<h1>Group by class</h1>
|
6
|
+
</div>
|
7
|
+
|
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
|
+
) %>
|
21
|
+
|
22
|
+
<% if @cleaner.limiter.on? %>
|
23
|
+
<%= erb File.read(ResqueCleaner::Server.erb_path("_limiter.erb")) %>
|
24
|
+
<% end %>
|
25
|
+
</div>
|