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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7a20cacb912beed5baf1c80012a87e5115dae2bf
4
- data.tar.gz: 1db3848aa6af319f5037ee72dc6720683735d53d
3
+ metadata.gz: 91574e1eabbcadaf02cc6fe5e70e3031e7022b33
4
+ data.tar.gz: da4ab6eb49ee18c42665a627abc08df7529e4972
5
5
  SHA512:
6
- metadata.gz: ed49f93281287bbc32d5a5b7629a85d5489e50e35bbae88e16369e764644d87f697593c610a5e149e65d9a4aff8041dc902b2901782d4b2e061e7930e8bc0cef
7
- data.tar.gz: d16b91fb061442fb4ec76ed66e415cb10e3ab5776bab6b7c77e5893c88d666072c09559b35870b222151a68005a22f5332be5e57b9aad0a7ce06a014d54a38ed
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
  [![Gem Version](https://badge.fury.io/rb/sidekiq-spy.png)](http://badge.fury.io/rb/sidekiq-spy)
4
- [![Build Status](https://travis-ci.org/tiredpixel/sidekiq-spy.png?branch=master,develop)](https://travis-ci.org/tiredpixel/sidekiq-spy)
4
+ [![Build Status](https://travis-ci.org/tiredpixel/sidekiq-spy.png?branch=master,stable)](https://travis-ci.org/tiredpixel/sidekiq-spy)
5
5
  [![Code Climate](https://codeclimate.com/github/tiredpixel/sidekiq-spy.png)](https://codeclimate.com/github/tiredpixel/sidekiq-spy)
6
- [![Coverage Status](https://coveralls.io/repos/tiredpixel/sidekiq-spy/badge.png?branch=master,develop)](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. In time,
17
- it would be nice to add the Workers, Queues, Retries, and Scheduled tabs, too.
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.1 | 01:02:58 +0100
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): 8|connections: 3
61
- memory: 4.84M|memory peak: 13.52M|
60
+ redis version: 2.6.11|uptime (d): 2|connections: 5
61
+ memory: 4.89M|memory peak: 5.03M|
62
62
 
63
- busy: 0|retries: 0|processed: 1304
64
- enqueued: 0|scheduled: 0|failed: 1236
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__)
@@ -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 = false
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
- while @running do
30
- refresh
31
-
32
- @sleep_timer = config.interval
33
-
34
- while @running && @sleep_timer > 0
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
- def initialize(height, width, top, left, structure, opts = {})
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
- include Translatable
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 => panel_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
- private
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