eye 0.3.2 → 0.4

Sign up to get free protection for your applications and to get access to all the features.
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