resque-analytics 0.5.0 → 0.6.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 +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
|