sidekiq_monitor 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.md +180 -0
  3. data/Rakefile +12 -0
  4. data/app/assets/javascripts/sidekiq/monitor/abstract_jobs_table.js.coffee +165 -0
  5. data/app/assets/javascripts/sidekiq/monitor/application.js.coffee +11 -0
  6. data/app/assets/javascripts/sidekiq/monitor/bootstrap-select.min.js +1 -0
  7. data/app/assets/javascripts/sidekiq/monitor/bootstrap.min.js +6 -0
  8. data/app/assets/javascripts/sidekiq/monitor/datatables.bootstrap.js +96 -0
  9. data/app/assets/javascripts/sidekiq/monitor/datatables.js +256 -0
  10. data/app/assets/javascripts/sidekiq/monitor/datatables.standing_redraw.js.coffee +5 -0
  11. data/app/assets/javascripts/sidekiq/monitor/initialize.js.coffee.erb +5 -0
  12. data/app/assets/javascripts/sidekiq/monitor/jobs_table.js.coffee +59 -0
  13. data/app/assets/javascripts/sidekiq/monitor/jquery.timeago.js +27 -0
  14. data/app/assets/javascripts/sidekiq/monitor/queue_jobs_table.js.coffee +92 -0
  15. data/app/assets/stylesheets/sidekiq/monitor/application.css.sass +5 -0
  16. data/app/assets/stylesheets/sidekiq/monitor/bootstrap-select.min.css +1 -0
  17. data/app/assets/stylesheets/sidekiq/monitor/bootstrap.min.css +9 -0
  18. data/app/assets/stylesheets/sidekiq/monitor/jobs_table.css.sass +51 -0
  19. data/app/assets/stylesheets/sidekiq/monitor/layout.css.sass +15 -0
  20. data/app/controllers/sidekiq/monitor/api/jobs_controller.rb +32 -0
  21. data/app/controllers/sidekiq/monitor/api/queues_controller.rb +24 -0
  22. data/app/controllers/sidekiq/monitor/jobs_controller.rb +14 -0
  23. data/app/controllers/sidekiq/monitor/queues_controller.rb +15 -0
  24. data/app/datatables/sidekiq/monitor/jobs_datatable.rb +74 -0
  25. data/app/helpers/sidekiq/monitor/sidekiq_helper.rb +13 -0
  26. data/app/models/sidekiq/monitor/job.rb +37 -0
  27. data/app/views/sidekiq/monitor/jobs/_jobs.slim +13 -0
  28. data/app/views/sidekiq/monitor/jobs/index.slim +1 -0
  29. data/app/views/sidekiq/monitor/layouts/application.slim +28 -0
  30. data/app/views/sidekiq/monitor/queues/_jobs.slim +13 -0
  31. data/app/views/sidekiq/monitor/queues/index.slim +6 -0
  32. data/config/routes.rb +10 -0
  33. data/lib/generators/sidekiq/monitor/install/install_generator.rb +27 -0
  34. data/lib/generators/sidekiq/monitor/install/templates/create_sidekiq_jobs.rb +26 -0
  35. data/lib/sidekiq/monitor/cleaner.rb +58 -0
  36. data/lib/sidekiq/monitor/client/middleware.rb +16 -0
  37. data/lib/sidekiq/monitor/engine.rb +11 -0
  38. data/lib/sidekiq/monitor/processor.rb +73 -0
  39. data/lib/sidekiq/monitor/server/middleware.rb +22 -0
  40. data/lib/sidekiq/monitor/version.rb +5 -0
  41. data/lib/sidekiq/monitor.rb +26 -0
  42. data/lib/sidekiq_monitor.rb +1 -0
  43. metadata +135 -0
@@ -0,0 +1,27 @@
1
+ require 'rails/generators'
2
+ require 'rails/generators/base'
3
+
4
+ module Sidekiq
5
+ module Monitor
6
+ module Generators
7
+ class InstallGenerator < ::Rails::Generators::Base
8
+ include ::Rails::Generators::Migration
9
+ source_root File.expand_path('../templates', __FILE__)
10
+ desc "Install the migrations"
11
+
12
+ def self.next_migration_number(path)
13
+ unless @prev_migration_nr
14
+ @prev_migration_nr = Time.now.utc.strftime("%Y%m%d%H%M%S").to_i
15
+ else
16
+ @prev_migration_nr += 1
17
+ end
18
+ @prev_migration_nr.to_s
19
+ end
20
+
21
+ def install_migrations
22
+ migration_template "create_sidekiq_jobs.rb", "db/migrate/create_sidekiq_jobs.rb"
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,26 @@
1
+ class CreateSidekiqJobs < ActiveRecord::Migration
2
+ def change
3
+ create_table :sidekiq_jobs do |t|
4
+ t.string :jid
5
+ t.string :queue
6
+ t.string :class_name
7
+ t.text :args
8
+ t.boolean :retry
9
+ t.datetime :enqueued_at
10
+ t.datetime :started_at
11
+ t.datetime :finished_at
12
+ t.string :status
13
+ t.string :name
14
+ t.text :result
15
+ end
16
+
17
+ add_index :sidekiq_jobs, :jid
18
+ add_index :sidekiq_jobs, :queue
19
+ add_index :sidekiq_jobs, :retry
20
+ add_index :sidekiq_jobs, :class_name
21
+ add_index :sidekiq_jobs, :enqueued_at
22
+ add_index :sidekiq_jobs, :started_at
23
+ add_index :sidekiq_jobs, :finished_at
24
+ add_index :sidekiq_jobs, :status
25
+ end
26
+ end
@@ -0,0 +1,58 @@
1
+ module Sidekiq
2
+ module Monitor
3
+ class Cleaner
4
+ # Cleans up records that are no longer in sync with Sidekiq's records
5
+ def clean
6
+ clean_queued
7
+ clean_running
8
+ end
9
+
10
+ private
11
+
12
+ def clean_queued
13
+ Sidekiq.redis do |conn|
14
+ queues = conn.smembers('queues')
15
+ queued_jids = []
16
+ queues.each do |queue|
17
+ workers = conn.lrange("queue:#{queue}", 0, -1)
18
+ workers.each do |worker|
19
+ worker = Sidekiq.load_json(worker)
20
+ queued_jids << worker['jid']
21
+ end
22
+ end
23
+
24
+ Sidekiq::Monitor::Job.where(status: 'queued').each do |job|
25
+ unless queued_jids.include?(job.jid)
26
+ job.update_attributes(
27
+ finished_at: DateTime.now,
28
+ status: 'interrupted'
29
+ )
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ def clean_running
36
+ Sidekiq.redis do |conn|
37
+ workers = conn.smembers('workers')
38
+ busy_jids = []
39
+ workers.each do |worker|
40
+ worker = conn.get("worker:#{worker}")
41
+ next if worker.blank?
42
+ worker = Sidekiq.load_json(worker)
43
+ busy_jids << worker['payload']['jid']
44
+ end
45
+
46
+ Sidekiq::Monitor::Job.where(status: 'running').each do |job|
47
+ unless busy_jids.include?(job.jid)
48
+ job.update_attributes(
49
+ finished_at: DateTime.now,
50
+ status: 'interrupted'
51
+ )
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,16 @@
1
+ module Sidekiq
2
+ module Monitor
3
+ module Client
4
+ class Middleware
5
+ def initialize(options=nil)
6
+ @processor = Monitor::Processor.new
7
+ end
8
+
9
+ def call(worker_class, item, queue)
10
+ @processor.queue(worker_class, item, queue)
11
+ yield
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,11 @@
1
+ module Sidekiq
2
+ module Monitor
3
+ class Engine < ::Rails::Engine
4
+ isolate_namespace Monitor
5
+
6
+ initializer "sidekiq_monitor.asset_pipeline" do |app|
7
+ app.config.assets.precompile << 'sidekiq/monitor/application.js'
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,73 @@
1
+ module Sidekiq
2
+ module Monitor
3
+ class Processor
4
+ def queue(worker_class, item, queue)
5
+ args = item['args']
6
+ name = job_name(worker_class, args)
7
+ Sidekiq::Monitor::Job.find_or_create_by_jid(
8
+ jid: item['jid'],
9
+ queue: queue,
10
+ class_name: worker_class.name,
11
+ args: args,
12
+ retry: item['retry'],
13
+ enqueued_at: DateTime.now,
14
+ status: 'queued',
15
+ name: name
16
+ )
17
+ end
18
+
19
+ def start(worker, msg, queue)
20
+ jid = msg['jid']
21
+ args = msg['args']
22
+ job = Sidekiq::Monitor::Job.find_by_jid(jid)
23
+ if job.blank?
24
+ name = job_name(worker.class, args)
25
+ job = Sidekiq::Monitor::Job.new(
26
+ jid: jid,
27
+ queue: queue,
28
+ class_name: worker.class.name,
29
+ args: args,
30
+ retry: msg['retry'],
31
+ name: name
32
+ )
33
+ end
34
+ job.update_attributes(
35
+ started_at: DateTime.now,
36
+ status: 'running'
37
+ )
38
+ end
39
+
40
+ def error(worker, msg, queue, exception)
41
+ result = {
42
+ message: exception.message,
43
+ backtrace: exception.backtrace
44
+ }
45
+ job = find_job(msg)
46
+ job.update_attributes(
47
+ finished_at: DateTime.now,
48
+ status: 'failed',
49
+ result: result
50
+ )
51
+ end
52
+
53
+ def complete(worker, msg, queue, return_value)
54
+ job = find_job(msg)
55
+ job.update_attributes(
56
+ finished_at: DateTime.now,
57
+ status: 'complete',
58
+ result: (return_value if return_value.is_a?(Hash))
59
+ )
60
+ end
61
+
62
+ protected
63
+
64
+ def find_job(msg)
65
+ Sidekiq::Monitor::Job.find_by_jid(msg['jid'])
66
+ end
67
+
68
+ def job_name(worker_class, args)
69
+ worker_class.respond_to?(:job_name) ? worker_class.job_name(*args) : nil
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,22 @@
1
+ module Sidekiq
2
+ module Monitor
3
+ module Server
4
+ class Middleware
5
+ def initialize(options=nil)
6
+ @processor = Monitor::Processor.new
7
+ end
8
+
9
+ def call(worker, msg, queue)
10
+ @processor.start(worker, msg, queue)
11
+ begin
12
+ return_value = yield
13
+ rescue Exception => exception
14
+ @processor.error(worker, msg, queue, exception)
15
+ return
16
+ end
17
+ @processor.complete(worker, msg, queue, return_value)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,5 @@
1
+ module Sidekiq
2
+ module Monitor
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,26 @@
1
+ require 'slim'
2
+
3
+ directory = File.dirname(File.absolute_path(__FILE__))
4
+ Dir.glob("#{directory}/monitor/**/*.rb") { |file| require file }
5
+
6
+ module Sidekiq
7
+ module Monitor
8
+ def self.table_name_prefix
9
+ 'sidekiq_'
10
+ end
11
+ end
12
+ end
13
+
14
+ Sidekiq.configure_client do |config|
15
+ config.client_middleware do |chain|
16
+ chain.add Sidekiq::Monitor::Client::Middleware
17
+ end
18
+ end
19
+ Sidekiq.configure_server do |config|
20
+ config.client_middleware do |chain|
21
+ chain.add Sidekiq::Monitor::Client::Middleware
22
+ end
23
+ config.server_middleware do |chain|
24
+ chain.add Sidekiq::Monitor::Server::Middleware
25
+ end
26
+ end
@@ -0,0 +1 @@
1
+ require "sidekiq/monitor"
metadata ADDED
@@ -0,0 +1,135 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sidekiq_monitor
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Tom Benner
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-06-04 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: sidekiq
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 2.2.1
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 2.2.1
30
+ - !ruby/object:Gem::Dependency
31
+ name: slim
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: ajax-datatables-rails
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: Advanced monitoring for Sidekiq
63
+ email:
64
+ - tombenner@gmail.com
65
+ executables: []
66
+ extensions: []
67
+ extra_rdoc_files: []
68
+ files:
69
+ - app/assets/javascripts/sidekiq/monitor/abstract_jobs_table.js.coffee
70
+ - app/assets/javascripts/sidekiq/monitor/application.js.coffee
71
+ - app/assets/javascripts/sidekiq/monitor/bootstrap-select.min.js
72
+ - app/assets/javascripts/sidekiq/monitor/bootstrap.min.js
73
+ - app/assets/javascripts/sidekiq/monitor/datatables.bootstrap.js
74
+ - app/assets/javascripts/sidekiq/monitor/datatables.js
75
+ - app/assets/javascripts/sidekiq/monitor/datatables.standing_redraw.js.coffee
76
+ - app/assets/javascripts/sidekiq/monitor/initialize.js.coffee.erb
77
+ - app/assets/javascripts/sidekiq/monitor/jobs_table.js.coffee
78
+ - app/assets/javascripts/sidekiq/monitor/jquery.timeago.js
79
+ - app/assets/javascripts/sidekiq/monitor/queue_jobs_table.js.coffee
80
+ - app/assets/stylesheets/sidekiq/monitor/application.css.sass
81
+ - app/assets/stylesheets/sidekiq/monitor/bootstrap-select.min.css
82
+ - app/assets/stylesheets/sidekiq/monitor/bootstrap.min.css
83
+ - app/assets/stylesheets/sidekiq/monitor/jobs_table.css.sass
84
+ - app/assets/stylesheets/sidekiq/monitor/layout.css.sass
85
+ - app/controllers/sidekiq/monitor/api/jobs_controller.rb
86
+ - app/controllers/sidekiq/monitor/api/queues_controller.rb
87
+ - app/controllers/sidekiq/monitor/jobs_controller.rb
88
+ - app/controllers/sidekiq/monitor/queues_controller.rb
89
+ - app/datatables/sidekiq/monitor/jobs_datatable.rb
90
+ - app/helpers/sidekiq/monitor/sidekiq_helper.rb
91
+ - app/models/sidekiq/monitor/job.rb
92
+ - app/views/sidekiq/monitor/jobs/_jobs.slim
93
+ - app/views/sidekiq/monitor/jobs/index.slim
94
+ - app/views/sidekiq/monitor/layouts/application.slim
95
+ - app/views/sidekiq/monitor/queues/_jobs.slim
96
+ - app/views/sidekiq/monitor/queues/index.slim
97
+ - config/routes.rb
98
+ - lib/generators/sidekiq/monitor/install/install_generator.rb
99
+ - lib/generators/sidekiq/monitor/install/templates/create_sidekiq_jobs.rb
100
+ - lib/sidekiq/monitor/cleaner.rb
101
+ - lib/sidekiq/monitor/client/middleware.rb
102
+ - lib/sidekiq/monitor/engine.rb
103
+ - lib/sidekiq/monitor/processor.rb
104
+ - lib/sidekiq/monitor/server/middleware.rb
105
+ - lib/sidekiq/monitor/version.rb
106
+ - lib/sidekiq/monitor.rb
107
+ - lib/sidekiq_monitor.rb
108
+ - MIT-LICENSE
109
+ - Rakefile
110
+ - README.md
111
+ homepage: https://github.com/socialpandas/sidekiq_monitor
112
+ licenses: []
113
+ post_install_message:
114
+ rdoc_options: []
115
+ require_paths:
116
+ - lib
117
+ required_ruby_version: !ruby/object:Gem::Requirement
118
+ none: false
119
+ requirements:
120
+ - - ! '>='
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
123
+ required_rubygems_version: !ruby/object:Gem::Requirement
124
+ none: false
125
+ requirements:
126
+ - - ! '>='
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ requirements: []
130
+ rubyforge_project:
131
+ rubygems_version: 1.8.24
132
+ signing_key:
133
+ specification_version: 3
134
+ summary: Advanced monitoring for Sidekiq
135
+ test_files: []