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,49 @@
1
+ module Eye::Checker::Validation
2
+ class Error < Exception; end
3
+
4
+ def inherited(subclass)
5
+ subclass.validates = self.validates.clone
6
+ subclass.should_bes = self.should_bes.clone
7
+ subclass.defaults = self.defaults.clone
8
+ end
9
+
10
+ attr_accessor :validates, :should_bes, :defaults
11
+
12
+ def validates; @validates ||= {}; end
13
+ def should_bes; @should_bes ||= []; end
14
+ def defaults; @defaults ||= {}; end
15
+
16
+ def param(param, types = [], should_be = false, default = nil)
17
+ param = param.to_sym
18
+
19
+ validates[param] = types
20
+ should_bes << param if should_be
21
+ defaults[param] = default
22
+
23
+ define_method "#{param}" do
24
+ @options[param.to_sym] || default
25
+ end
26
+ end
27
+
28
+ def validate(options = {})
29
+ options.each do |param, value|
30
+ types = validates[param.to_sym]
31
+ unless types
32
+ if param.to_sym != :type
33
+ raise Error, "#{self.name} unknown param :#{param} value #{value.inspect}"
34
+ end
35
+ end
36
+
37
+ next if types.blank?
38
+
39
+ types = Array(types)
40
+ good = types.any?{|type| value.is_a?(type) }
41
+ raise Error, "#{self.name} bad param :#{param} value #{value.inspect}, type #{types.inspect}" unless good
42
+ end
43
+
44
+ should_bes.each do |param|
45
+ raise Error, "#{self.name} bad param :#{param}, value should be" unless options[param.to_sym] || defaults[param.to_sym]
46
+ end
47
+ end
48
+
49
+ end
@@ -0,0 +1,75 @@
1
+ require 'celluloid'
2
+
3
+ class Eye::ChildProcess
4
+ include Celluloid
5
+
6
+ # needs: kill_process
7
+ include Eye::Process::Commands
8
+
9
+ # easy config + defaults: prepare_config, c, []
10
+ include Eye::Process::Config
11
+
12
+ # conditional watchers: start_checkers
13
+ include Eye::Process::Watchers
14
+
15
+ # system methods: send_signal
16
+ include Eye::Process::System
17
+
18
+ # logger methods: info, ...
19
+ include Eye::Logger::Helpers
20
+
21
+ # self_status_data
22
+ include Eye::Process::Data
23
+
24
+ # manage notify methods
25
+ include Eye::Process::Notify
26
+
27
+ # scheduler
28
+ include Eye::Process::Scheduler
29
+
30
+ attr_reader :pid, :name, :config, :watchers
31
+
32
+ def initialize(pid, config = {}, logger_prefix = nil)
33
+ raise 'Empty pid' unless pid
34
+
35
+ @pid = pid
36
+ @config = prepare_config(config)
37
+ @name = '=child='
38
+
39
+ @logger = Eye::Logger.new("#{logger_prefix} child:#{pid}")
40
+
41
+ @watchers = {}
42
+
43
+ debug "start monitoring CHILD config: #{@config.inspect}"
44
+
45
+ start_checkers
46
+ end
47
+
48
+ def state
49
+ :up
50
+ end
51
+
52
+ def stop
53
+ kill_process
54
+ end
55
+
56
+ def restart
57
+ stop
58
+ end
59
+
60
+ def monitor
61
+ end
62
+
63
+ def unmonitor
64
+ end
65
+
66
+ def delete
67
+ remove_watchers
68
+ terminate
69
+ end
70
+
71
+ def status_data(debug = false)
72
+ self_status_data(debug)
73
+ end
74
+
75
+ end
@@ -0,0 +1,32 @@
1
+ require 'socket'
2
+ require 'timeout'
3
+
4
+ class Eye::Client
5
+ attr_reader :socket_path
6
+
7
+ def initialize(socket_path)
8
+ @socket_path = socket_path
9
+ end
10
+
11
+ def command(cmd, *args)
12
+ attempt_command([cmd, *args] * '|')
13
+ end
14
+
15
+ def attempt_command(pack)
16
+ Timeout.timeout(Eye::Settings.client_timeout) do
17
+ return send_request(pack)
18
+ end
19
+
20
+ rescue Timeout::Error, EOFError
21
+ :timeouted
22
+ end
23
+
24
+ def send_request(pack)
25
+ UNIXSocket.open(@socket_path) do |socket|
26
+ socket.puts(pack)
27
+ data = socket.read
28
+ res = Marshal.load(data) rescue :corrupred_marshal
29
+ end
30
+ end
31
+
32
+ end
@@ -0,0 +1,2 @@
1
+ # controller global singlton
2
+ Eye::Control = Eye::Controller.new
@@ -0,0 +1,43 @@
1
+ require 'celluloid'
2
+
3
+ require 'yaml'
4
+ require 'active_support'
5
+ require 'active_support/core_ext/object/blank'
6
+ require 'active_support/core_ext/object/try'
7
+ require 'active_support/core_ext/numeric'
8
+ require 'active_support/core_ext/string/filters'
9
+
10
+ require_relative 'utils/leak_19'
11
+
12
+ Eye.send(:extend, Eye::Logger::Helpers)
13
+
14
+ class Eye::Controller
15
+ include Celluloid
16
+
17
+ autoload :Load, 'eye/controller/load'
18
+ autoload :Helpers, 'eye/controller/helpers'
19
+ autoload :Commands, 'eye/controller/commands'
20
+ autoload :Status, 'eye/controller/status'
21
+ autoload :SendCommand, 'eye/controller/send_command'
22
+
23
+ include Eye::Logger::Helpers
24
+ include Eye::Controller::Load
25
+ include Eye::Controller::Helpers
26
+ include Eye::Controller::Commands
27
+ include Eye::Controller::Status
28
+ include Eye::Controller::SendCommand
29
+
30
+ attr_reader :applications, :current_config
31
+
32
+ def initialize
33
+ @applications = []
34
+ @current_config = Eye::Dsl.initial_config
35
+
36
+ Eye.instance_variable_set(:@logger, Eye::Logger.new('eye'))
37
+ @logger = Eye.logger
38
+ Celluloid::logger = Eye.logger
39
+
40
+ Eye::SystemResources.setup
41
+ end
42
+
43
+ end
@@ -0,0 +1,64 @@
1
+ module Eye::Controller::Commands
2
+
3
+ # Main method, answer for the client command
4
+ def command(cmd, *args)
5
+ debug "client command: #{cmd} #{args * ', '}"
6
+
7
+ start_at = Time.now
8
+ cmd = cmd.to_sym
9
+
10
+ res = case cmd
11
+ when :start, :stop, :restart, :unmonitor, :monitor
12
+ send_command(cmd, *args)
13
+ when :delete
14
+ exclusive{ send_command(cmd, *args) }
15
+ when :signal
16
+ signal(*args)
17
+ when :load
18
+ exclusive{ load(*args) }
19
+ when :info
20
+ info_string(*args)
21
+ when :object_info
22
+ info_data(*args)
23
+ when :xinfo
24
+ info_string_debug(*args)
25
+ when :oinfo
26
+ info_string_short
27
+ when :quit
28
+ quit
29
+ when :check
30
+ check(*args)
31
+ when :explain
32
+ explain(*args)
33
+ when :match
34
+ match(*args)
35
+ when :ping
36
+ :pong
37
+ when :logger_dev
38
+ Eye::Logger.dev
39
+ else
40
+ :unknown_command
41
+ end
42
+
43
+ GC.start
44
+ info "client command: #{cmd} #{args * ', '} (#{Time.now - start_at}s)"
45
+
46
+ res
47
+ end
48
+
49
+ private
50
+
51
+ def quit
52
+ info 'exiting...'
53
+ delete
54
+ sleep 1
55
+ Eye::System.send_signal($$) # soft terminate
56
+ sleep 2
57
+ Eye::System.send_signal($$, 9)
58
+ end
59
+
60
+ def delete
61
+ send_command(:delete)
62
+ end
63
+
64
+ end
@@ -0,0 +1,61 @@
1
+ module Eye::Controller::Helpers
2
+
3
+ def set_proc_line
4
+ str = "eye monitoring v#{Eye::VERSION}"
5
+ str += " (#{@applications.map(&:name) * ', '})" if @applications.present?
6
+ $0 = str
7
+ end
8
+
9
+ def process_by_name(name)
10
+ all_processes.detect{|c| c.name == name}
11
+ end
12
+
13
+ def group_by_name(name)
14
+ all_groups.detect{|c| c.name == name}
15
+ end
16
+
17
+ def application_by_name(name)
18
+ @applications.detect{|c| c.name == name}
19
+ end
20
+
21
+ def all_processes
22
+ processes = []
23
+ all_groups.each do |gr|
24
+ processes += gr.processes.to_a
25
+ end
26
+
27
+ processes
28
+ end
29
+
30
+ def all_groups
31
+ groups = []
32
+ @applications.each do |app|
33
+ groups += app.groups.to_a
34
+ end
35
+
36
+ groups
37
+ end
38
+
39
+ # {'app_name' => {'group_name' => {'process_name' => 'pid_file'}}}
40
+ def short_tree
41
+ res = {}
42
+ @applications.each do |app|
43
+ res2 = {}
44
+
45
+ app.groups.each do |group|
46
+ res3 = {}
47
+
48
+ group.processes.each do |process|
49
+ res3[process.name] = process[:pid_file_ex]
50
+ end
51
+
52
+ res2[group.name] = res3
53
+ end
54
+
55
+ res[app.name] = res2
56
+ end
57
+
58
+ res
59
+ end
60
+
61
+ end
@@ -0,0 +1,224 @@
1
+ module Eye::Controller::Load
2
+ include Eye::Dsl::Validate
3
+
4
+ def check(filename = '')
5
+ catch_load_error(filename) do
6
+ parse_config(filename)
7
+ end
8
+ end
9
+
10
+ def explain(filename)
11
+ catch_load_error(filename) do
12
+ parse_set_of_configs(filename)
13
+ end
14
+ end
15
+
16
+ # filename is a path, or folder, or mask
17
+ def load(filename = '')
18
+ catch_load_error(filename) do
19
+ _load(filename)
20
+ set_proc_line
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ # regexp for clean backtrace to show for user
27
+ BT_REGX = %r[/lib/eye/|lib/celluloid|internal:prelude|logger.rb:].freeze
28
+
29
+ def catch_load_error(filename, &block)
30
+ res = block.call
31
+
32
+ {:error => false, :config => res}
33
+ rescue Eye::Dsl::Error, Exception, NoMethodError => ex
34
+ error "load: config error <#{filename}>: #{ex.message}"
35
+
36
+ # filter backtrace for user output
37
+ bt = (ex.backtrace || []).reject{|line| line.to_s =~ BT_REGX }
38
+ error bt.join("\n")
39
+
40
+ res = {:error => true, :message => ex.message}
41
+ res.merge!(:backtrace => bt) if bt.present?
42
+ res
43
+ end
44
+
45
+ # return: result, config
46
+ def parse_config(filename = '', &block)
47
+ raise Eye::Dsl::Error, "config file '#{filename}' not found!" unless File.exists?(filename)
48
+
49
+ cfg = Eye::Dsl.parse(nil, filename)
50
+ validate( merge_configs(@current_config, cfg) )
51
+
52
+ cfg
53
+ end
54
+
55
+ def parse_set_of_configs(filename)
56
+ mask = if File.directory?(filename)
57
+ File.join filename, '{*.eye}'
58
+ else
59
+ filename
60
+ end
61
+
62
+ debug "load: globbing mask #{mask}"
63
+ configs = []
64
+
65
+ Dir[mask].each do |config_path|
66
+ info "load: config #{config_path}"
67
+ configs << parse_config(config_path)
68
+ end
69
+
70
+ raise Eye::Dsl::Error, "config file '#{mask}' not found!" if configs.blank?
71
+
72
+ new_cfg = @current_config
73
+ configs.each do |cfg|
74
+ new_cfg = merge_configs(new_cfg, cfg)
75
+ end
76
+
77
+ validate(new_cfg)
78
+
79
+ new_cfg
80
+ end
81
+
82
+ def _load(filename)
83
+ new_cfg = parse_set_of_configs(filename)
84
+
85
+ load_config(new_cfg)
86
+
87
+ GC.start
88
+ end
89
+
90
+ def load_config(new_config)
91
+ load_options(new_config[:config])
92
+ create_objects(new_config[:applications])
93
+ @current_config = new_config
94
+ end
95
+
96
+ def merge_configs(old_config, new_config)
97
+ {:config => old_config[:config].merge(new_config[:config]),
98
+ :applications => old_config[:applications].merge(new_config[:applications])}
99
+ end
100
+
101
+ # load global config options
102
+ def load_options(opts)
103
+ return if opts.blank?
104
+
105
+ if opts[:logger]
106
+ # do not apply logger, if in stdout state
107
+ if !%w{stdout stderr}.include?(Eye::Logger.dev)
108
+ if opts[:logger].blank?
109
+ Eye::Logger.link_logger(nil)
110
+ else
111
+ Eye::Logger.link_logger(opts[:logger])
112
+ end
113
+ end
114
+
115
+ Eye::Logger.log_level = opts[:logger_level] if opts[:logger_level]
116
+ end
117
+ end
118
+
119
+ # create objects as diff, from configs
120
+ def create_objects(apps_config)
121
+ debug 'create objects'
122
+ apps_config.each do |app_name, app_cfg|
123
+ update_or_create_application(app_name, app_cfg.clone)
124
+ end
125
+
126
+ # sorting applications
127
+ @applications.sort_by!(&:name)
128
+ end
129
+
130
+ def update_or_create_application(app_name, app_config)
131
+ @old_groups = {}
132
+ @old_processes = {}
133
+
134
+ app = @applications.detect{|c| c.name == app_name}
135
+
136
+ if app
137
+ app.groups.each do |group|
138
+ @old_groups[group.name] = group
139
+ group.processes.each do |proc|
140
+ @old_processes[proc.name] = proc
141
+ end
142
+ end
143
+
144
+ @applications.delete(app)
145
+
146
+ debug "update app #{app_name}"
147
+ else
148
+ debug "create app #{app_name}"
149
+ end
150
+
151
+ app = Eye::Application.new(app_name, app_config)
152
+ @applications << app
153
+ @added_groups, @added_processes = [], []
154
+
155
+ new_groups = app_config.delete(:groups) || {}
156
+ new_groups.each do |group_name, group_cfg|
157
+ group = update_or_create_group(group_name, group_cfg.clone)
158
+ app.add_group(group)
159
+ group.resort_processes
160
+ end
161
+
162
+ # now, need to clear @old_groups, and @old_processes
163
+ @old_groups.each{|_, group| group.clear; group.send_command(:delete) }
164
+ @old_processes.each{|_, process| process.send_command(:delete) if process.alive? }
165
+
166
+ # schedule monitoring for new groups, processes
167
+ added_fully_groups = []
168
+ @added_groups.each do |group|
169
+ if group.processes.size > 0 && (group.processes.pure - @added_processes).size == 0
170
+ added_fully_groups << group
171
+ @added_processes -= group.processes.pure
172
+ end
173
+ end
174
+
175
+ added_fully_groups.each{|group| group.send_command :monitor }
176
+ @added_processes.each{|process| process.send_command :monitor }
177
+
178
+ # remove links to prevent memory leaks
179
+ @old_groups = nil
180
+ @old_processes = nil
181
+ @added_groups = nil
182
+ @added_processes = nil
183
+
184
+ app
185
+ end
186
+
187
+ def update_or_create_group(group_name, group_config)
188
+ group = if @old_groups[group_name]
189
+ debug "update group #{group_name}"
190
+ group = @old_groups.delete(group_name)
191
+ group.schedule :update_config, group_config, 'load config'
192
+ group.clear
193
+ group
194
+ else
195
+ debug "create group #{group_name}"
196
+ gr = Eye::Group.new(group_name, group_config)
197
+ @added_groups << gr
198
+ gr
199
+ end
200
+
201
+ processes = group_config.delete(:processes) || {}
202
+ processes.each do |process_name, process_cfg|
203
+ process = update_or_create_process(process_name, process_cfg.clone)
204
+ group.add_process(process)
205
+ end
206
+
207
+ group
208
+ end
209
+
210
+ def update_or_create_process(process_name, process_cfg)
211
+ if @old_processes[process_name]
212
+ debug "update process #{process_name}"
213
+ process = @old_processes.delete(process_name)
214
+ process.schedule :update_config, process_cfg, 'load config'
215
+ process
216
+ else
217
+ debug "create process #{process_name}"
218
+ process = Eye::Process.new(process_cfg)
219
+ @added_processes << process
220
+ process
221
+ end
222
+ end
223
+
224
+ end