sidekiq-spy 0.1.0 → 0.2.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/.travis.yml +1 -3
- data/CHANGELOG.md +27 -0
- data/README.md +17 -12
- data/lib/sidekiq-spy.rb +6 -0
- data/lib/sidekiq-spy/app.rb +49 -12
- data/lib/sidekiq-spy/display/panel.rb +10 -1
- data/lib/sidekiq-spy/display/panels/header.rb +25 -0
- data/lib/sidekiq-spy/display/panels/redis_stats.rb +37 -0
- data/lib/sidekiq-spy/display/panels/sidekiq_stats.rb +33 -0
- data/lib/sidekiq-spy/display/panels/workers.rb +50 -0
- data/lib/sidekiq-spy/display/screen.rb +12 -47
- data/lib/sidekiq-spy/display/subpanel.rb +15 -7
- data/lib/sidekiq-spy/spy/stats.rb +1 -1
- data/lib/sidekiq-spy/spy/workers.rb +35 -0
- data/lib/sidekiq-spy/translatable.rb +7 -4
- data/lib/sidekiq-spy/version.rb +1 -1
- data/sidekiq-spy.gemspec +1 -2
- data/test/helper.rb +1 -5
- data/test/sidekiq-spy/app_test.rb +149 -3
- data/test/sidekiq-spy/config_test.rb +0 -92
- data/test/sidekiq-spy/display/panel_test.rb +161 -0
- data/test/sidekiq-spy/display/screen_test.rb +98 -0
- data/test/sidekiq-spy/display/subpanel_test.rb +186 -0
- data/test/sidekiq-spy/spy/stats_test.rb +23 -36
- data/test/sidekiq-spy/spy/workers_test.rb +81 -0
- data/test/sidekiq-spy/translatable_test.rb +18 -0
- metadata +24 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 91574e1eabbcadaf02cc6fe5e70e3031e7022b33
|
4
|
+
data.tar.gz: da4ab6eb49ee18c42665a627abc08df7529e4972
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 49c09665f4349ada057861bb8d9f02dbd2a473ea33ad4fc0843613d03429228fc707b1dae3fb5a5c092d7a9725c5b9e6d4a55a17698a99cf98dc9573c7e2c36a
|
7
|
+
data.tar.gz: 0b80737bf8f199ff2be3daa6e41746438ee55033d23926c106f9228fdad43a58476bcf4020c4eb41206a564a84197c9a6660e38a2639f2821b94a35aa0565736
|
data/.travis.yml
CHANGED
@@ -1,16 +1,14 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
+
- 2.0.0
|
3
4
|
- 1.9.3
|
4
5
|
- jruby-19mode
|
5
6
|
- rbx-19mode
|
6
|
-
- 2.0.0
|
7
7
|
notifications:
|
8
8
|
email:
|
9
9
|
recipients:
|
10
10
|
- tp@tiredpixel.com
|
11
|
-
- sidekiq.spy@librelist.com
|
12
11
|
matrix:
|
13
12
|
allow_failures:
|
14
|
-
- rvm: 1.9.3
|
15
13
|
- rvm: jruby-19mode
|
16
14
|
- rvm: rbx-19mode
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# Sidekiq Spy Changelog
|
2
|
+
|
3
|
+
This changelog documents the main changes between released versions.
|
4
|
+
For a full list of changes, consult the commit history.
|
5
|
+
For many of commits by [tiredpixel](http://www.tiredpixel.com), the commit
|
6
|
+
message provides information and examples.
|
7
|
+
|
8
|
+
|
9
|
+
## 0.1.0
|
10
|
+
|
11
|
+
- first release
|
12
|
+
- `sidekiq-spy` executable providing: `--url`, `--host`, `--port`, `--database`,
|
13
|
+
`--namespace`, `--interval`, `--help`, `--version`
|
14
|
+
- core Redis statistics: redis, namespace, redis version, uptime (d),
|
15
|
+
connections, memory, memory peak
|
16
|
+
- core Sidekiq statistics: busy, retries, processed, enqueued, scheduled, failed
|
17
|
+
|
18
|
+
|
19
|
+
## 0.2.0
|
20
|
+
|
21
|
+
- test fixes for Ruby 1.9.3, which is supported along with Ruby 2.0.0
|
22
|
+
- a plethora of tests; most of the core is now covered
|
23
|
+
- command-loop to handle key presses
|
24
|
+
- `<q>` for quit (in addition to existing `<ctrl>+<c>`)
|
25
|
+
- smaller sleep increments for faster exit
|
26
|
+
- content overrun fix
|
27
|
+
- workers panel (like `Sidekiq::Web` Workers tab), reporting who is up to what
|
data/README.md
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
# Sidekiq Spy
|
2
2
|
|
3
3
|
[](http://badge.fury.io/rb/sidekiq-spy)
|
4
|
-
[](https://travis-ci.org/tiredpixel/sidekiq-spy)
|
5
5
|
[](https://codeclimate.com/github/tiredpixel/sidekiq-spy)
|
6
|
-
[](https://coveralls.io/r/tiredpixel/sidekiq-spy)
|
7
6
|
|
8
7
|
[Sidekiq](https://github.com/mperham/sidekiq) monitoring in the console.
|
9
8
|
A bit like Sidekiq::Web. But without the web.
|
@@ -13,8 +12,9 @@ see how your workers are doing at-a-glance when SSHed into a remote box with
|
|
13
12
|
no web server, this one's for you. <3
|
14
13
|
|
15
14
|
This project is so hot out of the oven you might need mitts. But it's already
|
16
|
-
functional, with the main statistics from the Sidekiq::Web homepage
|
17
|
-
it would be nice to add the
|
15
|
+
functional, with the main statistics from the Sidekiq::Web homepage and the
|
16
|
+
Workers tab. In time, it would be nice to add the Queues, Retries, and
|
17
|
+
Scheduled tabs, too.
|
18
18
|
|
19
19
|
More sleep lost by [tiredpixel](http://www.tiredpixel.com).
|
20
20
|
|
@@ -50,18 +50,25 @@ We won't tell anyone! ;) (Resque is awesome, too!)
|
|
50
50
|
|
51
51
|
$ sidekiq-spy -n resque
|
52
52
|
|
53
|
-
That's about it.
|
53
|
+
To quit, press `<q>` or `<ctrl>+<c>`. That's about it.
|
54
54
|
|
55
55
|
|
56
56
|
## ASCII Art (a.k.a. Screenshot)
|
57
57
|
|
58
|
-
Sidekiq Spy 0.0
|
58
|
+
Sidekiq Spy 0.2.0 16:17:23 +0000
|
59
59
|
redis: 127.0.0.1:6379/0|namespace:
|
60
|
-
redis version: 2.6.11|uptime (d):
|
61
|
-
memory: 4.
|
60
|
+
redis version: 2.6.11|uptime (d): 2|connections: 5
|
61
|
+
memory: 4.89M|memory peak: 5.03M|
|
62
62
|
|
63
|
-
busy:
|
64
|
-
enqueued: 0|scheduled: 0|failed:
|
63
|
+
busy: 5|retries: 15|processed: 1623
|
64
|
+
enqueued: 0|scheduled: 0|failed: 1535
|
65
|
+
|
66
|
+
WORKER QUEUE CLASS ARGUMENTS STARTED
|
67
|
+
sep.da.local:17045-70130396 default MakeSEPFields [2670] 2013-11-03
|
68
|
+
sep.da.local:17045-70130397 default MakeSEPFields [2668] 2013-11-03
|
69
|
+
sep.da.local:17045-70130396 default MakeSEPFields [2669] 2013-11-03
|
70
|
+
sep.da.local:17045-70130397 default MakeSEPFields [2667] 2013-11-03
|
71
|
+
sep.da.local:17045-70130396 default MakeSEPFields [2671] 2013-11-03
|
65
72
|
|
66
73
|
|
67
74
|
## Stay Tuned
|
@@ -77,8 +84,6 @@ That was easy.
|
|
77
84
|
|
78
85
|
Dear Me, Here is a vague wishlist:
|
79
86
|
|
80
|
-
- more tests for the display parts
|
81
|
-
- Workers table on main page
|
82
87
|
- Queues page
|
83
88
|
- Retries page
|
84
89
|
- Scheduled page
|
data/lib/sidekiq-spy.rb
CHANGED
@@ -5,7 +5,13 @@ require File.expand_path('../sidekiq-spy/translatable', __FILE__)
|
|
5
5
|
require File.expand_path('../sidekiq-spy/app', __FILE__)
|
6
6
|
|
7
7
|
require File.expand_path('../sidekiq-spy/spy/stats', __FILE__)
|
8
|
+
require File.expand_path('../sidekiq-spy/spy/workers', __FILE__)
|
8
9
|
|
9
10
|
require File.expand_path('../sidekiq-spy/display/screen', __FILE__)
|
10
11
|
require File.expand_path('../sidekiq-spy/display/panel', __FILE__)
|
11
12
|
require File.expand_path('../sidekiq-spy/display/subpanel', __FILE__)
|
13
|
+
|
14
|
+
require File.expand_path('../sidekiq-spy/display/panels/header', __FILE__)
|
15
|
+
require File.expand_path('../sidekiq-spy/display/panels/redis_stats', __FILE__)
|
16
|
+
require File.expand_path('../sidekiq-spy/display/panels/sidekiq_stats', __FILE__)
|
17
|
+
require File.expand_path('../sidekiq-spy/display/panels/workers', __FILE__)
|
data/lib/sidekiq-spy/app.rb
CHANGED
@@ -1,13 +1,17 @@
|
|
1
|
+
require 'thread'
|
1
2
|
require 'sidekiq'
|
2
3
|
|
3
4
|
|
4
5
|
module SidekiqSpy
|
5
6
|
class App
|
6
7
|
|
8
|
+
REFRESH_SUBINTERVAL = 0.1
|
9
|
+
|
7
10
|
attr_reader :running
|
8
11
|
|
9
12
|
def initialize
|
10
|
-
@running
|
13
|
+
@running = false
|
14
|
+
@threads = {}
|
11
15
|
end
|
12
16
|
|
13
17
|
def config
|
@@ -26,17 +30,15 @@ module SidekiqSpy
|
|
26
30
|
|
27
31
|
setup
|
28
32
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
sleep 1
|
36
|
-
|
37
|
-
@sleep_timer -= 1
|
38
|
-
end
|
33
|
+
@threads[:command] ||= Thread.new do
|
34
|
+
command_loop # listen for commands
|
35
|
+
end
|
36
|
+
|
37
|
+
@threads[:refresh] ||= Thread.new do
|
38
|
+
refresh_loop # refresh frequently
|
39
39
|
end
|
40
|
+
|
41
|
+
@threads.each { |tname, t| t.join }
|
40
42
|
ensure
|
41
43
|
cleanup
|
42
44
|
end
|
@@ -46,6 +48,13 @@ module SidekiqSpy
|
|
46
48
|
@running = false
|
47
49
|
end
|
48
50
|
|
51
|
+
def do_command(key)
|
52
|
+
case key
|
53
|
+
when 'q' # quit
|
54
|
+
@running = false
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
49
58
|
private
|
50
59
|
|
51
60
|
def configure_sidekiq
|
@@ -58,12 +67,40 @@ module SidekiqSpy
|
|
58
67
|
end
|
59
68
|
end
|
60
69
|
|
70
|
+
def command_loop
|
71
|
+
while @running do
|
72
|
+
key = next_key
|
73
|
+
|
74
|
+
next unless key # keep listening if timeout
|
75
|
+
|
76
|
+
do_command(key)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def refresh_loop
|
81
|
+
while @running do
|
82
|
+
refresh
|
83
|
+
|
84
|
+
@sleep_timer = config.interval
|
85
|
+
|
86
|
+
while @running && @sleep_timer > 0
|
87
|
+
sleep REFRESH_SUBINTERVAL
|
88
|
+
|
89
|
+
@sleep_timer -= REFRESH_SUBINTERVAL
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
61
94
|
def setup
|
62
95
|
@screen = Display::Screen.new
|
63
96
|
end
|
64
97
|
|
65
98
|
def refresh
|
66
|
-
@screen.refresh
|
99
|
+
@screen.refresh if @screen
|
100
|
+
end
|
101
|
+
|
102
|
+
def next_key
|
103
|
+
@screen.next_key if @screen
|
67
104
|
end
|
68
105
|
|
69
106
|
def cleanup
|
@@ -5,7 +5,16 @@ module SidekiqSpy
|
|
5
5
|
module Display
|
6
6
|
class Panel
|
7
7
|
|
8
|
-
|
8
|
+
include Translatable
|
9
|
+
|
10
|
+
attr_reader :height
|
11
|
+
attr_reader :width
|
12
|
+
attr_reader :top
|
13
|
+
attr_reader :left
|
14
|
+
attr_reader :dividers
|
15
|
+
attr_reader :divider_length
|
16
|
+
|
17
|
+
def initialize(height, width, top, left, structure = [], opts = {})
|
9
18
|
@height = height
|
10
19
|
@width = width
|
11
20
|
@top = top
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module SidekiqSpy
|
2
|
+
module Display
|
3
|
+
module Panels
|
4
|
+
class Header < Display::Panel
|
5
|
+
|
6
|
+
def initialize(height, width, top, left)
|
7
|
+
super(height, width, top, left, structure)
|
8
|
+
end
|
9
|
+
|
10
|
+
def structure
|
11
|
+
# [
|
12
|
+
# [relative_column_width, data_left, data_right]
|
13
|
+
# ]
|
14
|
+
[
|
15
|
+
[
|
16
|
+
[1, t[:program], nil],
|
17
|
+
[1, nil, -> { Time.now.strftime("%T %z") }],
|
18
|
+
],
|
19
|
+
]
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module SidekiqSpy
|
2
|
+
module Display
|
3
|
+
module Panels
|
4
|
+
class RedisStats < Display::Panel
|
5
|
+
|
6
|
+
def initialize(height, width, top, left)
|
7
|
+
super(height, width, top, left, structure, :divider_r => "|")
|
8
|
+
end
|
9
|
+
|
10
|
+
def structure
|
11
|
+
stats = Spy::Stats.new
|
12
|
+
|
13
|
+
# [
|
14
|
+
# [relative_column_width, data_left, data_right]
|
15
|
+
# ]
|
16
|
+
[
|
17
|
+
[
|
18
|
+
[2, t[:redis][:connection], -> { stats.connection }],
|
19
|
+
[1, t[:redis][:namespace], -> { stats.namespace }],
|
20
|
+
],
|
21
|
+
[
|
22
|
+
[1, t[:redis][:version], -> { stats.redis_version }],
|
23
|
+
[1, t[:redis][:uptime], -> { stats.uptime }],
|
24
|
+
[1, t[:redis][:connections], -> { stats.connections }],
|
25
|
+
],
|
26
|
+
[
|
27
|
+
[1, t[:redis][:memory], -> { stats.memory }],
|
28
|
+
[1, t[:redis][:memory_peak], -> { stats.memory_peak }],
|
29
|
+
[1, nil, nil],
|
30
|
+
],
|
31
|
+
]
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module SidekiqSpy
|
2
|
+
module Display
|
3
|
+
module Panels
|
4
|
+
class SidekiqStats < Display::Panel
|
5
|
+
|
6
|
+
def initialize(height, width, top, left)
|
7
|
+
super(height, width, top, left, structure, :divider_r => "|")
|
8
|
+
end
|
9
|
+
|
10
|
+
def structure
|
11
|
+
stats = Spy::Stats.new
|
12
|
+
|
13
|
+
# [
|
14
|
+
# [relative_column_width, data_left, data_right]
|
15
|
+
# ]
|
16
|
+
[
|
17
|
+
[
|
18
|
+
[1, t[:sidekiq][:busy], -> { stats.busy }],
|
19
|
+
[1, t[:sidekiq][:retries], -> { stats.retries }],
|
20
|
+
[1, t[:sidekiq][:processed], -> { stats.processed }],
|
21
|
+
],
|
22
|
+
[
|
23
|
+
[1, t[:sidekiq][:enqueued], -> { stats.enqueued }],
|
24
|
+
[1, t[:sidekiq][:scheduled], -> { stats.scheduled }],
|
25
|
+
[1, t[:sidekiq][:failed], -> { stats.failed }],
|
26
|
+
],
|
27
|
+
]
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module SidekiqSpy
|
2
|
+
module Display
|
3
|
+
module Panels
|
4
|
+
class Workers < Display::Panel
|
5
|
+
|
6
|
+
def initialize(height, width, top, left)
|
7
|
+
@height = height # #structure needs this before #initialize ends
|
8
|
+
|
9
|
+
super(height, width, top, left, structure, :divider_r => " ")
|
10
|
+
end
|
11
|
+
|
12
|
+
def refresh
|
13
|
+
@workers.refresh # refresh data feed
|
14
|
+
|
15
|
+
super
|
16
|
+
end
|
17
|
+
|
18
|
+
def structure
|
19
|
+
@workers = Spy::Workers.new
|
20
|
+
|
21
|
+
# [
|
22
|
+
# [relative_column_width, data_left, data_right]
|
23
|
+
# ]
|
24
|
+
s = [
|
25
|
+
[ # table header slots
|
26
|
+
[2, t[:heading][:worker], nil],
|
27
|
+
[1, t[:heading][:queue], nil],
|
28
|
+
[1, t[:heading][:class], nil],
|
29
|
+
[1, t[:heading][:args], nil],
|
30
|
+
[1, nil, t[:heading][:started_at]],
|
31
|
+
],
|
32
|
+
]
|
33
|
+
|
34
|
+
(0...(@height - 1)).each do |i|
|
35
|
+
s << [ # table row slots
|
36
|
+
[2, -> { @workers.data.values[i][:name] rescue nil }, nil],
|
37
|
+
[1, -> { @workers.data.values[i][:queue] rescue nil }, nil],
|
38
|
+
[1, -> { @workers.data.values[i][:class] rescue nil }, nil],
|
39
|
+
[1, -> { @workers.data.values[i][:args] rescue nil }, nil],
|
40
|
+
[1, nil, -> { @workers.data.values[i][:started_at] rescue nil }],
|
41
|
+
]
|
42
|
+
end
|
43
|
+
|
44
|
+
s
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -5,19 +5,26 @@ module SidekiqSpy
|
|
5
5
|
module Display
|
6
6
|
class Screen
|
7
7
|
|
8
|
-
|
8
|
+
CURSES_GETCH_TIMEOUT = 100
|
9
|
+
|
10
|
+
attr_reader :height
|
11
|
+
attr_reader :width
|
9
12
|
|
10
13
|
def initialize
|
11
14
|
Curses.init_screen
|
12
15
|
Curses.nl
|
13
16
|
Curses.noecho
|
14
17
|
Curses.curs_set(0)
|
18
|
+
Curses.timeout = CURSES_GETCH_TIMEOUT
|
15
19
|
|
16
20
|
@height = Curses.lines
|
17
21
|
@width = Curses.cols
|
18
22
|
|
19
|
-
@panels = {
|
20
|
-
:header
|
23
|
+
@panels = { # attach panels, defining height, width, top, left
|
24
|
+
:header => Display::Panels::Header.new( 1, @width, 0, 0),
|
25
|
+
:redis_stats => Display::Panels::RedisStats.new( 3, @width, 1, 0),
|
26
|
+
:sidekiq_stats => Display::Panels::SidekiqStats.new(2, @width, 5, 0),
|
27
|
+
:workers => Display::Panels::Workers.new( (@height - 8), @width, 8, 0),
|
21
28
|
}
|
22
29
|
end
|
23
30
|
|
@@ -31,50 +38,8 @@ module SidekiqSpy
|
|
31
38
|
@panels.each { |pname, panel| panel.refresh }
|
32
39
|
end
|
33
40
|
|
34
|
-
|
35
|
-
|
36
|
-
def panel_header
|
37
|
-
stats = Spy::Stats.new
|
38
|
-
|
39
|
-
structure = [
|
40
|
-
[
|
41
|
-
[1, t[:program], nil],
|
42
|
-
[1, nil, -> { Time.now.strftime("%T %z") }],
|
43
|
-
],
|
44
|
-
[
|
45
|
-
[2, t[:redis][:connection], -> { stats.connection }],
|
46
|
-
[1, t[:redis][:namespace], -> { stats.namespace }],
|
47
|
-
],
|
48
|
-
[
|
49
|
-
[1, t[:redis][:version], -> { stats.redis_version }],
|
50
|
-
[1, t[:redis][:uptime], -> { stats.uptime }],
|
51
|
-
[1, t[:redis][:connections], -> { stats.connections }],
|
52
|
-
],
|
53
|
-
[
|
54
|
-
[1, t[:redis][:memory], -> { stats.memory }],
|
55
|
-
[1, t[:redis][:memory_peak], -> { stats.memory_peak }],
|
56
|
-
[1, nil, nil],
|
57
|
-
],
|
58
|
-
nil,
|
59
|
-
[
|
60
|
-
[1, t[:sidekiq][:busy], -> { stats.busy }],
|
61
|
-
[1, t[:sidekiq][:retries], -> { stats.retries }],
|
62
|
-
[1, t[:sidekiq][:processed], -> { stats.processed }],
|
63
|
-
],
|
64
|
-
[
|
65
|
-
[1, t[:sidekiq][:enqueued], -> { stats.enqueued }],
|
66
|
-
[1, t[:sidekiq][:scheduled], -> { stats.scheduled }],
|
67
|
-
[1, t[:sidekiq][:failed], -> { stats.failed }],
|
68
|
-
],
|
69
|
-
nil,
|
70
|
-
]
|
71
|
-
|
72
|
-
opts = {
|
73
|
-
:divider_l => t[:divider][:left],
|
74
|
-
:divider_r => t[:divider][:right],
|
75
|
-
}
|
76
|
-
|
77
|
-
Display::Panel.new(structure.length, @width, 0, 0, structure, opts)
|
41
|
+
def next_key
|
42
|
+
Curses.getch
|
78
43
|
end
|
79
44
|
|
80
45
|
end
|