eye 0.4.2 → 0.5

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 (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'