eye 0.1.11
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.
- data/.gitignore +31 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +132 -0
- data/Rakefile +18 -0
- data/bin/eye +282 -0
- data/bin/loader_eye +56 -0
- data/examples/processes/em.rb +56 -0
- data/examples/processes/forking.rb +20 -0
- data/examples/processes/sample.rb +144 -0
- data/examples/rbenv.eye +11 -0
- data/examples/test.eye +65 -0
- data/examples/unicorn.eye +29 -0
- data/eye.gemspec +37 -0
- data/lib/eye.rb +25 -0
- data/lib/eye/application.rb +65 -0
- data/lib/eye/checker.rb +118 -0
- data/lib/eye/checker/cpu.rb +27 -0
- data/lib/eye/checker/file_ctime.rb +29 -0
- data/lib/eye/checker/file_size.rb +38 -0
- data/lib/eye/checker/http.rb +94 -0
- data/lib/eye/checker/memory.rb +27 -0
- data/lib/eye/checker/socket.rb +148 -0
- data/lib/eye/checker/validation.rb +49 -0
- data/lib/eye/child_process.rb +75 -0
- data/lib/eye/client.rb +32 -0
- data/lib/eye/control.rb +2 -0
- data/lib/eye/controller.rb +43 -0
- data/lib/eye/controller/commands.rb +64 -0
- data/lib/eye/controller/helpers.rb +61 -0
- data/lib/eye/controller/load.rb +224 -0
- data/lib/eye/controller/send_command.rb +88 -0
- data/lib/eye/controller/status.rb +136 -0
- data/lib/eye/dsl.rb +52 -0
- data/lib/eye/dsl/application_opts.rb +33 -0
- data/lib/eye/dsl/chain.rb +12 -0
- data/lib/eye/dsl/child_process_opts.rb +7 -0
- data/lib/eye/dsl/config_opts.rb +11 -0
- data/lib/eye/dsl/group_opts.rb +27 -0
- data/lib/eye/dsl/helpers.rb +12 -0
- data/lib/eye/dsl/main.rb +58 -0
- data/lib/eye/dsl/opts.rb +88 -0
- data/lib/eye/dsl/process_opts.rb +21 -0
- data/lib/eye/dsl/pure_opts.rb +132 -0
- data/lib/eye/dsl/validate.rb +41 -0
- data/lib/eye/group.rb +125 -0
- data/lib/eye/group/chain.rb +68 -0
- data/lib/eye/io/unix_server.rb +44 -0
- data/lib/eye/io/unix_socket.rb +39 -0
- data/lib/eye/loader.rb +13 -0
- data/lib/eye/logger.rb +80 -0
- data/lib/eye/process.rb +83 -0
- data/lib/eye/process/child.rb +61 -0
- data/lib/eye/process/commands.rb +256 -0
- data/lib/eye/process/config.rb +70 -0
- data/lib/eye/process/controller.rb +72 -0
- data/lib/eye/process/data.rb +46 -0
- data/lib/eye/process/monitor.rb +97 -0
- data/lib/eye/process/notify.rb +17 -0
- data/lib/eye/process/scheduler.rb +50 -0
- data/lib/eye/process/states.rb +92 -0
- data/lib/eye/process/states_history.rb +62 -0
- data/lib/eye/process/system.rb +60 -0
- data/lib/eye/process/trigger.rb +32 -0
- data/lib/eye/process/watchers.rb +67 -0
- data/lib/eye/server.rb +51 -0
- data/lib/eye/settings.rb +35 -0
- data/lib/eye/system.rb +145 -0
- data/lib/eye/system_resources.rb +83 -0
- data/lib/eye/trigger.rb +53 -0
- data/lib/eye/trigger/flapping.rb +24 -0
- data/lib/eye/utils.rb +5 -0
- data/lib/eye/utils/alive_array.rb +31 -0
- data/lib/eye/utils/celluloid_chain.rb +51 -0
- data/lib/eye/utils/leak_19.rb +7 -0
- data/lib/eye/utils/tail.rb +20 -0
- data/spec/checker/cpu_spec.rb +58 -0
- data/spec/checker/file_ctime_spec.rb +34 -0
- data/spec/checker/file_size_spec.rb +107 -0
- data/spec/checker/http_spec.rb +109 -0
- data/spec/checker/memory_spec.rb +64 -0
- data/spec/checker/socket_spec.rb +116 -0
- data/spec/checker_spec.rb +188 -0
- data/spec/child_process/child_process_spec.rb +46 -0
- data/spec/client_server_spec.rb +34 -0
- data/spec/controller/commands_spec.rb +92 -0
- data/spec/controller/controller_spec.rb +133 -0
- data/spec/controller/find_objects_spec.rb +150 -0
- data/spec/controller/group_spec.rb +110 -0
- data/spec/controller/intergration_spec.rb +327 -0
- data/spec/controller/load_spec.rb +326 -0
- data/spec/controller/races_spec.rb +70 -0
- data/spec/controller/stop_on_delete_spec.rb +157 -0
- data/spec/dsl/chain_spec.rb +140 -0
- data/spec/dsl/checks_spec.rb +202 -0
- data/spec/dsl/config_spec.rb +44 -0
- data/spec/dsl/dsl_spec.rb +73 -0
- data/spec/dsl/getter_spec.rb +223 -0
- data/spec/dsl/integration_spec.rb +311 -0
- data/spec/dsl/load_spec.rb +52 -0
- data/spec/dsl/process_spec.rb +330 -0
- data/spec/dsl/sub_procs_spec.rb +93 -0
- data/spec/dsl/with_server_spec.rb +104 -0
- data/spec/example/em.rb +57 -0
- data/spec/example/forking.rb +20 -0
- data/spec/example/sample.rb +154 -0
- data/spec/fixtures/dsl/0.rb +8 -0
- data/spec/fixtures/dsl/0a.rb +8 -0
- data/spec/fixtures/dsl/0c.rb +8 -0
- data/spec/fixtures/dsl/1.rb +5 -0
- data/spec/fixtures/dsl/bad.eye +6 -0
- data/spec/fixtures/dsl/configs/1.eye +3 -0
- data/spec/fixtures/dsl/configs/2.eye +1 -0
- data/spec/fixtures/dsl/configs/3.eye +1 -0
- data/spec/fixtures/dsl/configs/4.eye +3 -0
- data/spec/fixtures/dsl/empty.eye +20 -0
- data/spec/fixtures/dsl/include_test.eye +5 -0
- data/spec/fixtures/dsl/include_test/1.rb +6 -0
- data/spec/fixtures/dsl/include_test/ha.rb +4 -0
- data/spec/fixtures/dsl/include_test2.eye +5 -0
- data/spec/fixtures/dsl/integration.eye +30 -0
- data/spec/fixtures/dsl/integration2.eye +32 -0
- data/spec/fixtures/dsl/integration_locks.eye +30 -0
- data/spec/fixtures/dsl/integration_sor.eye +32 -0
- data/spec/fixtures/dsl/integration_sor2.eye +27 -0
- data/spec/fixtures/dsl/integration_sor3.eye +32 -0
- data/spec/fixtures/dsl/load.eye +25 -0
- data/spec/fixtures/dsl/load2.eye +7 -0
- data/spec/fixtures/dsl/load2_dup2.eye +13 -0
- data/spec/fixtures/dsl/load2_dup_pid.eye +7 -0
- data/spec/fixtures/dsl/load3.eye +10 -0
- data/spec/fixtures/dsl/load4.eye +7 -0
- data/spec/fixtures/dsl/load5.eye +8 -0
- data/spec/fixtures/dsl/load6.eye +17 -0
- data/spec/fixtures/dsl/load_dubls.eye +36 -0
- data/spec/fixtures/dsl/load_dup_ex_names.eye +15 -0
- data/spec/fixtures/dsl/load_error.eye +5 -0
- data/spec/fixtures/dsl/load_error_folder/load3.eye +10 -0
- data/spec/fixtures/dsl/load_error_folder/load4.eye +7 -0
- data/spec/fixtures/dsl/load_folder/load3.eye +10 -0
- data/spec/fixtures/dsl/load_folder/load4.eye +7 -0
- data/spec/fixtures/dsl/load_int.eye +8 -0
- data/spec/fixtures/dsl/load_int2.eye +13 -0
- data/spec/fixtures/dsl/load_logger.eye +26 -0
- data/spec/fixtures/dsl/load_logger2.eye +3 -0
- data/spec/fixtures/dsl/long_load.eye +5 -0
- data/spec/fixtures/dsl/subfolder1/proc1.rb +3 -0
- data/spec/fixtures/dsl/subfolder2.eye +9 -0
- data/spec/fixtures/dsl/subfolder2/common.rb +1 -0
- data/spec/fixtures/dsl/subfolder2/proc2.rb +3 -0
- data/spec/fixtures/dsl/subfolder2/sub/proc3.rb +6 -0
- data/spec/fixtures/dsl/subfolder3.eye +8 -0
- data/spec/fixtures/dsl/subfolder3/common.rb +1 -0
- data/spec/fixtures/dsl/subfolder3/proc4.rb +3 -0
- data/spec/fixtures/dsl/subfolder3/sub/proc5.rb +6 -0
- data/spec/fixtures/dsl/subfolder4.eye +6 -0
- data/spec/fixtures/dsl/subfolder4/a.rb +2 -0
- data/spec/fixtures/dsl/subfolder4/b.rb +1 -0
- data/spec/fixtures/dsl/subfolder4/c.rb +1 -0
- data/spec/mock_spec.rb +32 -0
- data/spec/process/checks/child_checks_spec.rb +79 -0
- data/spec/process/checks/cpu_spec.rb +114 -0
- data/spec/process/checks/ctime_spec.rb +43 -0
- data/spec/process/checks/fsize_spec.rb +22 -0
- data/spec/process/checks/http_spec.rb +52 -0
- data/spec/process/checks/intergration_spec.rb +32 -0
- data/spec/process/checks/memory_spec.rb +113 -0
- data/spec/process/child_process_spec.rb +125 -0
- data/spec/process/config_spec.rb +75 -0
- data/spec/process/controller_spec.rb +173 -0
- data/spec/process/monitoring_spec.rb +180 -0
- data/spec/process/restart_spec.rb +174 -0
- data/spec/process/scheduler_spec.rb +150 -0
- data/spec/process/start_spec.rb +261 -0
- data/spec/process/states_history_spec.rb +118 -0
- data/spec/process/stop_spec.rb +150 -0
- data/spec/process/system_spec.rb +100 -0
- data/spec/process/triggers/flapping_spec.rb +81 -0
- data/spec/process/update_config_spec.rb +63 -0
- data/spec/spec_helper.rb +120 -0
- data/spec/support/rr_celluloid.rb +36 -0
- data/spec/support/scheduler_hack.rb +16 -0
- data/spec/support/spec_support.rb +164 -0
- data/spec/system_resources_spec.rb +59 -0
- data/spec/system_spec.rb +170 -0
- data/spec/utils/alive_array_spec.rb +50 -0
- data/spec/utils/celluloid_chain_spec.rb +82 -0
- data/spec/utils/tail_spec.rb +21 -0
- 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
|
data/lib/eye/client.rb
ADDED
@@ -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
|
data/lib/eye/control.rb
ADDED
@@ -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
|