reel-eye 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +32 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +3 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE +22 -0
  7. data/README.md +170 -0
  8. data/Rakefile +20 -0
  9. data/bin/eye +322 -0
  10. data/bin/loader_eye +58 -0
  11. data/examples/notify.eye +18 -0
  12. data/examples/process_thin.rb +29 -0
  13. data/examples/processes/em.rb +57 -0
  14. data/examples/processes/forking.rb +20 -0
  15. data/examples/processes/sample.rb +144 -0
  16. data/examples/processes/thin.ru +12 -0
  17. data/examples/puma.eye +34 -0
  18. data/examples/rbenv.eye +11 -0
  19. data/examples/sidekiq.eye +23 -0
  20. data/examples/test.eye +81 -0
  21. data/examples/thin-farm.eye +29 -0
  22. data/examples/unicorn.eye +31 -0
  23. data/eye.gemspec +42 -0
  24. data/lib/eye.rb +28 -0
  25. data/lib/eye/application.rb +74 -0
  26. data/lib/eye/checker.rb +138 -0
  27. data/lib/eye/checker/cpu.rb +27 -0
  28. data/lib/eye/checker/file_ctime.rb +25 -0
  29. data/lib/eye/checker/file_size.rb +34 -0
  30. data/lib/eye/checker/http.rb +98 -0
  31. data/lib/eye/checker/memory.rb +27 -0
  32. data/lib/eye/checker/socket.rb +152 -0
  33. data/lib/eye/child_process.rb +101 -0
  34. data/lib/eye/client.rb +32 -0
  35. data/lib/eye/config.rb +88 -0
  36. data/lib/eye/control.rb +2 -0
  37. data/lib/eye/controller.rb +53 -0
  38. data/lib/eye/controller/commands.rb +73 -0
  39. data/lib/eye/controller/helpers.rb +61 -0
  40. data/lib/eye/controller/load.rb +214 -0
  41. data/lib/eye/controller/options.rb +48 -0
  42. data/lib/eye/controller/send_command.rb +115 -0
  43. data/lib/eye/controller/show_history.rb +62 -0
  44. data/lib/eye/controller/status.rb +131 -0
  45. data/lib/eye/dsl.rb +48 -0
  46. data/lib/eye/dsl/application_opts.rb +33 -0
  47. data/lib/eye/dsl/chain.rb +12 -0
  48. data/lib/eye/dsl/child_process_opts.rb +8 -0
  49. data/lib/eye/dsl/config_opts.rb +48 -0
  50. data/lib/eye/dsl/group_opts.rb +27 -0
  51. data/lib/eye/dsl/helpers.rb +12 -0
  52. data/lib/eye/dsl/main.rb +40 -0
  53. data/lib/eye/dsl/opts.rb +140 -0
  54. data/lib/eye/dsl/process_opts.rb +21 -0
  55. data/lib/eye/dsl/pure_opts.rb +110 -0
  56. data/lib/eye/dsl/validation.rb +59 -0
  57. data/lib/eye/group.rb +134 -0
  58. data/lib/eye/group/chain.rb +81 -0
  59. data/lib/eye/http.rb +31 -0
  60. data/lib/eye/http/router.rb +25 -0
  61. data/lib/eye/loader.rb +23 -0
  62. data/lib/eye/logger.rb +80 -0
  63. data/lib/eye/notify.rb +86 -0
  64. data/lib/eye/notify/jabber.rb +30 -0
  65. data/lib/eye/notify/mail.rb +44 -0
  66. data/lib/eye/process.rb +86 -0
  67. data/lib/eye/process/child.rb +58 -0
  68. data/lib/eye/process/commands.rb +256 -0
  69. data/lib/eye/process/config.rb +70 -0
  70. data/lib/eye/process/controller.rb +76 -0
  71. data/lib/eye/process/data.rb +47 -0
  72. data/lib/eye/process/monitor.rb +95 -0
  73. data/lib/eye/process/notify.rb +32 -0
  74. data/lib/eye/process/scheduler.rb +78 -0
  75. data/lib/eye/process/states.rb +86 -0
  76. data/lib/eye/process/states_history.rb +66 -0
  77. data/lib/eye/process/system.rb +97 -0
  78. data/lib/eye/process/trigger.rb +54 -0
  79. data/lib/eye/process/validate.rb +23 -0
  80. data/lib/eye/process/watchers.rb +69 -0
  81. data/lib/eye/reason.rb +20 -0
  82. data/lib/eye/server.rb +52 -0
  83. data/lib/eye/settings.rb +46 -0
  84. data/lib/eye/system.rb +154 -0
  85. data/lib/eye/system_resources.rb +86 -0
  86. data/lib/eye/trigger.rb +53 -0
  87. data/lib/eye/trigger/flapping.rb +28 -0
  88. data/lib/eye/utils.rb +14 -0
  89. data/lib/eye/utils/alive_array.rb +31 -0
  90. data/lib/eye/utils/celluloid_chain.rb +70 -0
  91. data/lib/eye/utils/leak_19.rb +7 -0
  92. data/lib/eye/utils/tail.rb +20 -0
  93. metadata +390 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 464e9e9a66aef932d82c8452238c083bfc3561da
4
+ data.tar.gz: 795aaf16fec1578814570cdeff914cf5792144f6
5
+ SHA512:
6
+ metadata.gz: f68bc9205b02c7b3a1643c4f97a5a6f7e151391b93563019663d84b9bf335a8c5a180445ea4b1f97d888fc64d4ba3c3fa6fa1cefdaa404a9d8fe472a96f42f62
7
+ data.tar.gz: 9dcf75372e1a0a93f68a1f7ff04542b1ff391a9522597f7203322157b5860c8bf0243fb271b41c19567077dd70c657bc154061a2a35267149b68469acea7e011
data/.gitignore ADDED
@@ -0,0 +1,32 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.pid
19
+ *.log
20
+ *.swp
21
+ *~
22
+ TODO
23
+ .todo
24
+ *.png
25
+ *.lock
26
+ experiments
27
+ .git2
28
+ *.stop
29
+ *sublime*
30
+ examples/work*.eye
31
+ script
32
+ [0-9].rb
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --profile
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - "1.9.3"
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in eye.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012-2013 'Konstantin Makarchev'
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,170 @@
1
+ Eye [![Build Status](https://secure.travis-ci.org/kostya/eye.png?branch=master)](http://travis-ci.org/kostya/eye)
2
+ ===
3
+
4
+ Process monitoring tool. An alternative to God and Bluepill. With Bluepill like config syntax. Requires MRI Ruby >= 1.9.3-p194. Uses Celluloid and Celluloid::IO.
5
+
6
+ Little demo, shows general commands and how chain works:
7
+
8
+ [![Eye](https://raw.github.com/kostya/stuff/master/eye/eye.png)](https://raw.github.com/kostya/stuff/master/eye/eye.gif)
9
+
10
+ Recommended installation on the server (system wide):
11
+
12
+ $ sudo /usr/local/ruby/1.9.3/bin/gem install eye
13
+ $ sudo ln -sf /usr/local/ruby/1.9.3/bin/eye /usr/local/bin/eye
14
+
15
+
16
+ Config example, shows some typical processes and most of the options (see in exampes/ folder):
17
+
18
+ examples/test.eye
19
+ ```ruby
20
+ # load submodules, here just for example
21
+ Eye.load("./eye/*.rb")
22
+
23
+ # Eye self-configuration section
24
+ Eye.config do
25
+ logger "/tmp/eye.log"
26
+ end
27
+
28
+ # Adding application
29
+ Eye.application "test" do
30
+ # All options inherits down to the config leafs.
31
+ # except `env`, which merging down
32
+
33
+ working_dir File.expand_path(File.join(File.dirname(__FILE__), %w[ processes ]))
34
+ stdall "trash.log" # stdout,err logs for processes by default
35
+ env "APP_ENV" => "production" # global env for each processes
36
+ triggers :flapping, :times => 10, :within => 1.minute, :retry_in => 10.minutes
37
+ checks :cpu, :below => 100, :times => 3 # global check for all processes
38
+
39
+ group "samples" do
40
+ chain :grace => 5.seconds # chained start-restart with 5s interval, one by one.
41
+
42
+ # eye daemonized process
43
+ process :sample1 do
44
+ pid_file "1.pid" # pid_path will be expanded with the working_dir
45
+ start_command "ruby ./sample.rb"
46
+ daemonize true
47
+ stdall "sample1.log"
48
+
49
+ checks :cpu, :below => 30, :times => [3, 5]
50
+ end
51
+
52
+ # self daemonized process
53
+ process :sample2 do
54
+ pid_file "2.pid"
55
+ start_command "ruby ./sample.rb -d --pid 2.pid --log sample2.log"
56
+ stop_command "kill -9 {PID}"
57
+
58
+ checks :memory, :below => 300.megabytes, :times => 3
59
+ end
60
+ end
61
+
62
+ # daemon with 3 childs
63
+ process :forking do
64
+ pid_file "forking.pid"
65
+ start_command "ruby ./forking.rb start"
66
+ stop_command "ruby forking.rb stop"
67
+ stdall "forking.log"
68
+
69
+ start_timeout 5.seconds
70
+ stop_grace 5.seconds
71
+
72
+ monitor_children do
73
+ restart_command "kill -2 {PID}" # for this child process
74
+ checks :memory, :below => 300.megabytes, :times => 3
75
+ end
76
+ end
77
+
78
+ # eventmachine process, daemonized with eye
79
+ process :event_machine do |p|
80
+ pid_file 'em.pid'
81
+ start_command 'ruby em.rb'
82
+ stdout 'em.log'
83
+ daemonize true
84
+ stop_signals [:QUIT, 2.seconds, :KILL]
85
+
86
+ checks :socket, :addr => "tcp://127.0.0.1:33221", :every => 10.seconds, :times => 2,
87
+ :timeout => 1.second, :send_data => "ping", :expect_data => /pong/
88
+ end
89
+
90
+ # thin process, self daemonized
91
+ process :thin do
92
+ pid_file "thin.pid"
93
+ start_command "bundle exec thin start -R thin.ru -p 33233 -d -l thin.log -P thin.pid"
94
+ stop_signals [:QUIT, 2.seconds, :TERM, 1.seconds, :KILL]
95
+
96
+ checks :http, :url => "http://127.0.0.1:33233/hello", :pattern => /World/, :every => 5.seconds,
97
+ :times => [2, 3], :timeout => 1.second
98
+ end
99
+
100
+ end
101
+ ```
102
+
103
+ ### Start monitoring and load config:
104
+
105
+ $ eye l(oad) examples/test.eye
106
+
107
+ load folder with configs:
108
+
109
+ $ eye l examples/
110
+ $ eye l examples/*.rb
111
+
112
+ Load also uses for config synchronization and load new application into runned eye daemon. Light operation, so i recommend to use with every deploy (and than restart processes).
113
+ (for processes with option `stop_on_delete`, `load` becomes a tool for full config synchronization, which stopps deleted from config processes).
114
+
115
+
116
+ Process statuses:
117
+
118
+ $ eye i(nfo)
119
+
120
+ ```
121
+ test
122
+ samples
123
+ sample1 ....................... up (21:52, 0%, 13Mb, <4107>)
124
+ sample2 ....................... up (21:52, 0%, 12Mb, <4142>)
125
+ event_machine ................... up (21:52, 3%, 26Mb, <4112>)
126
+ forking ......................... up (21:52, 0%, 41Mb, <4203>)
127
+ child-4206 .................... up (21:52, 0%, 41Mb, <4206>)
128
+ child-4211 .................... up (21:52, 0%, 41Mb, <4211>)
129
+ child-4214 .................... up (21:52, 0%, 41Mb, <4214>)
130
+ thin ............................ up (21:53, 2%, 54Mb, <4228>)
131
+ ```
132
+
133
+ ### Commands:
134
+
135
+ start, stop, restart, delete, monitor, unmonitor
136
+
137
+ Command params (with restart for example):
138
+
139
+ $ eye r(estart) all
140
+ $ eye r test
141
+ $ eye r samples
142
+ $ eye r sample1
143
+ $ eye r sample*
144
+ $ eye r test:samples
145
+ $ eye r test:samples:sample1
146
+ $ eye r test:samples:sample*
147
+ $ eye r test:*sample*
148
+
149
+ Check config syntax:
150
+
151
+ $ eye c(heck) examples/test.eye
152
+
153
+ Log tracing:
154
+
155
+ $ eye trace
156
+ $ eye tr test
157
+ $ eye tr sample
158
+
159
+ Quit monitoring:
160
+
161
+ $ eye q(uit)
162
+
163
+ Config explain (for debug):
164
+
165
+ $ eye explain examples/test.eye
166
+
167
+
168
+ ### Config api:
169
+
170
+ Waiting for pull requests ..., until that you can read `examples` and `spec/dsl` folders.
data/Rakefile ADDED
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ require 'rspec/core/rake_task'
5
+ task :default => :spec
6
+ RSpec::Core::RakeTask.new(:spec) do |t|
7
+ t.verbose = false
8
+ end
9
+
10
+ task :env do
11
+ require 'bundler/setup'
12
+ require 'eye'
13
+ Eye::Control
14
+ Eye::Process # preload
15
+ end
16
+
17
+ desc "graph"
18
+ task :graph => :env do
19
+ StateMachine::Machine.draw("Eye::Process")
20
+ end
data/bin/eye ADDED
@@ -0,0 +1,322 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift File.expand_path(File.join(File.dirname(__FILE__), %w[.. lib]))
3
+ require 'rubygems' if RUBY_VERSION < '1.9'
4
+ require 'eye'
5
+
6
+ gem 'thor'
7
+ require 'thor'
8
+
9
+ class Cli < Thor
10
+
11
+ desc "info [MASK]", "show process statuses"
12
+ def info(mask = nil)
13
+ res = cmd(:info, mask)
14
+ puts res if res && !res.empty?
15
+ puts
16
+ end
17
+
18
+ desc "status ", "show process statuses"
19
+ def status
20
+ say ":status is deprecated, use :info instead", :yellow
21
+ info
22
+ end
23
+
24
+ desc "xinfo", "extended eye info, debug data"
25
+ method_option :config, :type => :boolean, :aliases => "-c"
26
+ method_option :show_processes, :type => :boolean, :aliases => "-p"
27
+ def xinfo
28
+ res = cmd(:xinfo, options[:config], options[:show_processes])
29
+ puts res if res && !res.empty?
30
+ puts
31
+ end
32
+
33
+ desc "oinfo", "onelined info"
34
+ def oinfo
35
+ res = cmd(:oinfo)
36
+ puts res if res && !res.empty?
37
+ puts
38
+ end
39
+
40
+ desc "load [CONF, ...]", "load config (and start server if needed) (-f for foregraund start)"
41
+ method_option :foregraund, :type => :boolean, :aliases => "-f"
42
+ method_option :logger, :type => :string, :aliases => "-l"
43
+ def load(*configs)
44
+ configs.map!{ |c| File.expand_path(c) } if !configs.empty?
45
+
46
+ if options[:foregraund]
47
+ # in foregraund we stop another server, and run just 1 current config version
48
+ if configs.size != 1
49
+ say "foregraund expected only one config", :red
50
+ exit 1
51
+ end
52
+
53
+ server_start_foregraund(configs.first)
54
+
55
+ elsif server_started?
56
+ say_load_result cmd(:load, *configs)
57
+
58
+ else
59
+ server_start(configs)
60
+
61
+ end
62
+ end
63
+
64
+ desc "quit", "stop eye monitoring"
65
+ def quit
66
+ res = _cmd(:quit)
67
+
68
+ # if eye server got crazy, stop by force
69
+ ensure_stop_previous_server if res != :corrupred_marshal
70
+
71
+ say "stopped...", :yellow
72
+ end
73
+
74
+ [:start, :stop, :restart, :unmonitor, :monitor, :delete, :match].each do |_cmd|
75
+ desc "#{_cmd} MASK[,...]", "#{_cmd} app,group or process"
76
+ define_method(_cmd) do |*targets|
77
+ send_command(_cmd, *targets)
78
+ end
79
+ end
80
+
81
+ desc "signal SIG, MASK[,...]", "send signal to matched app,group or process (ex: `eye sig USR2 some_app`)"
82
+ def signal(sig, *targets)
83
+ send_command(:signal, sig, *targets)
84
+ end
85
+
86
+ desc "break TARGET[,...]", "break group chain executing"
87
+ def break(*targets)
88
+ send_command(:break_chain, *targets)
89
+ end
90
+
91
+ desc "history TARGET[,...]", "show process states history"
92
+ def history(*targets)
93
+ res = cmd(:history, *targets)
94
+ puts res if res && !res.empty?
95
+ puts
96
+ end
97
+
98
+ desc "trace [TARGET]", "tracing log for app,group or process"
99
+ def trace(target = "")
100
+ log_trace(target)
101
+ end
102
+
103
+ desc "version", "show current version"
104
+ def version
105
+ say Eye::ABOUT
106
+ end
107
+
108
+ desc "check CONF", "check syntax of the config file"
109
+ method_option :host, :type => :string, :aliases => "-h"
110
+ method_option :verbose, :type => :boolean, :aliases => "-v"
111
+ def check(conf)
112
+ conf = File.expand_path(conf) if conf && !conf.empty?
113
+
114
+ Eye::System.host = options[:host] if options[:host]
115
+ Eye::Dsl.verbose = options[:verbose]
116
+
117
+ if RUBY_VERSION < '1.9'
118
+ say_load_result cmd(:check, conf), :syntax => true
119
+ else
120
+ say_load_result Eye::Control.check(conf), :syntax => true
121
+ end
122
+ end
123
+
124
+ desc "explain CONF", "explain config tree (for debug)"
125
+ method_option :host, :type => :string, :aliases => "-h"
126
+ method_option :verbose, :type => :boolean, :aliases => "-v"
127
+ def explain(conf)
128
+ conf = File.expand_path(conf) if conf && !conf.empty?
129
+
130
+ Eye::System.host = options[:host] if options[:host]
131
+ Eye::Dsl.verbose = options[:verbose]
132
+
133
+ if RUBY_VERSION < '1.9'
134
+ say_load_result cmd(:explain, conf), :print_config => true, :syntax => true
135
+ else
136
+ say_load_result Eye::Control.explain(conf), :print_config => true, :syntax => true
137
+ end
138
+ end
139
+
140
+ desc "watch [MASK]", "interactive process info"
141
+ def watch(*args)
142
+ pid = Process.spawn("watch -n 1 --color #{$0} i #{args * ' '}")
143
+ Process.waitpid(pid)
144
+ rescue Interrupt
145
+ end
146
+
147
+ private
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
+ say "eye monitoring not found, did you start it?", :red
164
+ exit 1
165
+ elsif res == :timeouted
166
+ say "eye does not answer, timeouted...", :red
167
+ exit 1
168
+ end
169
+
170
+ res
171
+ end
172
+
173
+ def server_started?
174
+ _cmd(:ping) == :pong
175
+ end
176
+
177
+ def say_load_result(res = {}, opts = {})
178
+ say(res) unless res.is_a?(Hash)
179
+
180
+ if res.has_key?(:error) # TODO: remove that case, outdated
181
+ show_load_message(res, opts)
182
+ exit 1 if res[:error]
183
+ else
184
+ say_filename = (res.size > 1)
185
+ say "eye started!", :green if opts[:started]
186
+ res.each do |filename, _res|
187
+ say "#{filename}: ", nil, true if say_filename
188
+ show_load_message(_res, opts)
189
+ end
190
+ end
191
+ end
192
+
193
+ def show_load_message(res, opts = {})
194
+ if res[:error]
195
+ say res[:message], :red
196
+ res[:backtrace].to_a.each{|line| say line, :red }
197
+ else
198
+ all_error = false
199
+ if opts[:syntax]
200
+ say "config ok!", :green if !res[:empty]
201
+ else
202
+ say "config loaded!", :green if !res[:empty]
203
+ end
204
+
205
+ if opts[:print_config]
206
+ require 'pp'
207
+ PP.pp res[:config]
208
+ end
209
+ end
210
+ end
211
+
212
+ def send_command(_cmd, *args)
213
+ res = cmd(_cmd, *args)
214
+ if res == :unknown_command
215
+ say "unknown command :#{_cmd}", :red
216
+ elsif res == :corrupred_marshal
217
+ say "something crazy wrong, check eye logs!", :red
218
+ elsif res == []
219
+ say "command :#{_cmd}, targets not found!", :red
220
+ else
221
+ say "command :#{_cmd} sended to [#{res * ", "}]"
222
+ end
223
+ end
224
+
225
+ def log_trace(tag = '')
226
+ log_file = cmd(:logger_dev)
227
+ if log_file && File.exists?(log_file)
228
+ Process.exec "tail -n 100 -f #{log_file} | grep '#{tag}'"
229
+ else
230
+ say "log file not found #{log_file.inspect}", :red
231
+ end
232
+ end
233
+
234
+ def loader_path
235
+ if RUBY_VERSION < '1.9'
236
+ begin
237
+ return Gem.bin_path('eye', 'loader_eye')
238
+ rescue Gem::GemNotFoundException, Gem::Exception
239
+ end
240
+ end
241
+
242
+ filename = File.expand_path(File.join(File.dirname(__FILE__), %w[loader_eye]))
243
+ File.exists?(filename) ? filename : nil
244
+ end
245
+
246
+ def ruby_path
247
+ require 'rbconfig'
248
+ RbConfig::CONFIG['bindir'] + "/ruby"
249
+ end
250
+
251
+ def ensure_loader_path
252
+ unless loader_path
253
+ say "start monitoring needs to run under ruby with installed gem 'eye'", :red
254
+ exit 1
255
+ end
256
+ end
257
+
258
+ def server_start_foregraund(conf = nil)
259
+ ensure_loader_path
260
+ Eye::Settings.ensure_eye_dir
261
+
262
+ if server_started?
263
+ _cmd(:quit) && sleep(1) # stop previous server
264
+ end
265
+
266
+ args = []
267
+ args += ['-c', conf] if conf
268
+ args += ['-l', 'stdout']
269
+
270
+ Process.exec(ruby_path, loader_path, *args)
271
+ end
272
+
273
+ def server_start(configs)
274
+ ensure_loader_path
275
+ Eye::Settings.ensure_eye_dir
276
+
277
+ ensure_stop_previous_server
278
+
279
+ args = []
280
+ args += ['-l', options[:logger]] if options[:logger]
281
+
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
+ say "server not runned in 15 seconds, something crazy wrong", :red
289
+ exit 1
290
+ end
291
+
292
+ configs.unshift(Eye::Settings.eyeconfig) if File.exists?(Eye::Settings.eyeconfig)
293
+
294
+ if !configs.empty?
295
+ say_load_result cmd(:load, *configs), :started => true
296
+ else
297
+ say "started!", :green
298
+ end
299
+ end
300
+
301
+ def ensure_stop_previous_server
302
+ Eye::Settings.ensure_eye_dir
303
+ pid = File.read(Eye::Settings.pid_path).to_i rescue nil
304
+ if pid
305
+ Process.kill(9, pid) rescue nil
306
+ end
307
+ File.delete(Eye::Settings.pid_path) rescue nil
308
+ true
309
+ end
310
+
311
+ def wait_server(timeout = 15)
312
+ Timeout.timeout(timeout) do
313
+ sleep 0.3 while !server_started?
314
+ end
315
+ true
316
+ rescue Timeout::Error
317
+ false
318
+ end
319
+
320
+ end
321
+
322
+ Cli.start