eye 0.4.2 → 0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.travis.yml +4 -0
  4. data/CHANGES.md +11 -0
  5. data/README.md +3 -3
  6. data/Rakefile +8 -0
  7. data/bin/eye +0 -316
  8. data/bin/loader_eye +3 -3
  9. data/examples/test.eye +2 -2
  10. data/eye.gemspec +4 -9
  11. data/lib/eye.rb +4 -2
  12. data/lib/eye/application.rb +3 -3
  13. data/lib/eye/checker.rb +14 -5
  14. data/lib/eye/checker/cputime.rb +23 -0
  15. data/lib/eye/checker/file_touched.rb +15 -0
  16. data/lib/eye/checker/http.rb +7 -9
  17. data/lib/eye/checker/memory.rb +1 -1
  18. data/lib/eye/checker/runtime.rb +28 -0
  19. data/lib/eye/checker/socket.rb +4 -4
  20. data/lib/eye/cli.rb +166 -0
  21. data/lib/eye/cli/commands.rb +79 -0
  22. data/lib/eye/cli/render.rb +137 -0
  23. data/lib/eye/cli/server.rb +85 -0
  24. data/lib/eye/client.rb +3 -3
  25. data/lib/eye/config.rb +17 -14
  26. data/lib/eye/controller.rb +6 -10
  27. data/lib/eye/controller/commands.rb +6 -10
  28. data/lib/eye/controller/helpers.rb +1 -1
  29. data/lib/eye/controller/send_command.rb +5 -2
  30. data/lib/eye/controller/status.rb +37 -105
  31. data/lib/eye/dsl.rb +1 -1
  32. data/lib/eye/dsl/application_opts.rb +6 -2
  33. data/lib/eye/dsl/child_process_opts.rb +3 -2
  34. data/lib/eye/dsl/config_opts.rb +2 -2
  35. data/lib/eye/dsl/group_opts.rb +2 -1
  36. data/lib/eye/dsl/main.rb +4 -2
  37. data/lib/eye/dsl/opts.rb +11 -4
  38. data/lib/eye/dsl/validation.rb +49 -43
  39. data/lib/eye/group.rb +1 -1
  40. data/lib/eye/loader.rb +5 -9
  41. data/lib/eye/{settings.rb → local.rb} +1 -1
  42. data/lib/eye/logger.rb +5 -0
  43. data/lib/eye/notify.rb +12 -6
  44. data/lib/eye/notify/jabber.rb +2 -2
  45. data/lib/eye/process/child.rb +3 -1
  46. data/lib/eye/process/commands.rb +2 -2
  47. data/lib/eye/process/controller.rb +1 -1
  48. data/lib/eye/process/trigger.rb +1 -1
  49. data/lib/eye/sigar.rb +5 -0
  50. data/lib/eye/system.rb +7 -6
  51. data/lib/eye/system_resources.rb +46 -41
  52. data/lib/eye/trigger.rb +15 -8
  53. data/lib/eye/trigger/flapping.rb +1 -1
  54. data/lib/eye/trigger/stop_childs.rb +1 -1
  55. data/lib/eye/trigger/transition.rb +15 -0
  56. data/lib/eye/utils.rb +12 -0
  57. data/lib/eye/utils/leak_19.rb +7 -0
  58. data/lib/eye/utils/mini_active_support.rb +106 -0
  59. metadata +24 -15
  60. data/lib/eye/controller/show_history.rb +0 -63
  61. data/lib/eye/trigger/state.rb +0 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4cc2e7aadccf1d14e140a5973af361dbb08095e9
4
- data.tar.gz: 2a893e150885625c221d598f9a0dcddf4040e076
3
+ metadata.gz: 52f2c58046c9d6301970df8a240c6c961ff0733a
4
+ data.tar.gz: 822332e4acc57056a53e81bb608eb77d02c12efd
5
5
  SHA512:
6
- metadata.gz: 8e97e29338ad7de4c16f4c36b599f911625431b0680e96a523e04b8ba8046730270b80af718b55d323c2524952477a876f3e097be67ee3ecf3d1cf1ec4b3c18f
7
- data.tar.gz: f284102b968e833691aab4cccac606f6bb2815dbcc9514203ac687f607c2603e8f12b0e18cb3daddbf09569e217d1e9c6ae4ad86232a63e5c32a10958eb5b1dc
6
+ metadata.gz: d65c899e338aeae72c9a7d637a60e6bd6e5dfc971c3ffaccb44d48fb8f362b41831a20ae16df93bdb9f0717c9499bad0a5a84829fcb24a46d97af81ddc89eb2d
7
+ data.tar.gz: f14fdcdb398ef75eb47f145ff231bd80f4f7f28597c89ffba4d5983c9dc6bf5ae2edbf8e0ffa90fb84c0a8949b7e158bdb961a166891f124bc2cb32bb9c6561a
data/.gitignore CHANGED
@@ -32,3 +32,5 @@ script
32
32
  [0-9].rb
33
33
  *.cache
34
34
  *.tmp
35
+ /vendor/
36
+
@@ -4,3 +4,7 @@ rvm:
4
4
  - "1.9.3"
5
5
  - "2.0"
6
6
  script: bundle exec rake N=15
7
+ #before_script:
8
+ # - bundle exec rake remove_coverage
9
+ #after_script:
10
+ # - bundle exec rake coveralls:push
data/CHANGES.md CHANGED
@@ -1,3 +1,14 @@
1
+ 0.5
2
+ -------
3
+ * little fixes in dsl
4
+ * remove activesupport dependency
5
+ * rename `state` trigger to `transition`
6
+ * add runtime, cputime, file_touched checks
7
+ * real cpu check
8
+ * use sigar gem instead of `ps ax`
9
+ * refactor cli (requires `eye q && eye l` after update gem from 0.4.x)
10
+ * update celluloid to 0.15
11
+
1
12
  0.4.2
2
13
  -----
3
14
  * add checker options :initial_grace, :skip_initial_fails
data/README.md CHANGED
@@ -100,8 +100,8 @@ Eye.application "test" do
100
100
  start_command "bundle exec thin start -R thin.ru -p 33233 -d -l thin.log -P thin.pid"
101
101
  stop_signals [:QUIT, 2.seconds, :TERM, 1.seconds, :KILL]
102
102
 
103
- check :http, :url => "http://127.0.0.1:33233/hello", :pattern => /World/, :every => 5.seconds,
104
- :times => [2, 3], :timeout => 1.second
103
+ check :http, :url => "http://127.0.0.1:33233/hello", :pattern => /World/,
104
+ :every => 5.seconds, :times => [2, 3], :timeout => 1.second
105
105
  end
106
106
 
107
107
  end
@@ -116,7 +116,7 @@ load folder with configs:
116
116
  $ eye l examples/
117
117
  $ eye l examples/*.rb
118
118
 
119
- foregraund load:
119
+ foreground load:
120
120
 
121
121
  $ eye l CONF -f
122
122
 
data/Rakefile CHANGED
@@ -3,6 +3,9 @@
3
3
  require "bundler/gem_tasks"
4
4
  require 'rspec/core/rake_task'
5
5
  require 'parallel_tests/tasks'
6
+ require 'coveralls/rake/task'
7
+
8
+ Coveralls::RakeTask.new
6
9
 
7
10
  task :default => :pspecs
8
11
 
@@ -14,6 +17,11 @@ RSpec::Core::RakeTask.new(:spec) do |t|
14
17
  t.verbose = false
15
18
  end
16
19
 
20
+ task :remove_coverage do
21
+ require 'fileutils'
22
+ FileUtils.rm_rf(File.expand_path(File.join(File.dirname(__FILE__), %w{ coverage })))
23
+ end
24
+
17
25
  task :env do
18
26
  require 'bundler/setup'
19
27
  require 'eye'
data/bin/eye CHANGED
@@ -1,321 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
  $:.unshift File.expand_path(File.join(File.dirname(__FILE__), %w[.. lib]))
3
- require 'rubygems' if RUBY_VERSION < '1.9'
4
3
  require 'eye'
5
4
 
6
- gem 'thor'
7
- require 'thor'
8
-
9
- class Eye::Cli < Thor
10
-
11
- desc "info [MASK]", "show process statuses"
12
- def info(mask = nil)
13
- print cmd(:info, *Array(mask))
14
- end
15
-
16
- desc "status ", "show process statuses"
17
- def status
18
- say ":status is deprecated, use :info instead", :yellow
19
- info
20
- end
21
-
22
- desc "xinfo", "extended eye info, debug data"
23
- method_option :config, :type => :boolean, :aliases => "-c"
24
- method_option :processes, :type => :boolean, :aliases => "-p"
25
- def xinfo
26
- print cmd(:xinfo, :config => options[:config], :processes => options[:processes])
27
- end
28
-
29
- desc "oinfo", "onelined info"
30
- def oinfo
31
- print cmd(:oinfo)
32
- end
33
-
34
- desc "load [CONF, ...]", "load config (and start server if needed) (-f for foregraund start)"
35
- method_option :foregraund, :type => :boolean, :aliases => "-f"
36
- def load(*configs)
37
- configs.map!{ |c| File.expand_path(c) } if !configs.empty?
38
-
39
- if options[:foregraund]
40
- # in foregraund we stop another server, and run just 1 current config version
41
- error!("foregraund expected only one config") if configs.size != 1
42
- server_start_foregraund(configs.first)
43
-
44
- elsif server_started?
45
- say_load_result cmd(:load, *configs)
46
-
47
- else
48
- server_start(configs)
49
-
50
- end
51
- end
52
-
53
- desc "quit", "stop eye monitoring"
54
- def quit
55
- res = _cmd(:quit)
56
-
57
- # if eye server got crazy, stop by force
58
- ensure_stop_previous_server if res != :corrupred_data
59
-
60
- # remove pid_file
61
- File.delete(Eye::Settings.pid_path) if File.exists?(Eye::Settings.pid_path)
62
-
63
- say "quit...", :yellow
64
- end
65
-
66
- [:start, :stop, :restart, :unmonitor, :monitor, :delete, :match].each do |_cmd|
67
- desc "#{_cmd} MASK[,...]", "#{_cmd} app,group or process"
68
- define_method(_cmd) do |*targets|
69
- send_command(_cmd, *targets)
70
- end
71
- end
72
-
73
- desc "signal SIG, MASK[,...]", "send signal to matched app,group or process (ex: `eye sig USR2 some_app`)"
74
- def signal(sig, *targets)
75
- send_command(:signal, sig, *targets)
76
- end
77
-
78
- desc "break TARGET[,...]", "break group chain executing"
79
- def break(*targets)
80
- send_command(:break_chain, *targets)
81
- end
82
-
83
- desc "history TARGET[,...]", "show process states history"
84
- def history(*targets)
85
- print cmd(:history, *targets)
86
- end
87
-
88
- desc "trace [TARGET]", "tracing log for app,group or process"
89
- def trace(target = "")
90
- log_trace(target)
91
- end
92
-
93
- desc "version", "show current version"
94
- def version
95
- say Eye::ABOUT
96
- end
97
-
98
- desc "check CONF", "check syntax of the config file"
99
- method_option :host, :type => :string, :aliases => "-h"
100
- method_option :verbose, :type => :boolean, :aliases => "-v"
101
- def check(conf)
102
- conf = File.expand_path(conf) if conf && !conf.empty?
103
-
104
- Eye::System.host = options[:host] if options[:host]
105
- Eye::Dsl.verbose = options[:verbose]
106
-
107
- if RUBY_VERSION < '1.9'
108
- say_load_result cmd(:check, conf), :syntax => true
109
- else
110
- say_load_result Eye::Controller.new.check(conf), :syntax => true
111
- end
112
- end
113
-
114
- desc "explain CONF", "explain config tree (for debug)"
115
- method_option :host, :type => :string, :aliases => "-h"
116
- method_option :verbose, :type => :boolean, :aliases => "-v"
117
- def explain(conf)
118
- conf = File.expand_path(conf) if conf && !conf.empty?
119
-
120
- Eye::System.host = options[:host] if options[:host]
121
- Eye::Dsl.verbose = options[:verbose]
122
-
123
- if RUBY_VERSION < '1.9'
124
- say_load_result cmd(:explain, conf), :print_config => true, :syntax => true
125
- else
126
- say_load_result Eye::Controller.new.explain(conf), :print_config => true, :syntax => true
127
- end
128
- end
129
-
130
- desc "watch [MASK]", "interactive process info"
131
- def watch(*args)
132
- pid = Process.spawn("watch -n 1 --color #{$0} i #{args * ' '}")
133
- Process.waitpid(pid)
134
- rescue Interrupt
135
- end
136
-
137
- private
138
-
139
- def error!(msg)
140
- say msg, :red
141
- exit 1
142
- end
143
-
144
- def print(msg, new_line = true)
145
- say msg if msg && !msg.empty?
146
- say if new_line
147
- end
148
-
149
- def client
150
- @client ||= Eye::Client.new(Eye::Settings.socket_path)
151
- end
152
-
153
- def _cmd(cmd, *args)
154
- client.command(cmd, *args)
155
- rescue Errno::ECONNREFUSED, Errno::ENOENT
156
- :not_started
157
- end
158
-
159
- def cmd(cmd, *args)
160
- res = _cmd(cmd, *args)
161
-
162
- if res == :not_started
163
- error! "socket(#{Eye::Settings.socket_path}) not found, did you `eye load`?"
164
- elsif res == :timeouted
165
- error! "eye does not answer, timeouted..."
166
- end
167
-
168
- res
169
- end
170
-
171
- def server_started?
172
- _cmd(:ping) == :pong
173
- end
174
-
175
- def say_load_result(res = {}, opts = {})
176
- error!(res) unless res.is_a?(Hash)
177
- say_filename = (res.size > 1)
178
- say "eye started!", :green if opts[:started]
179
- error = false
180
- res.each do |filename, _res|
181
- say "#{filename}: ", nil, true if say_filename
182
- show_load_message(_res, opts)
183
- error = true if _res[:error]
184
- end
185
-
186
- exit(1) if error
187
- end
188
-
189
- def show_load_message(res, opts = {})
190
- if res[:error]
191
- say res[:message], :red
192
- res[:backtrace].to_a.each{|line| say line, :red }
193
- else
194
- if opts[:syntax]
195
- say "config ok!", :green if !res[:empty]
196
- else
197
- say "config loaded!", :green if !res[:empty]
198
- end
199
-
200
- if opts[:print_config]
201
- require 'pp'
202
- PP.pp res[:config], STDOUT, 150
203
- end
204
- end
205
- end
206
-
207
- def send_command(_cmd, *args)
208
- res = cmd(_cmd, *args)
209
- if res == :unknown_command
210
- error! "unknown command :#{_cmd}"
211
- elsif res == :corrupred_data
212
- error! "something crazy wrong, check eye logs!"
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
223
- else
224
- error! "unknown result #{res.inspect}"
225
- end
226
- end
227
-
228
- def log_trace(tag = '')
229
- log_file = cmd(:logger_dev)
230
- if log_file && File.exists?(log_file)
231
- Process.exec "tail -n 100 -f #{log_file} | grep '#{tag}'"
232
- else
233
- error! "log file not found #{log_file.inspect}"
234
- end
235
- end
236
-
237
- def loader_path
238
- if RUBY_VERSION < '1.9'
239
- begin
240
- return Gem.bin_path('eye', 'loader_eye')
241
- rescue Gem::GemNotFoundException, Gem::Exception
242
- end
243
- end
244
-
245
- filename = File.expand_path(File.join(File.dirname(__FILE__), %w[loader_eye]))
246
- File.exists?(filename) ? filename : nil
247
- end
248
-
249
- def ruby_path
250
- require 'rbconfig'
251
- RbConfig::CONFIG['bindir'] + "/ruby"
252
- end
253
-
254
- def ensure_loader_path
255
- unless loader_path
256
- error! "start monitoring needs to run under ruby with installed gem 'eye'"
257
- end
258
- end
259
-
260
- def server_start_foregraund(conf = nil)
261
- ensure_loader_path
262
- Eye::Settings.ensure_eye_dir
263
-
264
- if server_started?
265
- _cmd(:quit) && sleep(1) # stop previous server
266
- end
267
-
268
- args = []
269
- args += ['-c', conf] if conf
270
- args += ['-l', 'stdout']
271
-
272
- Process.exec(ruby_path, loader_path, *args)
273
- end
274
-
275
- def server_start(configs)
276
- ensure_loader_path
277
- Eye::Settings.ensure_eye_dir
278
-
279
- ensure_stop_previous_server
280
-
281
- args = []
282
- pid = Process.spawn(ruby_path, loader_path, *args, :out => '/dev/null', :err => '/dev/null', :in => '/dev/null',
283
- :chdir => '/', :pgroup => true)
284
- Process.detach(pid)
285
- File.open(Eye::Settings.pid_path, 'w'){|f| f.write(pid) }
286
-
287
- unless wait_server
288
- error! "server not runned in 15 seconds, something crazy wrong"
289
- end
290
-
291
- configs.unshift(Eye::Settings.eyeconfig) if File.exists?(Eye::Settings.eyeconfig)
292
-
293
- if !configs.empty?
294
- say_load_result cmd(:load, *configs), :started => true
295
- else
296
- say "started!", :green
297
- end
298
- end
299
-
300
- def ensure_stop_previous_server
301
- Eye::Settings.ensure_eye_dir
302
- pid = File.read(Eye::Settings.pid_path).to_i rescue nil
303
- if pid
304
- Process.kill(9, pid) rescue nil
305
- end
306
- File.delete(Eye::Settings.pid_path) rescue nil
307
- true
308
- end
309
-
310
- def wait_server(timeout = 15)
311
- Timeout.timeout(timeout) do
312
- sleep 0.3 while !server_started?
313
- end
314
- true
315
- rescue Timeout::Error
316
- false
317
- end
318
-
319
- end
320
-
321
5
  Eye::Cli.start
@@ -30,9 +30,9 @@ OptionParser.new do |opts|
30
30
 
31
31
  end.parse!
32
32
 
33
- Eye::Settings.ensure_eye_dir
33
+ Eye::Local.ensure_eye_dir
34
34
 
35
- socket_path = options[:socket_path] || Eye::Settings.socket_path
35
+ socket_path = options[:socket_path] || Eye::Local.socket_path
36
36
  server = Eye::Server.new(socket_path)
37
37
 
38
38
  Eye::Logger.log_level = options[:debug] ? Logger::DEBUG : Logger::INFO
@@ -45,7 +45,7 @@ Eye::Control # preload
45
45
 
46
46
  if config
47
47
  res = server.command('load', config)
48
- exit if res[:error]
48
+ exit if res.values.any? { |r| r[:error] }
49
49
  end
50
50
 
51
51
  Eye::Control.set_proc_line
@@ -78,8 +78,8 @@ Eye.application "test" do
78
78
  start_command "bundle exec thin start -R thin.ru -p 33233 -d -l thin.log -P thin.pid"
79
79
  stop_signals [:QUIT, 2.seconds, :TERM, 1.seconds, :KILL]
80
80
 
81
- check :http, :url => "http://127.0.0.1:33233/hello", :pattern => /World/, :every => 5.seconds,
82
- :times => [2, 3], :timeout => 1.second
81
+ check :http, :url => "http://127.0.0.1:33233/hello", :pattern => /World/,
82
+ :every => 5.seconds, :times => [2, 3], :timeout => 1.second
83
83
  end
84
84
 
85
85
  end
@@ -2,7 +2,7 @@ require File.expand_path('../lib/eye', __FILE__)
2
2
 
3
3
  Gem::Specification.new do |gem|
4
4
  gem.authors = "Konstantin Makarchev"
5
- gem.email = "kostya27@gmail.com"
5
+ gem.email = "eye-rb@googlegroups.com"
6
6
 
7
7
  gem.description = gem.summary = \
8
8
  %q{Process monitoring tool. Inspired from Bluepill and God. Requires Ruby(MRI) >= 1.9.3-p194. Uses Celluloid and Celluloid::IO.}
@@ -19,16 +19,11 @@ Gem::Specification.new do |gem|
19
19
  gem.required_ruby_version = '>= 1.9.2' # because of celluloid
20
20
  gem.required_rubygems_version = '>= 1.3.6'
21
21
 
22
- gem.add_dependency 'celluloid', '~> 0.14.0'
23
- gem.add_dependency 'celluloid-io', '~> 0.14.0'
22
+ gem.add_dependency 'celluloid', '~> 0.15.0'
23
+ gem.add_dependency 'celluloid-io', '~> 0.15.0'
24
24
  gem.add_dependency 'state_machine'
25
25
  gem.add_dependency 'thor'
26
-
27
- if RUBY_VERSION == '1.9.2'
28
- gem.add_dependency 'activesupport', '>= 3', '< 4.0'
29
- else
30
- gem.add_dependency 'activesupport', '>= 3'
31
- end
26
+ gem.add_dependency 'sigar', '~> 0.7.2'
32
27
 
33
28
  gem.add_development_dependency 'rake'
34
29
  gem.add_development_dependency 'rspec', '< 2.14'