resque-info 0.0.1 → 0.0.2
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/README.md +51 -1
- data/lib/resque-info/base.rb +37 -29
- data/lib/resque-info/jobs.rb +86 -0
- data/lib/resque-info/version.rb +1 -1
- data/lib/resque-info/workers.rb +30 -0
- data/lib/resque-info.rb +2 -0
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7f9496f78e68ade5273bd71fff8dfe4733f7df3c6917b6b4ed0b576b319ce9d7
|
4
|
+
data.tar.gz: bf2ce5c9484dd4647574fdc7cc91cd473cce6fecf4af1d4bc4e67740c905e465
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c46f6275f22b83a047fd3b7a03f23dd05bebf2d2504e37586716679aa1daf453d14aec487e4c03d01b21c037ea67050764a9132fcef7b8106129c3ee665740c0
|
7
|
+
data.tar.gz: 764a02eb21cdfd148d53d930375de7f14bfedc98ff36f2c32b7563fca604ba5778d770390cea86d1f301faec375b59a22e6fe0120ef517cae533ab3d6542935f
|
data/README.md
CHANGED
@@ -21,8 +21,58 @@ Or install it yourself as:
|
|
21
21
|
Try this snippet of code on ruby irb
|
22
22
|
|
23
23
|
require 'resque-info'
|
24
|
-
puts ResqueInfo.info
|
24
|
+
puts ResqueInfo.info
|
25
25
|
|
26
|
+
puts ResqueInfo.resque_redis
|
27
|
+
puts ResqueInfo.resque_workers
|
28
|
+
puts ResqueInfo.resque_queues
|
29
|
+
puts ResqueInfo.total_jobs
|
30
|
+
# Failed-Jobs
|
31
|
+
puts ResqueInfo.resque_failed_jobs
|
32
|
+
puts ResqueInfo.resque_failed_jobs_count
|
33
|
+
puts ResqueInfo.resque_failed_jobs_count_by_class
|
34
|
+
puts ResqueInfo.resque_failed_jobs_count_by_queue
|
35
|
+
# Processed-Jobs
|
36
|
+
puts ResqueInfo.processed_jobs
|
37
|
+
puts ResqueInfo.processed_jobs_per_minute
|
38
|
+
puts ResqueInfo.processed_jobs_per_hour
|
39
|
+
puts ResqueInfo.processed_jobs_per_day
|
40
|
+
puts ResqueInfo.processed_jobs_per_week
|
41
|
+
puts ResqueInfo.processed_jobs_per_month
|
42
|
+
puts ResqueInfo.processed_jobs_per_year
|
43
|
+
# Redis-Details
|
44
|
+
puts ResqueInfo.redis_info
|
45
|
+
puts ResqueInfo.redis_version
|
46
|
+
puts ResqueInfo.redis_ping
|
47
|
+
puts ResqueInfo.redis_connected?
|
48
|
+
puts ResqueInfo.redis_details
|
49
|
+
puts ResqueInfo.redis_uptime
|
50
|
+
puts ResqueInfo.redis_used_memory
|
51
|
+
puts ResqueInfo.redis_allocator
|
52
|
+
puts ResqueInfo.redis_memory
|
53
|
+
puts ResqueInfo.redis_mem
|
54
|
+
puts ResqueInfo.redis_rdb
|
55
|
+
puts ResqueInfo.redis_aof
|
56
|
+
puts ResqueInfo.redis_total_net
|
57
|
+
puts ResqueInfo.redis_instantaneous
|
58
|
+
puts ResqueInfo.redis_defrag
|
59
|
+
puts ResqueInfo.redis_acl_access_denied
|
60
|
+
puts ResqueInfo.redis_master_repl
|
61
|
+
puts ResqueInfo.redis_used_cpu
|
62
|
+
puts ResqueInfo.redis_other_details
|
63
|
+
# ResqueInfo-Analytis
|
64
|
+
puts ResqueInfo.total_retried_jobs
|
65
|
+
puts ResqueInfo.retry_success_rate
|
66
|
+
puts ResqueInfo.longest_running_jobs(limit = 5)
|
67
|
+
puts ResqueInfo.failed_jobs_by_hour
|
68
|
+
puts ResqueInfo.retry_trends(days = 7)
|
69
|
+
puts ResqueInfo.most_frequent_job_classes(limit = 5)
|
70
|
+
puts ResqueInfo.stuck_jobs(threshold_seconds = 3600)
|
71
|
+
puts ResqueInfo.most_used_queues(limit = 5)
|
72
|
+
puts ResqueInfo.common_job_arguments(limit = 5)
|
73
|
+
puts ResqueInfo.idle_time_per_worker
|
74
|
+
puts ResqueInfo.jobs_processed_per_worker
|
75
|
+
puts ResqueInfo.average_job_time_per_worker
|
26
76
|
|
27
77
|
## Contributing
|
28
78
|
|
data/lib/resque-info/base.rb
CHANGED
@@ -1,41 +1,49 @@
|
|
1
1
|
module ResqueInfo
|
2
|
-
|
2
|
+
class << self
|
3
|
+
def resque_redis
|
4
|
+
Resque.redis
|
5
|
+
end
|
3
6
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
+
def resque_workers
|
8
|
+
Resque.workers
|
9
|
+
end
|
7
10
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
+
def resque_queues
|
12
|
+
Resque.queues
|
13
|
+
end
|
11
14
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
+
def resque_failed_jobs
|
16
|
+
Resque::Failure
|
17
|
+
end
|
15
18
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
19
|
+
def resque_failed_jobs_count
|
20
|
+
resque_failed_jobs.count
|
21
|
+
end
|
22
|
+
|
23
|
+
def resque_failed_jobs_count_by_class
|
24
|
+
klass_name = []
|
25
|
+
(0...resque_failed_jobs_count).step(BATCH_SIZE) do |start|
|
26
|
+
resque_failed_jobs.all(start, BATCH_SIZE).each do |job|
|
27
|
+
next if job.nil?
|
28
|
+
klass_name << job['payload']['class'].to_s
|
29
|
+
rescue StandardError => error
|
30
|
+
logger_rescue('Failed-Job-Count-By-Class', error)
|
31
|
+
end
|
24
32
|
end
|
33
|
+
klass_name.group_by(&:itself).transform_values(&:count)
|
25
34
|
end
|
26
|
-
klass_name.group_by(&:itself).transform_values(&:count)
|
27
|
-
end
|
28
35
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
36
|
+
def resque_failed_jobs_count_by_queue
|
37
|
+
job_queue = []
|
38
|
+
(0...resque_failed_jobs_count).step(BATCH_SIZE) do |start|
|
39
|
+
resque_failed_jobs.all(start, BATCH_SIZE).each do |job|
|
40
|
+
next if job.nil?
|
41
|
+
job_queue << job['queue'].to_s
|
42
|
+
rescue StandardError => error
|
43
|
+
logger_rescue('Failed-Job-Count-By-Queue', error)
|
44
|
+
end
|
37
45
|
end
|
46
|
+
job_queue.group_by(&:itself).transform_values(&:count)
|
38
47
|
end
|
39
|
-
job_queue.group_by(&:itself).transform_values(&:count)
|
40
48
|
end
|
41
49
|
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module ResqueInfo
|
2
|
+
class << self
|
3
|
+
def total_retried_jobs
|
4
|
+
resque_redis.get("resque:stat:retried").to_i
|
5
|
+
end
|
6
|
+
|
7
|
+
def retry_success_rate
|
8
|
+
retried_jobs = total_retried_jobs
|
9
|
+
successful_retries = resque_redis.get("resque:stat:successful_retries").to_i
|
10
|
+
retried_jobs.zero? ? 0 : ((successful_retries.to_f / retried_jobs) * 100).round(2)
|
11
|
+
end
|
12
|
+
|
13
|
+
#### Longest-Running-Jobs
|
14
|
+
#### Identify the jobs that took the most time to process.
|
15
|
+
def longest_running_jobs(limit = 5)
|
16
|
+
resque_redis.zrevrange("resque:stat:longest_jobs", 0, limit - 1).map do |entry|
|
17
|
+
job_data = JSON.parse(entry)
|
18
|
+
{
|
19
|
+
job: job_data['job'],
|
20
|
+
duration: job_data['duration'],
|
21
|
+
completed_at: Time.at(job_data['timestamp'])
|
22
|
+
}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
#### Failed Jobs by Time of Day
|
27
|
+
#### Analyze when most failures occur to identify patterns (e.g., peak failure hours).
|
28
|
+
def failed_jobs_by_hour
|
29
|
+
failed_jobs = resque_failed_jobs.all(0, resque_failed_jobs.count)
|
30
|
+
hourly_data = Array.new(24, 0)
|
31
|
+
|
32
|
+
failed_jobs.each do |job|
|
33
|
+
hour = Time.parse(job['failed_at']).hour
|
34
|
+
hourly_data[hour] += 1
|
35
|
+
end
|
36
|
+
|
37
|
+
hourly_data
|
38
|
+
end
|
39
|
+
|
40
|
+
#### Job-Retry-Trends
|
41
|
+
#### Track retries over time (e.g., daily or weekly).
|
42
|
+
def retry_trends(days = 7)
|
43
|
+
Array.new(days) do |i|
|
44
|
+
date = (Date.today - i).strftime("%Y-%m-%d")
|
45
|
+
retries = resque_redis.get("resque:stat:retries:#{date}").to_i
|
46
|
+
{ date: date, retries: retries }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
#### Most Frequent Job Classes
|
51
|
+
#### Identify the job classes that are enqueued most often.
|
52
|
+
def most_frequent_job_classes(limit = 5)
|
53
|
+
resque_redis.zrevrange("resque:stat:job_classes", 0, limit - 1, with_scores: true).map do |job_class, count|
|
54
|
+
{ job_class: job_class, count: count.to_i }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
#### Jobs Stuck in Queues
|
59
|
+
#### Identify jobs stuck in queues for an unusually long time.
|
60
|
+
def stuck_jobs(threshold_seconds = 3600)
|
61
|
+
resque_queues.each_with_object([]) do |queue, result|
|
62
|
+
Resque.peek(queue, 0, Resque.size(queue)).each do |job|
|
63
|
+
enqueued_time = job['enqueued_at'] || Time.now.to_i
|
64
|
+
wait_time = Time.now.to_i - enqueued_time
|
65
|
+
result << { job: job, queue: queue, wait_time: wait_time } if wait_time > threshold_seconds
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
#### Most Used Queues
|
71
|
+
#### Track queues that are used most frequently.
|
72
|
+
def most_used_queues(limit = 5)
|
73
|
+
resque_queues.map { |queue| { queue: queue, size: Resque.size(queue) } }
|
74
|
+
.sort_by { |q| -q[:size] }
|
75
|
+
.first(limit)
|
76
|
+
end
|
77
|
+
|
78
|
+
#### Job Arguments Analysis
|
79
|
+
#### Common arguments passed to jobs, useful for debugging recurring failures.
|
80
|
+
def common_job_arguments(limit = 5)
|
81
|
+
resque_redis.zrevrange("resque:stat:job_arguments", 0, limit - 1, with_scores: true).map do |args, count|
|
82
|
+
{ arguments: JSON.parse(args), count: count.to_i }
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
data/lib/resque-info/version.rb
CHANGED
@@ -0,0 +1,30 @@
|
|
1
|
+
module ResqueInfo
|
2
|
+
class << self
|
3
|
+
#### Idle Time Metrics
|
4
|
+
#### Measure how long a worker or queue has been idle.
|
5
|
+
def idle_time_per_worker
|
6
|
+
resque_workers.each_with_object({}) do |worker, result|
|
7
|
+
last_job_time = resque_redis.get("worker:#{worker.id}:last_job_time").to_i
|
8
|
+
idle_time = Time.now.to_i - last_job_time
|
9
|
+
result[worker.id] = idle_time
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
#### Jobs processed per worker.
|
14
|
+
def jobs_processed_per_worker
|
15
|
+
resque_workers.each_with_object({}) do |worker, result|
|
16
|
+
jobs = resque_redis.get("worker:#{worker.id}:jobs_processed").to_i
|
17
|
+
result[worker.id] = jobs
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
#### Average job completion time per worker.
|
22
|
+
def average_job_time_per_worker
|
23
|
+
resque_workers.each_with_object({}) do |worker, result|
|
24
|
+
total_time = resque_redis.get("worker:#{worker.id}:total_time").to_f
|
25
|
+
jobs = resque_redis.get("worker:#{worker.id}:jobs_processed").to_i
|
26
|
+
result[worker.id] = jobs.zero? ? 0 : (total_time / jobs).round(2)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/resque-info.rb
CHANGED
@@ -4,6 +4,8 @@ require_relative './resque-info/common.rb'
|
|
4
4
|
require_relative './resque-info/base.rb'
|
5
5
|
require_relative './resque-info/queues.rb'
|
6
6
|
require_relative './resque-info/redis.rb'
|
7
|
+
require_relative './resque-info/jobs.rb'
|
8
|
+
require_relative './resque-info/workers.rb'
|
7
9
|
|
8
10
|
require 'time'
|
9
11
|
require 'digest'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: resque-info
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rahul Patil
|
@@ -52,9 +52,11 @@ files:
|
|
52
52
|
- lib/resque-info/base.rb
|
53
53
|
- lib/resque-info/common.rb
|
54
54
|
- lib/resque-info/constants.rb
|
55
|
+
- lib/resque-info/jobs.rb
|
55
56
|
- lib/resque-info/queues.rb
|
56
57
|
- lib/resque-info/redis.rb
|
57
58
|
- lib/resque-info/version.rb
|
59
|
+
- lib/resque-info/workers.rb
|
58
60
|
homepage: https://github.com/rpatil/resque-info
|
59
61
|
licenses:
|
60
62
|
- MIT
|