resque-analytics 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Changelog +8 -0
- data/README.rdoc +5 -1
- data/VERSION +1 -1
- data/lib/resque-analytics/server.rb +16 -1
- data/lib/resque-analytics/server/views/analytics.erb +3 -24
- data/lib/resque/plugins/analytics.rb +33 -6
- data/resque-analytics.gemspec +7 -5
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ee6adecc8664d4c813d51b0d276a09f3805eef5a
|
4
|
+
data.tar.gz: b3f61c77bfea5cc51b7bd9d1db1d2cdfcc5b786c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d514eba2882be8a2625773e4d4411fafc7a044159fdeaecae0b516ff43d73722bd79502fef94056a2dda4b8ad2dce5f5cd25106b3420c370cfa2e63569756620
|
7
|
+
data.tar.gz: 72db95f784fe75998f2bb4714c8e110fe453126d05b305c40840503b98336884555c8a6ad29562abf0f4cd754b518f5a5a6c98936f8407031e32361a08850508
|
data/Changelog
ADDED
data/README.rdoc
CHANGED
@@ -7,6 +7,11 @@ For each worker, the gem keeps the following key performance indicators:
|
|
7
7
|
* Number of times it executed successfuly per day
|
8
8
|
* Number of times is failed per day
|
9
9
|
* Total run time per day
|
10
|
+
* Total wait time per day, which is the amount of time items for this worker were waiting in the queue
|
11
|
+
|
12
|
+
Wait is somewhat tricky, as Resque doesn't provide the proper hooks to calculate this value. To handle that, I had to
|
13
|
+
replace Resque's push method, and Job initialization method. These methods now add a timestamp when items are added
|
14
|
+
to queues, and use the timestamp to calculate the total wait time, when an item is taken out of the queue.
|
10
15
|
|
11
16
|
== Installation
|
12
17
|
|
@@ -35,7 +40,6 @@ On the Resque screens, you will find a new tab called "Analytics".
|
|
35
40
|
== TODO
|
36
41
|
|
37
42
|
* Add tests
|
38
|
-
* Add queued time to total run time analytics
|
39
43
|
|
40
44
|
== Contributing to resque-analytics
|
41
45
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.6.0
|
@@ -32,6 +32,21 @@ module Resque
|
|
32
32
|
def chart_data(data, job, kpi)
|
33
33
|
legend_keys.map { |key| @data[job][kpi][key].to_i || 0 }
|
34
34
|
end
|
35
|
+
|
36
|
+
def chart_it(title, legend, data)
|
37
|
+
Gchart.bar(
|
38
|
+
data: data,
|
39
|
+
title: title,
|
40
|
+
format: "image_tag",
|
41
|
+
size: "1000x300",
|
42
|
+
axis_with_labels: ['x,y'],
|
43
|
+
bar_width_and_spacing: '6',
|
44
|
+
axis_range: [[-90,0,-5], [0, data.map(&:max).sum ]],
|
45
|
+
legend: legend,
|
46
|
+
legend_position: 'top',
|
47
|
+
bar_colors: ['000000', '0088FF']
|
48
|
+
)
|
49
|
+
end
|
35
50
|
end
|
36
51
|
|
37
52
|
class << self
|
@@ -39,7 +54,7 @@ module Resque
|
|
39
54
|
app.get '/analytics' do
|
40
55
|
@data = measured_jobs.inject({}) { |res, job|
|
41
56
|
res[job] = {}
|
42
|
-
[PERFORMED, FAILED, TOTAL_TIME].each { |kpi| res[job][kpi] = counters_for(job, kpi) }
|
57
|
+
[PERFORMED, FAILED, TOTAL_TIME, WAIT_TIME].each { |kpi| res[job][kpi] = counters_for(job, kpi) }
|
43
58
|
res
|
44
59
|
}
|
45
60
|
erb(File.read(File.join(VIEW_PATH, 'analytics.erb')))
|
@@ -8,30 +8,9 @@
|
|
8
8
|
<h2><%= job %></h2>
|
9
9
|
<% performed = chart_data(@data, job, Resque::Plugins::Analytics::PERFORMED) %>
|
10
10
|
<% failed = chart_data(@data, job, Resque::Plugins::Analytics::FAILED) %>
|
11
|
-
<%=
|
12
|
-
data: [performed, failed],
|
13
|
-
title: "Number of jobs",
|
14
|
-
format: "image_tag",
|
15
|
-
size: "1000x300",
|
16
|
-
axis_with_labels: ['x,y'],
|
17
|
-
bar_width_and_spacing: '6',
|
18
|
-
axis_range: [[-90,0,-5], [0, performed.max + failed.max ]],
|
19
|
-
legend: [Resque::Plugins::Analytics::PERFORMED, Resque::Plugins::Analytics::FAILED],
|
20
|
-
legend_position: 'top',
|
21
|
-
bar_colors: ['000000', '0088FF']
|
22
|
-
) %>
|
11
|
+
<%= chart_it("Number of jobs", [Resque::Plugins::Analytics::PERFORMED, Resque::Plugins::Analytics::FAILED], [performed, failed]) %>
|
23
12
|
|
24
13
|
<% run_time = chart_data(@data, job, Resque::Plugins::Analytics::TOTAL_TIME) %>
|
25
|
-
|
26
|
-
|
27
|
-
title: "Run time",
|
28
|
-
format: "image_tag",
|
29
|
-
size: "1000x300",
|
30
|
-
axis_with_labels: ['x,y'],
|
31
|
-
bar_width_and_spacing: '6',
|
32
|
-
axis_range: [[-90,0,-5], [0, run_time.max ]],
|
33
|
-
legend: [Resque::Plugins::Analytics::TOTAL_TIME],
|
34
|
-
legend_position: 'top'
|
35
|
-
) %>
|
36
|
-
|
14
|
+
<% wait_time = chart_data(@data, job, Resque::Plugins::Analytics::WAIT_TIME) %>
|
15
|
+
<%= chart_it("Wait and Run times", [Resque::Plugins::Analytics::WAIT_TIME, Resque::Plugins::Analytics::TOTAL_TIME], [wait_time, run_time]) %>
|
37
16
|
<% end %>
|
@@ -1,13 +1,35 @@
|
|
1
1
|
require 'resque'
|
2
2
|
|
3
3
|
module Resque
|
4
|
+
# Override Resque's push method to add a timestemp to each enqueued item
|
5
|
+
def push(queue, item)
|
6
|
+
item['analytics_timestamp'] = Time.now if item.is_a?(Hash)
|
7
|
+
redis.pipelined do
|
8
|
+
watch_queue(queue)
|
9
|
+
redis.rpush "queue:#{queue}", encode(item)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class Job
|
14
|
+
# Override Job initialization to extract the timestamp
|
15
|
+
def initialize(queue, payload)
|
16
|
+
timestamp = payload.delete('analytics_timestamp')
|
17
|
+
@queue = queue
|
18
|
+
@payload = payload
|
19
|
+
@failure_hooks_ran = false
|
20
|
+
payload_class.send(:analytics_timestamp, timestamp) if payload_class.respond_to?(:analytics_timestamp)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
4
24
|
module Plugins
|
5
25
|
module Analytics
|
6
26
|
|
7
27
|
FAILED = "failed"
|
8
28
|
PERFORMED = "performed"
|
9
29
|
TOTAL_TIME = "total_time"
|
10
|
-
|
30
|
+
WAIT_TIME = "wait_time"
|
31
|
+
|
32
|
+
EXPIRE = 90 * 24 * 60
|
11
33
|
|
12
34
|
def key(kpi)
|
13
35
|
date = Time.now.strftime("%y_%m_%d")
|
@@ -20,19 +42,24 @@ module Resque
|
|
20
42
|
total_time = Time.now - start
|
21
43
|
|
22
44
|
Resque.redis.lpush(key(TOTAL_TIME), total_time)
|
23
|
-
Resque.redis.expire(key(
|
45
|
+
Resque.redis.expire(key(WAIT_TIME), EXPIRE)
|
24
46
|
end
|
25
47
|
|
26
48
|
def after_perform_analytics(*args)
|
27
49
|
Resque.redis.incr(key(PERFORMED))
|
28
|
-
Resque.redis.expire(key(
|
50
|
+
Resque.redis.expire(key(WAIT_TIME), EXPIRE)
|
29
51
|
end
|
30
52
|
|
31
|
-
def on_failure_analytics(
|
53
|
+
def on_failure_analytics(error, *args)
|
32
54
|
Resque.redis.incr(key(FAILED))
|
33
|
-
Resque.redis.expire(key(
|
55
|
+
Resque.redis.expire(key(WAIT_TIME), EXPIRE)
|
56
|
+
end
|
57
|
+
|
58
|
+
def analytics_timestamp(timestamp)
|
59
|
+
Resque.redis.lpush(key(WAIT_TIME), Time.now - Time.parse(timestamp))
|
60
|
+
Resque.redis.expire(key(WAIT_TIME), EXPIRE)
|
34
61
|
end
|
35
62
|
|
36
63
|
end
|
37
64
|
end
|
38
|
-
end
|
65
|
+
end
|
data/resque-analytics.gemspec
CHANGED
@@ -2,16 +2,15 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: resque-analytics 0.
|
5
|
+
# stub: resque-analytics 0.6.0 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "resque-analytics"
|
9
|
-
s.version = "0.
|
9
|
+
s.version = "0.6.0"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
|
-
s.require_paths = ["lib"]
|
13
12
|
s.authors = ["Nir Tzur"]
|
14
|
-
s.date = "2014-06-
|
13
|
+
s.date = "2014-06-09"
|
15
14
|
s.description = "Shows Resque jobs key performance indciators over time"
|
16
15
|
s.email = "nir.tzur@samanage.com"
|
17
16
|
s.extra_rdoc_files = [
|
@@ -20,9 +19,11 @@ Gem::Specification.new do |s|
|
|
20
19
|
]
|
21
20
|
s.files = [
|
22
21
|
".document",
|
22
|
+
"Changelog",
|
23
23
|
"Gemfile",
|
24
24
|
"Gemfile.lock",
|
25
25
|
"LICENSE",
|
26
|
+
"README.rdoc",
|
26
27
|
"Rakefile",
|
27
28
|
"VERSION",
|
28
29
|
"lib/resque-analytics.rb",
|
@@ -33,7 +34,8 @@ Gem::Specification.new do |s|
|
|
33
34
|
]
|
34
35
|
s.homepage = "http://github.com/nirtzur/resque-analytics"
|
35
36
|
s.licenses = ["MIT"]
|
36
|
-
s.
|
37
|
+
s.require_paths = ["lib"]
|
38
|
+
s.rubygems_version = "2.1.11"
|
37
39
|
s.summary = "Resque Job Analytics"
|
38
40
|
|
39
41
|
if s.respond_to? :specification_version then
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: resque-analytics
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nir Tzur
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-06-
|
11
|
+
date: 2014-06-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: resque
|
@@ -89,9 +89,11 @@ extra_rdoc_files:
|
|
89
89
|
- README.rdoc
|
90
90
|
files:
|
91
91
|
- .document
|
92
|
+
- Changelog
|
92
93
|
- Gemfile
|
93
94
|
- Gemfile.lock
|
94
95
|
- LICENSE
|
96
|
+
- README.rdoc
|
95
97
|
- Rakefile
|
96
98
|
- VERSION
|
97
99
|
- lib/resque-analytics.rb
|
@@ -99,7 +101,6 @@ files:
|
|
99
101
|
- lib/resque-analytics/server/views/analytics.erb
|
100
102
|
- lib/resque/plugins/analytics.rb
|
101
103
|
- resque-analytics.gemspec
|
102
|
-
- README.rdoc
|
103
104
|
homepage: http://github.com/nirtzur/resque-analytics
|
104
105
|
licenses:
|
105
106
|
- MIT
|