eye 0.3.2 → 0.4

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.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rspec +1 -1
  4. data/.travis.yml +3 -1
  5. data/CHANGES.md +11 -2
  6. data/Gemfile +1 -0
  7. data/README.md +18 -14
  8. data/Rakefile +10 -3
  9. data/bin/eye +41 -27
  10. data/examples/process_thin.rb +1 -1
  11. data/examples/processes/em.rb +2 -2
  12. data/examples/processes/forking.rb +2 -2
  13. data/examples/processes/sample.rb +5 -5
  14. data/examples/rbenv.eye +1 -1
  15. data/examples/sidekiq.eye +2 -2
  16. data/examples/test.eye +10 -6
  17. data/examples/thin-farm.eye +1 -1
  18. data/examples/unicorn.eye +1 -1
  19. data/eye.gemspec +13 -7
  20. data/lib/eye.rb +6 -6
  21. data/lib/eye/application.rb +9 -6
  22. data/lib/eye/checker.rb +51 -21
  23. data/lib/eye/checker/file_size.rb +1 -1
  24. data/lib/eye/checker/http.rb +3 -3
  25. data/lib/eye/checker/memory.rb +1 -1
  26. data/lib/eye/checker/socket.rb +6 -6
  27. data/lib/eye/child_process.rb +7 -11
  28. data/lib/eye/client.rb +6 -6
  29. data/lib/eye/config.rb +2 -2
  30. data/lib/eye/controller.rb +11 -8
  31. data/lib/eye/controller/commands.rb +8 -9
  32. data/lib/eye/controller/helpers.rb +1 -0
  33. data/lib/eye/controller/load.rb +11 -7
  34. data/lib/eye/controller/send_command.rb +44 -19
  35. data/lib/eye/controller/show_history.rb +8 -7
  36. data/lib/eye/controller/status.rb +39 -26
  37. data/lib/eye/dsl.rb +3 -3
  38. data/lib/eye/dsl/application_opts.rb +4 -4
  39. data/lib/eye/dsl/config_opts.rb +4 -4
  40. data/lib/eye/dsl/helpers.rb +2 -2
  41. data/lib/eye/dsl/main.rb +2 -2
  42. data/lib/eye/dsl/opts.rb +19 -14
  43. data/lib/eye/dsl/process_opts.rb +1 -1
  44. data/lib/eye/dsl/pure_opts.rb +2 -2
  45. data/lib/eye/dsl/validation.rb +7 -5
  46. data/lib/eye/group.rb +17 -11
  47. data/lib/eye/group/chain.rb +3 -3
  48. data/lib/eye/loader.rb +8 -6
  49. data/lib/eye/logger.rb +14 -5
  50. data/lib/eye/notify.rb +13 -7
  51. data/lib/eye/notify/jabber.rb +2 -2
  52. data/lib/eye/notify/mail.rb +2 -2
  53. data/lib/eye/process.rb +10 -13
  54. data/lib/eye/process/child.rb +1 -1
  55. data/lib/eye/process/commands.rb +34 -32
  56. data/lib/eye/process/config.rb +17 -12
  57. data/lib/eye/process/controller.rb +3 -6
  58. data/lib/eye/process/data.rb +16 -5
  59. data/lib/eye/process/monitor.rb +12 -5
  60. data/lib/eye/process/notify.rb +1 -1
  61. data/lib/eye/process/scheduler.rb +3 -3
  62. data/lib/eye/process/states.rb +10 -13
  63. data/lib/eye/process/states_history.rb +3 -3
  64. data/lib/eye/process/system.rb +17 -21
  65. data/lib/eye/process/trigger.rb +11 -30
  66. data/lib/eye/process/watchers.rb +9 -9
  67. data/lib/eye/server.rb +14 -6
  68. data/lib/eye/settings.rb +4 -4
  69. data/lib/eye/system.rb +10 -7
  70. data/lib/eye/system_resources.rb +4 -4
  71. data/lib/eye/trigger.rb +58 -21
  72. data/lib/eye/trigger/flapping.rb +24 -4
  73. data/lib/eye/trigger/state.rb +28 -0
  74. data/lib/eye/utils/alive_array.rb +1 -1
  75. data/lib/eye/utils/celluloid_klass.rb +5 -0
  76. data/lib/eye/utils/pmap.rb +7 -0
  77. data/lib/eye/utils/tail.rb +1 -1
  78. metadata +39 -23
  79. data/lib/eye/utils/leak_19.rb +0 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f91b36c9b73d802f079d62a345bbf29fcb929768
4
- data.tar.gz: 2953436d9e587ff52b0a2ee146c2ac52434e1662
3
+ metadata.gz: 2a4ce0513f92a734194ec12a2c10aa8cadcfaafa
4
+ data.tar.gz: 43e96f1ccc671f83454d790d8e546785b3cb8c18
5
5
  SHA512:
6
- metadata.gz: 1569dabc95b8e86f63eaf7b3d921758638cd2183ea403610400f437f6824fe0d18d0b763c3ce2752ab6d2a63641d2755affd51137d134f6cf3adf2e6caa10869
7
- data.tar.gz: 1e9d50a96ae0cc44d2ab218d45933ec4b3a49ec5686875351de2f6b5be10deaaa2e1843431bb88b89eb783c59a0c1f76d1ccda46ad915d11fc4e5da2c27640f1
6
+ metadata.gz: 780ee7abb50e1a473614d33e132ccbea9854cdf4e7f5b5ca77ee003caebcddf2759f2d6ae489f7585a915b8630d3813f60924e2762c224bd2f65ad51defcaddb
7
+ data.tar.gz: 26b46e22aeddce190a889072e88d41bb1d638db3147c6fe4cd79d6861ac5e11063de82deb0fa5e78ee34a8c106c2592c05db11748ff7569e6e0e2f7df2d95661
data/.gitignore CHANGED
@@ -31,3 +31,4 @@ examples/work*.eye
31
31
  script
32
32
  [0-9].rb
33
33
  *.cache
34
+ *.tmp
data/.rspec CHANGED
@@ -1,2 +1,2 @@
1
1
  --color
2
- --profile
2
+ --format progress
@@ -1,4 +1,6 @@
1
1
  language: ruby
2
2
  rvm:
3
+ - "1.9.2"
3
4
  - "1.9.3"
4
- script: COVA=1 bundle exec rake
5
+ - "2.0"
6
+ script: bundle exec rake N=15
data/CHANGES.md CHANGED
@@ -1,11 +1,20 @@
1
- 0.3.3.dev
1
+ 0.4.dev
2
2
  ---------
3
+ * pass tests on 1.9.2
4
+ * relax activesupport dependency
5
+ * change client-server protocol (requires `eye q && eye l` after update gem from 0.3.x)
6
+ * not matching targets from different applications
7
+ * improve triggers (custom, better flapping)
8
+ * delete pid_file on crash for daemonize process
9
+ * delete pid_file on stop for all process types (`clear_pid false` to disable)
10
+ * parallel tests (from 30 mins to 3min)
11
+ * update celluloid to 0.14
3
12
 
4
13
  0.3.2
5
14
  ---------
6
15
  * improve matching targers
7
16
  * possibility to add many checkers with the same type per process (ex: checks :http_2, ...)
8
- * add uid,gid options (only for ruby 2.0)
17
+ * add uid, gid options (only for ruby 2.0)
9
18
 
10
19
  0.3.1
11
20
  -----
data/Gemfile CHANGED
@@ -3,3 +3,4 @@ source 'https://rubygems.org'
3
3
  # Specify your gem's dependencies in eye.gemspec
4
4
  gemspec
5
5
 
6
+ gem 'parallel_tests', :git => "https://github.com/kostya/parallel_tests.git"
data/README.md CHANGED
@@ -21,7 +21,7 @@ Config example, shows some typical processes and most of the options (see in exa
21
21
  examples/test.eye
22
22
  ```ruby
23
23
  # load submodules, here just for example
24
- Eye.load("./eye/*.rb")
24
+ Eye.load("./eye/*.rb")
25
25
 
26
26
  # Eye self-configuration section
27
27
  Eye.config do
@@ -46,6 +46,10 @@ Eye.application "test" do
46
46
  process :sample1 do
47
47
  pid_file "1.pid" # pid_path will be expanded with the working_dir
48
48
  start_command "ruby ./sample.rb"
49
+
50
+ # when no stop_command or stop_signals, default stop is [:TERM, 0.5, :KILL]
51
+ # default `restart` command is `stop; start`
52
+
49
53
  daemonize true
50
54
  stdall "sample1.log"
51
55
 
@@ -71,13 +75,13 @@ Eye.application "test" do
71
75
 
72
76
  start_timeout 5.seconds
73
77
  stop_grace 5.seconds
74
-
78
+
75
79
  monitor_children do
76
80
  restart_command "kill -2 {PID}" # for this child process
77
81
  checks :memory, :below => 300.megabytes, :times => 3
78
82
  end
79
83
  end
80
-
84
+
81
85
  # eventmachine process, daemonized with eye
82
86
  process :event_machine do |p|
83
87
  pid_file 'em.pid'
@@ -85,8 +89,8 @@ Eye.application "test" do
85
89
  stdout 'em.log'
86
90
  daemonize true
87
91
  stop_signals [:QUIT, 2.seconds, :KILL]
88
-
89
- checks :socket, :addr => "tcp://127.0.0.1:33221", :every => 10.seconds, :times => 2,
92
+
93
+ checks :socket, :addr => "tcp://127.0.0.1:33221", :every => 10.seconds, :times => 2,
90
94
  :timeout => 1.second, :send_data => "ping", :expect_data => /pong/
91
95
  end
92
96
 
@@ -96,7 +100,7 @@ Eye.application "test" do
96
100
  start_command "bundle exec thin start -R thin.ru -p 33233 -d -l thin.log -P thin.pid"
97
101
  stop_signals [:QUIT, 2.seconds, :TERM, 1.seconds, :KILL]
98
102
 
99
- checks :http, :url => "http://127.0.0.1:33233/hello", :pattern => /World/, :every => 5.seconds,
103
+ checks :http, :url => "http://127.0.0.1:33233/hello", :pattern => /World/, :every => 5.seconds,
100
104
  :times => [2, 3], :timeout => 1.second
101
105
  end
102
106
 
@@ -117,12 +121,12 @@ Load also uses for config synchronization and load new application into runned e
117
121
 
118
122
 
119
123
  Process statuses:
120
-
124
+
121
125
  $ eye i(nfo)
122
126
 
123
127
  ```
124
- test
125
- samples
128
+ test
129
+ samples
126
130
  sample1 ....................... up (21:52, 0%, 13Mb, <4107>)
127
131
  sample2 ....................... up (21:52, 0%, 12Mb, <4142>)
128
132
  event_machine ................... up (21:52, 3%, 26Mb, <4112>)
@@ -134,7 +138,7 @@ test
134
138
  ```
135
139
 
136
140
  ### Commands:
137
-
141
+
138
142
  start, stop, restart, delete, monitor, unmonitor
139
143
 
140
144
  Command params (with restart for example):
@@ -157,11 +161,11 @@ Config explain (for debug):
157
161
 
158
162
  $ eye e(xplain) examples/test.eye
159
163
 
160
- Log tracing:
164
+ Log tracing (tail and grep):
161
165
 
162
- $ eye trace
163
- $ eye tr test
164
- $ eye tr sample
166
+ $ eye t(race)
167
+ $ eye t test
168
+ $ eye t sample
165
169
 
166
170
  Quit monitoring:
167
171
 
data/Rakefile CHANGED
@@ -1,8 +1,15 @@
1
1
  #!/usr/bin/env rake
2
- require "bundler/gem_tasks"
3
2
 
3
+ require "bundler/gem_tasks"
4
4
  require 'rspec/core/rake_task'
5
- task :default => :spec
5
+ require 'parallel_tests/tasks'
6
+
7
+ task :default => :pspecs
8
+
9
+ task :pspecs do
10
+ Rake::Task['parallel:spec'].invoke(ENV['N'] || 8)
11
+ end
12
+
6
13
  RSpec::Core::RakeTask.new(:spec) do |t|
7
14
  t.verbose = false
8
15
  end
@@ -10,7 +17,7 @@ end
10
17
  task :env do
11
18
  require 'bundler/setup'
12
19
  require 'eye'
13
- Eye::Control
20
+ Eye::Controller
14
21
  Eye::Process # preload
15
22
  end
16
23
 
data/bin/eye CHANGED
@@ -6,11 +6,11 @@ require 'eye'
6
6
  gem 'thor'
7
7
  require 'thor'
8
8
 
9
- class Cli < Thor
9
+ class Eye::Cli < Thor
10
10
 
11
11
  desc "info [MASK]", "show process statuses"
12
12
  def info(mask = nil)
13
- print cmd(:info, mask)
13
+ print cmd(:info, *Array(mask))
14
14
  end
15
15
 
16
16
  desc "status ", "show process statuses"
@@ -21,9 +21,9 @@ class Cli < Thor
21
21
 
22
22
  desc "xinfo", "extended eye info, debug data"
23
23
  method_option :config, :type => :boolean, :aliases => "-c"
24
- method_option :show_processes, :type => :boolean, :aliases => "-p"
25
- def xinfo
26
- print cmd(:xinfo, options[:config], options[:show_processes])
24
+ method_option :processes, :type => :boolean, :aliases => "-p"
25
+ def xinfo
26
+ print cmd(:xinfo, :config => options[:config], :processes => options[:processes])
27
27
  end
28
28
 
29
29
  desc "oinfo", "onelined info"
@@ -55,11 +55,14 @@ class Cli < Thor
55
55
  res = _cmd(:quit)
56
56
 
57
57
  # if eye server got crazy, stop by force
58
- ensure_stop_previous_server if res != :corrupred_marshal
58
+ ensure_stop_previous_server if res != :corrupred_data
59
59
 
60
- say "stopped...", :yellow
60
+ # remove pid_file
61
+ File.delete(Eye::Settings.pid_path) if File.exists?(Eye::Settings.pid_path)
62
+
63
+ say "quit...", :yellow
61
64
  end
62
-
65
+
63
66
  [:start, :stop, :restart, :unmonitor, :monitor, :delete, :match].each do |_cmd|
64
67
  desc "#{_cmd} MASK[,...]", "#{_cmd} app,group or process"
65
68
  define_method(_cmd) do |*targets|
@@ -100,11 +103,11 @@ class Cli < Thor
100
103
 
101
104
  Eye::System.host = options[:host] if options[:host]
102
105
  Eye::Dsl.verbose = options[:verbose]
103
-
106
+
104
107
  if RUBY_VERSION < '1.9'
105
108
  say_load_result cmd(:check, conf), :syntax => true
106
109
  else
107
- say_load_result Eye::Control.check(conf), :syntax => true
110
+ say_load_result Eye::Controller.new.check(conf), :syntax => true
108
111
  end
109
112
  end
110
113
 
@@ -120,7 +123,7 @@ class Cli < Thor
120
123
  if RUBY_VERSION < '1.9'
121
124
  say_load_result cmd(:explain, conf), :print_config => true, :syntax => true
122
125
  else
123
- say_load_result Eye::Control.explain(conf), :print_config => true, :syntax => true
126
+ say_load_result Eye::Controller.new.explain(conf), :print_config => true, :syntax => true
124
127
  end
125
128
  end
126
129
 
@@ -152,7 +155,7 @@ private
152
155
  rescue Errno::ECONNREFUSED, Errno::ENOENT
153
156
  :not_started
154
157
  end
155
-
158
+
156
159
  def cmd(cmd, *args)
157
160
  res = _cmd(cmd, *args)
158
161
 
@@ -161,22 +164,26 @@ private
161
164
  elsif res == :timeouted
162
165
  error! "eye does not answer, timeouted..."
163
166
  end
164
-
167
+
165
168
  res
166
169
  end
167
-
170
+
168
171
  def server_started?
169
172
  _cmd(:ping) == :pong
170
173
  end
171
-
174
+
172
175
  def say_load_result(res = {}, opts = {})
173
176
  error!(res) unless res.is_a?(Hash)
174
177
  say_filename = (res.size > 1)
175
178
  say "eye started!", :green if opts[:started]
179
+ error = false
176
180
  res.each do |filename, _res|
177
181
  say "#{filename}: ", nil, true if say_filename
178
182
  show_load_message(_res, opts)
183
+ error = true if _res[:error]
179
184
  end
185
+
186
+ exit(1) if error
180
187
  end
181
188
 
182
189
  def show_load_message(res, opts = {})
@@ -184,7 +191,6 @@ private
184
191
  say res[:message], :red
185
192
  res[:backtrace].to_a.each{|line| say line, :red }
186
193
  else
187
- all_error = false
188
194
  if opts[:syntax]
189
195
  say "config ok!", :green if !res[:empty]
190
196
  else
@@ -193,22 +199,30 @@ private
193
199
 
194
200
  if opts[:print_config]
195
201
  require 'pp'
196
- PP.pp res[:config]
202
+ PP.pp res[:config], STDOUT, 150
197
203
  end
198
204
  end
199
205
  end
200
-
206
+
201
207
  def send_command(_cmd, *args)
202
208
  res = cmd(_cmd, *args)
203
209
  if res == :unknown_command
204
210
  error! "unknown command :#{_cmd}"
205
- elsif res == :corrupred_marshal
211
+ elsif res == :corrupred_data
206
212
  error! "something crazy wrong, check eye logs!"
207
- elsif res == []
208
- error! "command :#{_cmd}, targets not found!"
213
+ elsif res.is_a?(Hash)
214
+ if res[:error]
215
+ error! "Error: #{res[:error]}"
216
+ elsif res = res[:result]
217
+ if res == []
218
+ error! "command :#{_cmd}, targets not found!"
219
+ else
220
+ say "command :#{_cmd} sended to [#{res * ", "}]"
221
+ end
222
+ end
209
223
  else
210
- say "command :#{_cmd} sended to [#{res * ", "}]"
211
- end
224
+ error! "unknown result #{res.inspect}"
225
+ end
212
226
  end
213
227
 
214
228
  def log_trace(tag = '')
@@ -219,7 +233,7 @@ private
219
233
  error! "log file not found #{log_file.inspect}"
220
234
  end
221
235
  end
222
-
236
+
223
237
  def loader_path
224
238
  if RUBY_VERSION < '1.9'
225
239
  begin
@@ -230,8 +244,8 @@ private
230
244
 
231
245
  filename = File.expand_path(File.join(File.dirname(__FILE__), %w[loader_eye]))
232
246
  File.exists?(filename) ? filename : nil
233
- end
234
-
247
+ end
248
+
235
249
  def ruby_path
236
250
  require 'rbconfig'
237
251
  RbConfig::CONFIG['bindir'] + "/ruby"
@@ -304,4 +318,4 @@ private
304
318
 
305
319
  end
306
320
 
307
- Cli.start
321
+ Eye::Cli.start
@@ -23,7 +23,7 @@ def thin(proxy, port)
23
23
 
24
24
  stdall "thin.stdall.log"
25
25
 
26
- checks :http, :url => "http://127.0.0.1:#{port}/hello", :pattern => /World/,
26
+ checks :http, :url => "http://127.0.0.1:#{port}/hello", :pattern => /World/,
27
27
  :every => 5.seconds, :times => [2, 3], :timeout => 1.second
28
28
  end
29
29
  end
@@ -24,7 +24,7 @@ class Echo < EM::Connection
24
24
 
25
25
  def unbind
26
26
  puts "-- someone disconnected from the echo server!"
27
- end
27
+ end
28
28
  end
29
29
 
30
30
  class EchoObj < EM::Connection
@@ -41,7 +41,7 @@ class EchoObj < EM::Connection
41
41
 
42
42
  def unbind
43
43
  puts "-- someone disconnected from the echo server!"
44
- end
44
+ end
45
45
  end
46
46
 
47
47
  trap "QUIT" do
@@ -4,14 +4,14 @@ require 'forking'
4
4
  root = File.expand_path(File.dirname(__FILE__))
5
5
 
6
6
  f = Forking.new(:name => 'forking', :working_dir => root,
7
- :log_file => "#{root}/forking.log",
7
+ :log_file => "#{root}/forking.log",
8
8
  :pid_file => "#{root}/forking.pid", :sync_log => true)
9
9
 
10
10
  3.times do |i|
11
11
  f.spawn(:log_file => "#{root}/child#{i}.log", :sync_log => true) do
12
12
  $0 = "forking child"
13
13
  loop do
14
- p "#{Time.now} - #{Time.now.to_f} - #{i} - tick"
14
+ p "#{Time.now} - #{Time.now.to_f} - #{i} - tick"
15
15
  sleep 0.1
16
16
  end
17
17
  end
@@ -14,19 +14,19 @@ optparse = OptionParser.new do|opts|
14
14
  exit
15
15
  end
16
16
 
17
- opts.on( '-p', '--pid FILE', 'pid_file' ) do |a|
17
+ opts.on( '-p', '--pid FILE', 'pid_file' ) do |a|
18
18
  options[:pid_file] = a
19
19
  end
20
20
 
21
- opts.on( '-l', '--log FILE', 'log_file' ) do |a|
21
+ opts.on( '-l', '--log FILE', 'log_file' ) do |a|
22
22
  options[:log_file] = a
23
23
  end
24
24
 
25
- opts.on( '-L', '--lock FILE', 'lock_file' ) do |a|
25
+ opts.on( '-L', '--lock FILE', 'lock_file' ) do |a|
26
26
  options[:lock_file] = a
27
27
  end
28
28
 
29
- opts.on( '-d', '--daemonize', 'Daemonize' ) do
29
+ opts.on( '-d', '--daemonize', 'Daemonize' ) do
30
30
  options[:daemonize] = true
31
31
  end
32
32
 
@@ -34,7 +34,7 @@ optparse = OptionParser.new do|opts|
34
34
  options[:daemonize_delay] = d
35
35
  end
36
36
 
37
- opts.on( '-r', '--raise', 'Raised execution' ) do
37
+ opts.on( '-r', '--raise', 'Raised execution' ) do
38
38
  options[:raise] = true
39
39
  end
40
40
 
@@ -1,7 +1,7 @@
1
1
  Eye.application "rbenv_example" do
2
2
  env 'RBENV_ROOT' => '/usr/local/rbenv', 'PATH' => "/usr/local/rbenv/shims:/usr/local/rbenv/bin:#{ENV['PATH']}"
3
3
  working_dir File.expand_path(File.join(File.dirname(__FILE__), %w[ processes ]))
4
-
4
+
5
5
  process "some_process" do
6
6
  pid_file "some.pid"
7
7
  start_command "ruby some.rb"
@@ -9,7 +9,7 @@ def sidekiq_process(proxy, name)
9
9
  stdall "log/#{name}.log"
10
10
  daemonize true
11
11
  stop_signals [:QUIT, 5.seconds, :TERM, 5.seconds, :KILL]
12
-
12
+
13
13
  checks :cpu, :every => 30, :below => 100, :times => 5
14
14
  checks :memory, :every => 30, :below => 300.megabytes, :times => 5
15
15
  end
@@ -18,6 +18,6 @@ end
18
18
  Eye.application :sidekiq_test do
19
19
  working_dir File.expand_path(File.join(File.dirname(__FILE__), %w[ processes ]))
20
20
  env "RAILS_ENV" => 'production'
21
-
21
+
22
22
  sidekiq_process self, :sidekiq
23
23
  end