eye 0.1.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (190) hide show
  1. data/.gitignore +31 -0
  2. data/.rspec +2 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE +22 -0
  5. data/README.md +132 -0
  6. data/Rakefile +18 -0
  7. data/bin/eye +282 -0
  8. data/bin/loader_eye +56 -0
  9. data/examples/processes/em.rb +56 -0
  10. data/examples/processes/forking.rb +20 -0
  11. data/examples/processes/sample.rb +144 -0
  12. data/examples/rbenv.eye +11 -0
  13. data/examples/test.eye +65 -0
  14. data/examples/unicorn.eye +29 -0
  15. data/eye.gemspec +37 -0
  16. data/lib/eye.rb +25 -0
  17. data/lib/eye/application.rb +65 -0
  18. data/lib/eye/checker.rb +118 -0
  19. data/lib/eye/checker/cpu.rb +27 -0
  20. data/lib/eye/checker/file_ctime.rb +29 -0
  21. data/lib/eye/checker/file_size.rb +38 -0
  22. data/lib/eye/checker/http.rb +94 -0
  23. data/lib/eye/checker/memory.rb +27 -0
  24. data/lib/eye/checker/socket.rb +148 -0
  25. data/lib/eye/checker/validation.rb +49 -0
  26. data/lib/eye/child_process.rb +75 -0
  27. data/lib/eye/client.rb +32 -0
  28. data/lib/eye/control.rb +2 -0
  29. data/lib/eye/controller.rb +43 -0
  30. data/lib/eye/controller/commands.rb +64 -0
  31. data/lib/eye/controller/helpers.rb +61 -0
  32. data/lib/eye/controller/load.rb +224 -0
  33. data/lib/eye/controller/send_command.rb +88 -0
  34. data/lib/eye/controller/status.rb +136 -0
  35. data/lib/eye/dsl.rb +52 -0
  36. data/lib/eye/dsl/application_opts.rb +33 -0
  37. data/lib/eye/dsl/chain.rb +12 -0
  38. data/lib/eye/dsl/child_process_opts.rb +7 -0
  39. data/lib/eye/dsl/config_opts.rb +11 -0
  40. data/lib/eye/dsl/group_opts.rb +27 -0
  41. data/lib/eye/dsl/helpers.rb +12 -0
  42. data/lib/eye/dsl/main.rb +58 -0
  43. data/lib/eye/dsl/opts.rb +88 -0
  44. data/lib/eye/dsl/process_opts.rb +21 -0
  45. data/lib/eye/dsl/pure_opts.rb +132 -0
  46. data/lib/eye/dsl/validate.rb +41 -0
  47. data/lib/eye/group.rb +125 -0
  48. data/lib/eye/group/chain.rb +68 -0
  49. data/lib/eye/io/unix_server.rb +44 -0
  50. data/lib/eye/io/unix_socket.rb +39 -0
  51. data/lib/eye/loader.rb +13 -0
  52. data/lib/eye/logger.rb +80 -0
  53. data/lib/eye/process.rb +83 -0
  54. data/lib/eye/process/child.rb +61 -0
  55. data/lib/eye/process/commands.rb +256 -0
  56. data/lib/eye/process/config.rb +70 -0
  57. data/lib/eye/process/controller.rb +72 -0
  58. data/lib/eye/process/data.rb +46 -0
  59. data/lib/eye/process/monitor.rb +97 -0
  60. data/lib/eye/process/notify.rb +17 -0
  61. data/lib/eye/process/scheduler.rb +50 -0
  62. data/lib/eye/process/states.rb +92 -0
  63. data/lib/eye/process/states_history.rb +62 -0
  64. data/lib/eye/process/system.rb +60 -0
  65. data/lib/eye/process/trigger.rb +32 -0
  66. data/lib/eye/process/watchers.rb +67 -0
  67. data/lib/eye/server.rb +51 -0
  68. data/lib/eye/settings.rb +35 -0
  69. data/lib/eye/system.rb +145 -0
  70. data/lib/eye/system_resources.rb +83 -0
  71. data/lib/eye/trigger.rb +53 -0
  72. data/lib/eye/trigger/flapping.rb +24 -0
  73. data/lib/eye/utils.rb +5 -0
  74. data/lib/eye/utils/alive_array.rb +31 -0
  75. data/lib/eye/utils/celluloid_chain.rb +51 -0
  76. data/lib/eye/utils/leak_19.rb +7 -0
  77. data/lib/eye/utils/tail.rb +20 -0
  78. data/spec/checker/cpu_spec.rb +58 -0
  79. data/spec/checker/file_ctime_spec.rb +34 -0
  80. data/spec/checker/file_size_spec.rb +107 -0
  81. data/spec/checker/http_spec.rb +109 -0
  82. data/spec/checker/memory_spec.rb +64 -0
  83. data/spec/checker/socket_spec.rb +116 -0
  84. data/spec/checker_spec.rb +188 -0
  85. data/spec/child_process/child_process_spec.rb +46 -0
  86. data/spec/client_server_spec.rb +34 -0
  87. data/spec/controller/commands_spec.rb +92 -0
  88. data/spec/controller/controller_spec.rb +133 -0
  89. data/spec/controller/find_objects_spec.rb +150 -0
  90. data/spec/controller/group_spec.rb +110 -0
  91. data/spec/controller/intergration_spec.rb +327 -0
  92. data/spec/controller/load_spec.rb +326 -0
  93. data/spec/controller/races_spec.rb +70 -0
  94. data/spec/controller/stop_on_delete_spec.rb +157 -0
  95. data/spec/dsl/chain_spec.rb +140 -0
  96. data/spec/dsl/checks_spec.rb +202 -0
  97. data/spec/dsl/config_spec.rb +44 -0
  98. data/spec/dsl/dsl_spec.rb +73 -0
  99. data/spec/dsl/getter_spec.rb +223 -0
  100. data/spec/dsl/integration_spec.rb +311 -0
  101. data/spec/dsl/load_spec.rb +52 -0
  102. data/spec/dsl/process_spec.rb +330 -0
  103. data/spec/dsl/sub_procs_spec.rb +93 -0
  104. data/spec/dsl/with_server_spec.rb +104 -0
  105. data/spec/example/em.rb +57 -0
  106. data/spec/example/forking.rb +20 -0
  107. data/spec/example/sample.rb +154 -0
  108. data/spec/fixtures/dsl/0.rb +8 -0
  109. data/spec/fixtures/dsl/0a.rb +8 -0
  110. data/spec/fixtures/dsl/0c.rb +8 -0
  111. data/spec/fixtures/dsl/1.rb +5 -0
  112. data/spec/fixtures/dsl/bad.eye +6 -0
  113. data/spec/fixtures/dsl/configs/1.eye +3 -0
  114. data/spec/fixtures/dsl/configs/2.eye +1 -0
  115. data/spec/fixtures/dsl/configs/3.eye +1 -0
  116. data/spec/fixtures/dsl/configs/4.eye +3 -0
  117. data/spec/fixtures/dsl/empty.eye +20 -0
  118. data/spec/fixtures/dsl/include_test.eye +5 -0
  119. data/spec/fixtures/dsl/include_test/1.rb +6 -0
  120. data/spec/fixtures/dsl/include_test/ha.rb +4 -0
  121. data/spec/fixtures/dsl/include_test2.eye +5 -0
  122. data/spec/fixtures/dsl/integration.eye +30 -0
  123. data/spec/fixtures/dsl/integration2.eye +32 -0
  124. data/spec/fixtures/dsl/integration_locks.eye +30 -0
  125. data/spec/fixtures/dsl/integration_sor.eye +32 -0
  126. data/spec/fixtures/dsl/integration_sor2.eye +27 -0
  127. data/spec/fixtures/dsl/integration_sor3.eye +32 -0
  128. data/spec/fixtures/dsl/load.eye +25 -0
  129. data/spec/fixtures/dsl/load2.eye +7 -0
  130. data/spec/fixtures/dsl/load2_dup2.eye +13 -0
  131. data/spec/fixtures/dsl/load2_dup_pid.eye +7 -0
  132. data/spec/fixtures/dsl/load3.eye +10 -0
  133. data/spec/fixtures/dsl/load4.eye +7 -0
  134. data/spec/fixtures/dsl/load5.eye +8 -0
  135. data/spec/fixtures/dsl/load6.eye +17 -0
  136. data/spec/fixtures/dsl/load_dubls.eye +36 -0
  137. data/spec/fixtures/dsl/load_dup_ex_names.eye +15 -0
  138. data/spec/fixtures/dsl/load_error.eye +5 -0
  139. data/spec/fixtures/dsl/load_error_folder/load3.eye +10 -0
  140. data/spec/fixtures/dsl/load_error_folder/load4.eye +7 -0
  141. data/spec/fixtures/dsl/load_folder/load3.eye +10 -0
  142. data/spec/fixtures/dsl/load_folder/load4.eye +7 -0
  143. data/spec/fixtures/dsl/load_int.eye +8 -0
  144. data/spec/fixtures/dsl/load_int2.eye +13 -0
  145. data/spec/fixtures/dsl/load_logger.eye +26 -0
  146. data/spec/fixtures/dsl/load_logger2.eye +3 -0
  147. data/spec/fixtures/dsl/long_load.eye +5 -0
  148. data/spec/fixtures/dsl/subfolder1/proc1.rb +3 -0
  149. data/spec/fixtures/dsl/subfolder2.eye +9 -0
  150. data/spec/fixtures/dsl/subfolder2/common.rb +1 -0
  151. data/spec/fixtures/dsl/subfolder2/proc2.rb +3 -0
  152. data/spec/fixtures/dsl/subfolder2/sub/proc3.rb +6 -0
  153. data/spec/fixtures/dsl/subfolder3.eye +8 -0
  154. data/spec/fixtures/dsl/subfolder3/common.rb +1 -0
  155. data/spec/fixtures/dsl/subfolder3/proc4.rb +3 -0
  156. data/spec/fixtures/dsl/subfolder3/sub/proc5.rb +6 -0
  157. data/spec/fixtures/dsl/subfolder4.eye +6 -0
  158. data/spec/fixtures/dsl/subfolder4/a.rb +2 -0
  159. data/spec/fixtures/dsl/subfolder4/b.rb +1 -0
  160. data/spec/fixtures/dsl/subfolder4/c.rb +1 -0
  161. data/spec/mock_spec.rb +32 -0
  162. data/spec/process/checks/child_checks_spec.rb +79 -0
  163. data/spec/process/checks/cpu_spec.rb +114 -0
  164. data/spec/process/checks/ctime_spec.rb +43 -0
  165. data/spec/process/checks/fsize_spec.rb +22 -0
  166. data/spec/process/checks/http_spec.rb +52 -0
  167. data/spec/process/checks/intergration_spec.rb +32 -0
  168. data/spec/process/checks/memory_spec.rb +113 -0
  169. data/spec/process/child_process_spec.rb +125 -0
  170. data/spec/process/config_spec.rb +75 -0
  171. data/spec/process/controller_spec.rb +173 -0
  172. data/spec/process/monitoring_spec.rb +180 -0
  173. data/spec/process/restart_spec.rb +174 -0
  174. data/spec/process/scheduler_spec.rb +150 -0
  175. data/spec/process/start_spec.rb +261 -0
  176. data/spec/process/states_history_spec.rb +118 -0
  177. data/spec/process/stop_spec.rb +150 -0
  178. data/spec/process/system_spec.rb +100 -0
  179. data/spec/process/triggers/flapping_spec.rb +81 -0
  180. data/spec/process/update_config_spec.rb +63 -0
  181. data/spec/spec_helper.rb +120 -0
  182. data/spec/support/rr_celluloid.rb +36 -0
  183. data/spec/support/scheduler_hack.rb +16 -0
  184. data/spec/support/spec_support.rb +164 -0
  185. data/spec/system_resources_spec.rb +59 -0
  186. data/spec/system_spec.rb +170 -0
  187. data/spec/utils/alive_array_spec.rb +50 -0
  188. data/spec/utils/celluloid_chain_spec.rb +82 -0
  189. data/spec/utils/tail_spec.rb +21 -0
  190. metadata +558 -0
@@ -0,0 +1,31 @@
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
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --profile
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source :rubygems
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.
@@ -0,0 +1,132 @@
1
+ Eye
2
+ ===
3
+
4
+ Process monitoring tool. With Bluepill like config syntax. Requires MRI Ruby >= 1.9.2. Uses Celluloid and Celluloid::IO.
5
+
6
+
7
+ Recommended installation on the server (system wide):
8
+
9
+ $ sudo /usr/local/ruby/1.9.3/bin/gem install eye
10
+ $ sudo ln -sf /usr/local/ruby/1.9.3/bin/eye /usr/local/bin/eye
11
+
12
+
13
+ Config example, shows most of the options (examples/test.eye):
14
+
15
+ ```ruby
16
+ Eye.load("./eye/*.rb") # load submodules
17
+ Eye.config do
18
+ logger "/tmp/eye.log" # eye logger
19
+ end
20
+
21
+ Eye.app "test" do
22
+ working_dir File.expand_path(File.join(File.dirname(__FILE__), %w[ processes ]))
23
+ stdall "trash.log" # stdout + stderr
24
+ env "APP_ENV" => "production"
25
+ triggers :flapping, :times => 10, :within => 1.minute
26
+
27
+ group "samples" do
28
+ env "A" => "1" # env merging
29
+ chain :grace => 5.seconds, :action => :restart # restarting with 5s interval, one by one.
30
+
31
+ # eye daemonized process
32
+ process("sample1") do
33
+ pid_file "1.pid" # expanded with working_dir
34
+ start_command "ruby ./sample.rb"
35
+ daemonize true
36
+ stdall "sample1.log"
37
+
38
+ checks :cpu, :below => 30, :times => [3, 5]
39
+ end
40
+
41
+ # self daemonized process
42
+ process("sample2") do
43
+ pid_file "2.pid"
44
+ start_command "ruby ./sample.rb -d --pid 2.pid --log sample2.log"
45
+ stop_command "kill -9 {{PID}}"
46
+
47
+ checks :memory, :below => 300.megabytes, :times => 3
48
+ end
49
+ end
50
+
51
+ # daemon with 3 childs
52
+ process("forking") do
53
+ pid_file "forking.pid"
54
+ start_command "ruby ./forking.rb start"
55
+ stop_command "ruby forking.rb stop"
56
+ stdall "forking.log"
57
+
58
+ start_timeout 5.seconds
59
+ stop_grace 5.seconds
60
+
61
+ monitor_children do
62
+ childs_update_period 5.seconds
63
+
64
+ restart_command "kill -2 {{PID}}"
65
+ checks :memory, :below => 300.megabytes, :times => 3
66
+ end
67
+ end
68
+
69
+ end
70
+ ```
71
+
72
+ ### Start monitoring and load config:
73
+
74
+ $ eye l(oad) examples/test.eye
75
+
76
+ load folder with configs:
77
+
78
+ $ eye l examples/
79
+ $ eye l examples/*.rb
80
+
81
+ 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).
82
+ (for processes with option `stop_on_delete`, `load` becomes a tool for full config synchronization, which stopps deleted from config processes).
83
+
84
+
85
+ Process statuses:
86
+
87
+ $ eye i(nfo)
88
+
89
+ ```
90
+ test
91
+ samples
92
+ sample1 ....................... up (21:38, 0%, 15Mb, <4813>)
93
+ sample2 ....................... up (21:36, 0%, 14Mb, <4530>)
94
+ forking ......................... up (21:34, 0%, 19Mb, <4272>)
95
+ =child= ....................... up (21:34, 0%, 22Mb, <4275>)
96
+ =child= ....................... up (21:34, 0%, 21Mb, <4278>)
97
+ =child= ....................... up (21:34, 0%, 21Mb, <4281>)
98
+ ```
99
+
100
+ ### Commands:
101
+
102
+ start, stop, restart, delete, monitor, unmonitor
103
+
104
+ Command params (with restart for example):
105
+
106
+ $ eye r(estart) all
107
+ $ eye r test
108
+ $ eye r samples
109
+ $ eye r sample1
110
+ $ eye r sample*
111
+ $ eye r test:samples
112
+ $ eye r test:samples:sample1
113
+ $ eye r test:samples:sample*
114
+ $ eye r test:*sample*
115
+
116
+ Check config syntax:
117
+
118
+ $ eye c(heck) examples/test.eye
119
+
120
+ Log tracing:
121
+
122
+ $ eye trace
123
+ $ eye tr test
124
+ $ eye tr sample
125
+
126
+ Quit monitoring:
127
+
128
+ $ eye q(uit)
129
+
130
+ Config explain (for debug):
131
+
132
+ $ eye explain examples/test.eye
@@ -0,0 +1,18 @@
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)
7
+
8
+ task :env do
9
+ require 'bundler/setup'
10
+ require 'eye'
11
+ Eye::Control
12
+ Eye::Process # preload
13
+ end
14
+
15
+ desc "graph"
16
+ task :graph => :env do
17
+ StateMachine::Machine.draw("Eye::Process")
18
+ end
data/bin/eye ADDED
@@ -0,0 +1,282 @@
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
+ def xinfo
27
+ res = cmd(:xinfo, options[:config])
28
+ puts res if res && !res.empty?
29
+ puts
30
+ end
31
+
32
+ desc "oinfo", "onelined info"
33
+ def oinfo
34
+ res = cmd(:oinfo)
35
+ puts res if res && !res.empty?
36
+ puts
37
+ end
38
+
39
+ desc "load [CONF]", "load config (and start server if needed) (-f for foregraund start)"
40
+ method_option :foregraund, :type => :boolean, :aliases => "-f"
41
+ method_option :logger, :type => :string, :aliases => "-l"
42
+ def load(conf = "")
43
+ conf = File.expand_path(conf) if !conf.empty?
44
+
45
+ if options[:foregraund]
46
+ # in foregraund we stop another server, and run just 1 current config version
47
+ server_start_foregraund(conf)
48
+
49
+ elsif server_started?
50
+ say_load_result cmd(:load, conf)
51
+
52
+ else
53
+ server_start(conf)
54
+
55
+ end
56
+ end
57
+
58
+ desc "quit", "stop eye monitoring"
59
+ def quit
60
+ res = _cmd(:quit)
61
+
62
+ # if eye server got crazy, stop by force
63
+ ensure_stop_previous_server if res != :corrupred_marshal
64
+
65
+ say "stopped...", :yellow
66
+ end
67
+
68
+ [:start, :stop, :restart, :unmonitor, :monitor, :delete, :match].each do |_cmd|
69
+ desc "#{_cmd} MASK[,...]", "#{_cmd} app,group or process"
70
+ define_method(_cmd) do |*targets|
71
+ send_command(_cmd, *targets)
72
+ end
73
+ end
74
+
75
+ desc "signal SIG, MASK[,...]", "send signal to matched app,group or process (ex: `eye sig USR2 some_app`)"
76
+ def signal(sig, *targets)
77
+ send_command(:signal, sig, *targets)
78
+ end
79
+
80
+ desc "trace [TARGET]", "tracing log for app,group or process"
81
+ def trace(target = "")
82
+ log_trace(target)
83
+ end
84
+
85
+ desc "version", "show current version"
86
+ def version
87
+ say Eye::ABOUT
88
+ end
89
+
90
+ desc "check CONF", "check syntax of the config file"
91
+ method_option :host, :type => :string, :aliases => "-h"
92
+ method_option :verbose, :type => :boolean, :aliases => "-v"
93
+ def check(conf)
94
+ conf = File.expand_path(conf) if conf && !conf.empty?
95
+
96
+ Eye::System.host = options[:host] if options[:host]
97
+ Eye::Dsl.verbose = options[:verbose]
98
+
99
+ if RUBY_VERSION < '1.9'
100
+ say_load_result cmd(:check, conf), :syntax => true
101
+ else
102
+ say_load_result Eye::Control.check(conf), :syntax => true
103
+ end
104
+ end
105
+
106
+ desc "explain CONF", "explain config tree (for debug)"
107
+ method_option :host, :type => :string, :aliases => "-h"
108
+ method_option :verbose, :type => :boolean, :aliases => "-v"
109
+ def explain(conf)
110
+ conf = File.expand_path(conf) if conf && !conf.empty?
111
+
112
+ Eye::System.host = options[:host] if options[:host]
113
+ Eye::Dsl.verbose = options[:verbose]
114
+
115
+ if RUBY_VERSION < '1.9'
116
+ say_load_result cmd(:explain, conf), :print_config => true, :syntax => true
117
+ else
118
+ say_load_result Eye::Control.explain(conf), :print_config => true, :syntax => true
119
+ end
120
+ end
121
+
122
+ private
123
+
124
+ def client
125
+ @client ||= Eye::Client.new(Eye::Settings.socket_path)
126
+ end
127
+
128
+ def _cmd(cmd, *args)
129
+ client.command(cmd, *args)
130
+ rescue Errno::ECONNREFUSED, Errno::ENOENT
131
+ :not_started
132
+ end
133
+
134
+ def cmd(cmd, *args)
135
+ res = _cmd(cmd, *args)
136
+
137
+ if res == :not_started
138
+ say "eye monitoring not found, did you start it?", :red
139
+ exit 1
140
+ elsif res == :timeouted
141
+ say "eye does not answer, timeouted...", :red
142
+ exit 1
143
+ end
144
+
145
+ res
146
+ end
147
+
148
+ def server_started?
149
+ _cmd(:ping) == :pong
150
+ end
151
+
152
+ def say_load_result(res = {}, opts = {})
153
+ if res[:error]
154
+ say "config error: ", :red
155
+ say res[:message]
156
+
157
+ res[:backtrace].to_a.each{|line| say line}
158
+
159
+ exit 1
160
+ else
161
+ if opts[:started]
162
+ say "started and loaded!", :yellow if !res[:empty]
163
+ elsif opts[:syntax]
164
+ say "config ok!", :yellow if !res[:empty]
165
+ else
166
+ say "config loaded!", :yellow if !res[:empty]
167
+ end
168
+
169
+ if opts[:print_config]
170
+ require 'yaml'
171
+ puts YAML.dump(res[:config])
172
+ end
173
+ end
174
+ end
175
+
176
+ def send_command(_cmd, *args)
177
+ res = cmd(_cmd, *args)
178
+ if res == :unknown_command
179
+ say "unknown command :#{_cmd}", :red
180
+ elsif res == :corrupred_marshal
181
+ say "something crazy wrong, check eye logs!", :red
182
+ elsif res == []
183
+ say "command :#{_cmd}, targets not found!", :red
184
+ else
185
+ say "command :#{_cmd} sended to [#{res * ", "}]"
186
+ end
187
+ end
188
+
189
+ def log_trace(tag = '')
190
+ log_file = cmd(:logger_dev)
191
+ if log_file && File.exists?(log_file)
192
+ Process.exec "tail -n 100 -f #{log_file} | grep '#{tag}'"
193
+ else
194
+ say "log file not found #{log_file.inspect}", :red
195
+ end
196
+ end
197
+
198
+ def loader_path
199
+ Gem.bin_path('eye', 'loader_eye')
200
+ rescue Gem::GemNotFoundException, Gem::Exception
201
+ filename = File.expand_path(File.join(File.dirname(__FILE__), %w[loader_eye]))
202
+ File.exists?(filename) ? filename : nil
203
+ end
204
+
205
+ def ruby_path
206
+ require 'rbconfig'
207
+ RbConfig::CONFIG['bindir'] + "/ruby"
208
+ end
209
+
210
+ def ensure_loader_path
211
+ unless loader_path
212
+ say "start monitoring needs to run under ruby with installed gem 'eye'", :red
213
+ exit 1
214
+ end
215
+ end
216
+
217
+ def server_start_foregraund(conf = nil)
218
+ ensure_loader_path
219
+ Eye::Settings.ensure_eye_dir
220
+
221
+ if server_started?
222
+ _cmd(:quit) && sleep(1) # stop previous server
223
+ end
224
+
225
+ args = []
226
+ args += ['-c', conf] if conf
227
+ args += ['-l', 'stdout']
228
+
229
+ Process.exec(ruby_path, loader_path, *args)
230
+ end
231
+
232
+ def server_start(conf = nil)
233
+ ensure_loader_path
234
+ Eye::Settings.ensure_eye_dir
235
+
236
+ ensure_stop_previous_server
237
+
238
+ args = []
239
+ args += ['-l', options[:logger]] if options[:logger]
240
+
241
+ pid = Process.spawn(ruby_path, loader_path, *args, :out => '/dev/null', :err => '/dev/null', :in => '/dev/null',
242
+ :chdir => '/', :pgroup => true)
243
+ Process.detach(pid)
244
+ File.open(Eye::Settings.pid_path, 'w'){|f| f.write(pid) }
245
+
246
+ unless wait_server
247
+ say "server not runned in 15 seconds, something crazy wrong", :red
248
+ exit 1
249
+ end
250
+
251
+ if conf && !conf.empty?
252
+ say_load_result cmd(:load, conf), :started => true
253
+ else
254
+ say "started!", :yellow
255
+ end
256
+ end
257
+
258
+ def ensure_stop_previous_server
259
+ Eye::Settings.ensure_eye_dir
260
+ pid = File.read(Eye::Settings.pid_path).to_i rescue nil
261
+ if pid
262
+ Process.kill(9, pid) rescue nil
263
+ end
264
+ File.delete(Eye::Settings.pid_path) rescue nil
265
+ true
266
+ end
267
+
268
+ def wait_server
269
+ Timeout.timeout(15) do
270
+ while !server_started?
271
+ sleep 0.3
272
+ end
273
+ end
274
+
275
+ true
276
+ rescue Timeout::Error
277
+ false
278
+ end
279
+
280
+ end
281
+
282
+ Cli.start