eye 0.7 → 0.8.celluloid15
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +141 -0
- data/.travis.yml +5 -3
- data/CHANGES.md +9 -1
- data/README.md +5 -2
- data/Rakefile +6 -6
- data/bin/leye +9 -4
- data/bin/loader_eye +14 -15
- data/examples/custom_check.eye +24 -0
- data/examples/custom_trigger.eye +30 -0
- data/examples/delayed_job.eye +3 -3
- data/examples/dependency.eye +10 -11
- data/examples/leye_example/Eyefile +10 -0
- data/examples/notify.eye +3 -4
- data/examples/plugin/main.eye +5 -5
- data/examples/plugin/plugin.rb +10 -2
- data/examples/process_thin.rb +8 -8
- data/examples/processes/em.rb +18 -12
- data/examples/processes/forking.rb +5 -5
- data/examples/processes/sample.rb +46 -44
- data/examples/puma.eye +9 -8
- data/examples/rbenv.eye +5 -5
- data/examples/sidekiq.eye +3 -3
- data/examples/stress_test.eye +4 -4
- data/examples/syslog.eye +1 -1
- data/examples/test.eye +1 -2
- data/examples/thin-farm.eye +7 -8
- data/examples/triggers.eye +13 -15
- data/examples/unicorn.eye +12 -13
- data/eye.gemspec +16 -14
- data/lib/eye.rb +2 -3
- data/lib/eye/application.rb +5 -6
- data/lib/eye/checker.rb +44 -25
- data/lib/eye/checker/children_count.rb +1 -1
- data/lib/eye/checker/file_ctime.rb +1 -1
- data/lib/eye/checker/http.rb +13 -15
- data/lib/eye/checker/nop.rb +1 -0
- data/lib/eye/checker/socket.rb +60 -63
- data/lib/eye/checker/ssl_socket.rb +5 -5
- data/lib/eye/child_process.rb +6 -4
- data/lib/eye/cli.rb +74 -46
- data/lib/eye/cli/commands.rb +4 -5
- data/lib/eye/cli/render.rb +61 -41
- data/lib/eye/cli/server.rb +19 -16
- data/lib/eye/client.rb +1 -0
- data/lib/eye/config.rb +36 -33
- data/lib/eye/controller.rb +2 -3
- data/lib/eye/controller/commands.rb +1 -1
- data/lib/eye/controller/helpers.rb +2 -2
- data/lib/eye/controller/load.rb +19 -17
- data/lib/eye/controller/options.rb +1 -5
- data/lib/eye/controller/send_command.rb +21 -23
- data/lib/eye/controller/status.rb +17 -14
- data/lib/eye/dsl.rb +6 -1
- data/lib/eye/dsl/application_opts.rb +4 -3
- data/lib/eye/dsl/chain.rb +2 -2
- data/lib/eye/dsl/child_process_opts.rb +3 -3
- data/lib/eye/dsl/config_opts.rb +7 -7
- data/lib/eye/dsl/group_opts.rb +3 -3
- data/lib/eye/dsl/helpers.rb +1 -1
- data/lib/eye/dsl/main.rb +4 -3
- data/lib/eye/dsl/opts.rb +31 -28
- data/lib/eye/dsl/process_opts.rb +13 -7
- data/lib/eye/dsl/pure_opts.rb +13 -9
- data/lib/eye/dsl/validation.rb +48 -35
- data/lib/eye/group.rb +23 -8
- data/lib/eye/group/chain.rb +6 -6
- data/lib/eye/loader.rb +3 -3
- data/lib/eye/local.rb +9 -4
- data/lib/eye/logger.rb +11 -4
- data/lib/eye/notify.rb +10 -6
- data/lib/eye/notify/jabber.rb +1 -1
- data/lib/eye/notify/mail.rb +2 -2
- data/lib/eye/notify/slack.rb +4 -3
- data/lib/eye/process.rb +2 -0
- data/lib/eye/process/children.rb +4 -4
- data/lib/eye/process/commands.rb +38 -39
- data/lib/eye/process/config.rb +22 -16
- data/lib/eye/process/controller.rb +5 -19
- data/lib/eye/process/data.rb +11 -9
- data/lib/eye/process/monitor.rb +86 -76
- data/lib/eye/process/notify.rb +10 -10
- data/lib/eye/process/scheduler.rb +36 -31
- data/lib/eye/process/states.rb +7 -5
- data/lib/eye/process/states_history.rb +9 -3
- data/lib/eye/process/system.rb +35 -20
- data/lib/eye/process/trigger.rb +1 -5
- data/lib/eye/process/watchers.rb +12 -9
- data/lib/eye/reason.rb +4 -1
- data/lib/eye/server.rb +3 -2
- data/lib/eye/system.rb +22 -15
- data/lib/eye/system_resources.rb +17 -8
- data/lib/eye/trigger.rb +18 -16
- data/lib/eye/trigger/check_dependency.rb +7 -4
- data/lib/eye/trigger/flapping.rb +24 -7
- data/lib/eye/trigger/starting_guard.rb +7 -6
- data/lib/eye/trigger/stop_children.rb +2 -2
- data/lib/eye/trigger/transition.rb +1 -1
- data/lib/eye/trigger/wait_dependency.rb +3 -2
- data/lib/eye/utils.rb +4 -3
- data/lib/eye/utils/alive_array.rb +9 -4
- data/lib/eye/utils/celluloid_chain.rb +12 -10
- data/lib/eye/utils/mini_active_support.rb +16 -16
- data/lib/eye/utils/pmap.rb +2 -0
- data/lib/eye/utils/tail.rb +2 -2
- metadata +39 -8
- data/lib/eye/utils/leak_19.rb +0 -10
data/lib/eye/cli/commands.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
module Eye::Cli::Commands
|
2
|
+
|
2
3
|
private
|
3
4
|
|
4
5
|
def client
|
@@ -39,12 +40,10 @@ private
|
|
39
40
|
def show_load_message(res, opts = {})
|
40
41
|
if res[:error]
|
41
42
|
say res[:message], :red
|
42
|
-
res[:backtrace].to_a.each{|line| say line, :red }
|
43
|
+
res[:backtrace].to_a.each { |line| say line, :red }
|
43
44
|
else
|
44
|
-
|
45
|
-
say 'Config ok!'
|
46
|
-
else
|
47
|
-
say 'Config loaded!', :green if !res[:empty]
|
45
|
+
unless res[:empty]
|
46
|
+
say(opts[:syntax] ? 'Config ok!' : 'Config loaded!', :green)
|
48
47
|
end
|
49
48
|
|
50
49
|
if opts[:print_config]
|
data/lib/eye/cli/render.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
module Eye::Cli::Render
|
2
|
+
|
2
3
|
private
|
4
|
+
|
3
5
|
def render_status(data)
|
4
6
|
return [1, "unexpected server response #{data.inspect}"] unless data.is_a?(Hash)
|
5
7
|
data = data[:subtree]
|
6
|
-
return [1, "match #{data.size} objects (#{data.map{|d| d[:name]}}), but expected only 1 process"] if data.size != 1
|
8
|
+
return [1, "match #{data.size} objects (#{data.map { |d| d[:name] }}), but expected only 1 process"] if data.size != 1
|
7
9
|
process = data[0]
|
8
10
|
return [1, "unknown status for :#{process[:type]}=#{process[:name]}"] unless process[:type] == :process
|
9
11
|
|
@@ -24,37 +26,14 @@ private
|
|
24
26
|
return nil if !data || data.empty?
|
25
27
|
|
26
28
|
if data.is_a?(Array)
|
27
|
-
data.map{|el| make_str(el, level) }.compact * "\n"
|
29
|
+
data.map { |el| make_str(el, level) }.compact * "\n"
|
28
30
|
else
|
29
31
|
str = nil
|
30
32
|
|
31
33
|
if data[:name]
|
32
34
|
return make_str(data[:subtree], level) if data[:name] == '__default__'
|
33
35
|
|
34
|
-
|
35
|
-
off_str = ' ' * off
|
36
|
-
|
37
|
-
short_state = ((data[:type] == :application || data[:type] == :group) && data[:states])
|
38
|
-
is_text = data[:state] || data[:states]
|
39
|
-
|
40
|
-
name = (data[:type] == :application && !is_text) ? "\033[1m#{data[:name]}\033[0m" : data[:name].to_s
|
41
|
-
off_len = 35
|
42
|
-
str = off_str + (name + ' ').ljust(off_len - off, is_text ? '.' : ' ')
|
43
|
-
|
44
|
-
if short_state
|
45
|
-
str += ' ' + data[:states].map { |k, v| "#{k}:#{v}" }.join(', ')
|
46
|
-
elsif data[:state]
|
47
|
-
str += ' ' + data[:state].to_s
|
48
|
-
str += ' (' + resources_str(data[:resources]) + ')' if data[:resources] && data[:state].to_sym == :up
|
49
|
-
str += " (#{data[:state_reason]} at #{Eye::Utils.human_time2(data[:state_changed_at])})" if data[:state_reason] && data[:state] == 'unmonitored'
|
50
|
-
elsif data[:current_command]
|
51
|
-
chain_progress = if data[:chain_progress]
|
52
|
-
" #{data[:chain_progress][0]} of #{data[:chain_progress][1]}" rescue ''
|
53
|
-
end
|
54
|
-
str += " \e[1;33m[#{data[:current_command]}#{chain_progress}]\033[0m"
|
55
|
-
str += " (#{data[:chain_commands] * ', '})" if data[:chain_commands]
|
56
|
-
end
|
57
|
-
|
36
|
+
str = render_element(data, level)
|
58
37
|
end
|
59
38
|
|
60
39
|
if data[:subtree].nil?
|
@@ -67,18 +46,10 @@ private
|
|
67
46
|
end
|
68
47
|
end
|
69
48
|
|
70
|
-
def resources_str(r)
|
71
|
-
return '' if !r || r.empty?
|
72
|
-
memory, cpu, start_time, pid = r[:memory], r[:cpu], r[:start_time], r[:pid]
|
73
|
-
return '' unless memory && cpu && start_time
|
74
|
-
|
75
|
-
"#{Eye::Utils.human_time(start_time)}, #{cpu.to_i}%, #{memory / 1024 / 1024}Mb, <#{pid}>"
|
76
|
-
end
|
77
|
-
|
78
49
|
def render_debug_info(data)
|
79
50
|
error!("unexpected server response #{data.inspect}") unless data.is_a?(Hash)
|
80
51
|
|
81
|
-
s =
|
52
|
+
s = ''
|
82
53
|
|
83
54
|
if config_yaml = data.delete(:config_yaml)
|
84
55
|
s << config_yaml
|
@@ -88,10 +59,10 @@ private
|
|
88
59
|
s << "#{"#{k}:".ljust(10)} "
|
89
60
|
|
90
61
|
case k
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
62
|
+
when :resources
|
63
|
+
s << resources_str(v)
|
64
|
+
else
|
65
|
+
s << "#{v}"
|
95
66
|
end
|
96
67
|
|
97
68
|
s << "\n"
|
@@ -114,10 +85,10 @@ private
|
|
114
85
|
res = "\033[1m#{name}\033[0m\n"
|
115
86
|
history = history.reverse
|
116
87
|
|
117
|
-
history.chunk{|h| [h[:state], h[:reason].to_s] }.each do |_, hist|
|
88
|
+
history.chunk { |h| [h[:state], h[:reason].to_s] }.each do |_, hist|
|
118
89
|
if hist.size >= 3
|
119
90
|
res << detail_process_info_string(hist[0])
|
120
|
-
res << detail_process_info_string(:
|
91
|
+
res << detail_process_info_string(state: "... #{hist.size - 2} times", reason: '...')
|
121
92
|
res << detail_process_info_string(hist[-1])
|
122
93
|
else
|
123
94
|
hist.each do |h|
|
@@ -135,4 +106,53 @@ private
|
|
135
106
|
"#{at} - #{state} (#{h[:reason]})\n"
|
136
107
|
end
|
137
108
|
|
109
|
+
private
|
110
|
+
|
111
|
+
def render_element(data, level)
|
112
|
+
off = level * 2
|
113
|
+
off_str = ' ' * off
|
114
|
+
|
115
|
+
short_state = (data[:type] == :application || data[:type] == :group) && data[:states]
|
116
|
+
is_text = data[:state] || data[:states]
|
117
|
+
|
118
|
+
name = (data[:type] == :application && !is_text) ? "\033[1m#{data[:name]}\033[0m" : data[:name].to_s
|
119
|
+
off_len = 35
|
120
|
+
str = off_str + (name + ' ').ljust(off_len - off, is_text ? '.' : ' ')
|
121
|
+
|
122
|
+
if short_state
|
123
|
+
str += ' ' + data[:states].map { |k, v| "#{k}:#{v}" }.join(', ')
|
124
|
+
elsif data[:state]
|
125
|
+
str += ' ' + data[:state].to_s
|
126
|
+
if data[:resources] && data[:state].to_sym == :up
|
127
|
+
str += ' (' + resources_str(data[:resources])
|
128
|
+
str += ", <#{data[:procline]}>" if data[:procline]
|
129
|
+
str += ')'
|
130
|
+
end
|
131
|
+
if data[:state_reason] && data[:state] == 'unmonitored'
|
132
|
+
str += " (#{data[:state_reason]} at #{Eye::Utils.human_time2(data[:state_changed_at])})"
|
133
|
+
end
|
134
|
+
elsif data[:current_command]
|
135
|
+
chain_progress = if data[:chain_progress]
|
136
|
+
" #{data[:chain_progress][0]} of #{data[:chain_progress][1]}" rescue ''
|
137
|
+
end
|
138
|
+
str += " \e[1;33m[#{data[:current_command]}#{chain_progress}]\033[0m"
|
139
|
+
str += " (#{data[:chain_commands] * ', '})" if data[:chain_commands]
|
140
|
+
end
|
141
|
+
|
142
|
+
str
|
143
|
+
end
|
144
|
+
|
145
|
+
def resources_str(r)
|
146
|
+
return '' if !r || r.empty?
|
147
|
+
|
148
|
+
memory = r[:memory]
|
149
|
+
cpu = r[:cpu]
|
150
|
+
start_time = r[:start_time]
|
151
|
+
pid = r[:pid]
|
152
|
+
|
153
|
+
return '' unless memory && cpu && start_time
|
154
|
+
|
155
|
+
"#{Eye::Utils.human_time(start_time)}, #{cpu.to_i}%, #{memory / 1024 / 1024}Mb, <#{pid}>"
|
156
|
+
end
|
157
|
+
|
138
158
|
end
|
data/lib/eye/cli/server.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
module Eye::Cli::Server
|
4
|
+
|
4
5
|
private
|
5
6
|
|
6
7
|
def server_started?
|
@@ -26,17 +27,15 @@ private
|
|
26
27
|
ensure_loader_path
|
27
28
|
Eye::Local.ensure_eye_dir
|
28
29
|
|
29
|
-
if server_started?
|
30
|
-
_cmd(:quit) && sleep(1) # stop previous server
|
31
|
-
end
|
32
|
-
|
33
30
|
args = []
|
34
31
|
args += ['--config', conf] if conf
|
35
32
|
args += ['--logger', 'stdout']
|
33
|
+
args += ['--stop_all']
|
36
34
|
if Eye::Local.local_runner
|
37
|
-
args += ['--stop_all']
|
38
35
|
args += ['--dir', Eye::Local.dir]
|
39
|
-
|
36
|
+
if !conf && Eye::Local.eyefile
|
37
|
+
args += ['--config', Eye::Local.eyefile]
|
38
|
+
end
|
40
39
|
end
|
41
40
|
|
42
41
|
Process.exec(ruby_path, loader_path, *args)
|
@@ -51,12 +50,18 @@ private
|
|
51
50
|
args = []
|
52
51
|
args += ['--dir', Eye::Local.dir] if Eye::Local.local_runner
|
53
52
|
|
54
|
-
|
55
|
-
|
53
|
+
chdir = if Eye::Local.local_runner
|
54
|
+
Eye::Local.home
|
55
|
+
else
|
56
|
+
'/'
|
57
|
+
end
|
58
|
+
|
59
|
+
opts = { out: '/dev/null', err: '/dev/null', in: '/dev/null',
|
60
|
+
chdir: chdir, pgroup: true }
|
56
61
|
|
57
62
|
pid = Process.spawn(ruby_path, loader_path, *args, opts)
|
58
63
|
Process.detach(pid)
|
59
|
-
File.open(Eye::Local.pid_path, 'w'){|f| f.write(pid) }
|
64
|
+
File.open(Eye::Local.pid_path, 'w') { |f| f.write(pid) }
|
60
65
|
|
61
66
|
unless wait_server
|
62
67
|
error! 'server has not started in 15 seconds, something is very wrong'
|
@@ -64,11 +69,11 @@ private
|
|
64
69
|
|
65
70
|
configs.unshift(Eye::Local.global_eyeconfig) if File.exist?(Eye::Local.global_eyeconfig)
|
66
71
|
configs.unshift(Eye::Local.eyeconfig) if File.exist?(Eye::Local.eyeconfig)
|
67
|
-
configs << Eye::Local.eyefile if Eye::Local.local_runner
|
72
|
+
configs << Eye::Local.eyefile if Eye::Local.local_runner && Eye::Local.eyefile
|
68
73
|
|
69
|
-
say
|
74
|
+
say "Eye started! ㋡ (#{Eye::Local.home})", :green
|
70
75
|
|
71
|
-
if
|
76
|
+
if configs.any?
|
72
77
|
say_load_result cmd(:load, *configs)
|
73
78
|
end
|
74
79
|
end
|
@@ -76,16 +81,14 @@ private
|
|
76
81
|
def ensure_stop_previous_server
|
77
82
|
Eye::Local.ensure_eye_dir
|
78
83
|
pid = File.read(Eye::Local.pid_path).to_i rescue nil
|
79
|
-
if pid
|
80
|
-
Process.kill(9, pid) rescue nil
|
81
|
-
end
|
84
|
+
Process.kill(9, pid) rescue nil if pid
|
82
85
|
File.delete(Eye::Local.pid_path) rescue nil
|
83
86
|
true
|
84
87
|
end
|
85
88
|
|
86
89
|
def wait_server(timeout = 15)
|
87
90
|
Timeout.timeout(timeout) do
|
88
|
-
sleep 0.3
|
91
|
+
sleep 0.3 until server_started?
|
89
92
|
end
|
90
93
|
true
|
91
94
|
rescue Timeout::Error
|
data/lib/eye/client.rb
CHANGED
data/lib/eye/config.rb
CHANGED
@@ -32,71 +32,74 @@ class Eye::Config
|
|
32
32
|
|
33
33
|
# raise an error if config wrong
|
34
34
|
def validate!(validate_apps = [])
|
35
|
-
all_processes = processes
|
36
|
-
|
37
35
|
# Check blank pid_files
|
38
|
-
no_pid_file =
|
39
|
-
if
|
40
|
-
|
36
|
+
no_pid_file = []
|
37
|
+
each_process { |c| no_pid_file << c if c[:pid_file].blank? }
|
38
|
+
if no_pid_file.any?
|
39
|
+
raise Eye::Dsl::Error, "blank pid_file for: #{no_pid_file.map { |c| c[:name] } * ', '}"
|
41
40
|
end
|
42
41
|
|
43
42
|
# Check duplicates of the full pid_file
|
44
43
|
|
45
|
-
dupl_pids =
|
44
|
+
dupl_pids = Hash.new(0)
|
45
|
+
each_process do |o|
|
46
46
|
ex_pid_file = Eye::System.normalized_file(o[:pid_file], o[:working_dir])
|
47
|
-
|
47
|
+
dupl_pids[ex_pid_file] += 1
|
48
48
|
end
|
49
|
-
dupl_pids = dupl_pids.select{|
|
49
|
+
dupl_pids = dupl_pids.select { |_, v| v > 1 }
|
50
50
|
|
51
|
-
if dupl_pids.
|
51
|
+
if dupl_pids.any?
|
52
52
|
raise Eye::Dsl::Error, "duplicate pid_files: #{dupl_pids.inspect}"
|
53
53
|
end
|
54
54
|
|
55
55
|
# Check duplicates of the full_name
|
56
|
-
dupl_names =
|
56
|
+
dupl_names = Hash.new(0)
|
57
|
+
each_process do |o|
|
57
58
|
full_name = "#{o[:application]}:#{o[:group]}:#{o[:name]}"
|
58
|
-
|
59
|
+
dupl_names[full_name] += 1
|
59
60
|
end
|
60
|
-
dupl_names = dupl_names.select{|
|
61
|
+
dupl_names = dupl_names.select { |_, v| v > 1 }
|
61
62
|
|
62
|
-
if dupl_names.
|
63
|
+
if dupl_names.any?
|
63
64
|
raise Eye::Dsl::Error, "duplicate names: #{dupl_names.inspect}"
|
64
65
|
end
|
65
66
|
|
66
67
|
# validate processes with their own validate
|
67
|
-
|
68
|
+
each_process do |process_cfg|
|
68
69
|
Eye::Process.validate process_cfg, validate_apps.include?(process_cfg[:application])
|
69
70
|
end
|
70
71
|
|
71
72
|
# just to be sure ENV was not removed
|
72
|
-
ENV[''] rescue raise Eye::Dsl::Error
|
73
|
+
ENV[''] rescue raise Eye::Dsl::Error, "ENV is not a hash '#{ENV.inspect}'"
|
73
74
|
end
|
74
75
|
|
75
76
|
def transform!
|
76
|
-
all_processes = processes
|
77
|
-
|
78
77
|
# transform syslog option
|
79
|
-
|
78
|
+
each_process do |process|
|
80
79
|
out = process[:stdout] && process[:stdout].start_with?(':syslog')
|
81
80
|
err = process[:stderr] && process[:stderr].start_with?(':syslog')
|
82
|
-
|
83
|
-
redir = err ? '2>&1' : ''
|
84
|
-
process[:stdout] = nil if out
|
85
|
-
process[:stderr] = nil if err
|
81
|
+
next unless err || out
|
86
82
|
|
87
|
-
|
83
|
+
redir = err ? '2>&1' : ''
|
84
|
+
process[:stdout] = nil if out
|
85
|
+
process[:stderr] = nil if err
|
88
86
|
|
89
|
-
|
90
|
-
logger = "logger -t \"#{names.join(':')}\""
|
87
|
+
escaped_start_command = process[:start_command].to_s.gsub(%{"}, %{\\"})
|
91
88
|
|
92
|
-
|
93
|
-
|
94
|
-
|
89
|
+
names = [process[:application], process[:group] == '__default__' ? nil : process[:group], process[:name]].compact
|
90
|
+
logger = "logger -t \"#{names.join(':')}\""
|
91
|
+
|
92
|
+
process[:start_command] = %{sh -c "#{escaped_start_command} #{redir} | #{logger}"}
|
93
|
+
process[:use_leaf_child] = true if process[:daemonize]
|
95
94
|
end
|
96
95
|
end
|
97
96
|
|
98
|
-
def
|
99
|
-
applications.
|
97
|
+
def each_process(&block)
|
98
|
+
applications.each_value do |app_cfg|
|
99
|
+
(app_cfg[:groups] || {}).each_value do |gr_cfg|
|
100
|
+
(gr_cfg[:processes] || {}).each_value(&block)
|
101
|
+
end
|
102
|
+
end
|
100
103
|
end
|
101
104
|
|
102
105
|
def application_names
|
@@ -108,14 +111,14 @@ class Eye::Config
|
|
108
111
|
end
|
109
112
|
|
110
113
|
def delete_group(name)
|
111
|
-
applications.each do |
|
114
|
+
applications.each do |_app_name, app_cfg|
|
112
115
|
(app_cfg[:groups] || {}).delete(name)
|
113
116
|
end
|
114
117
|
end
|
115
118
|
|
116
119
|
def delete_process(name)
|
117
|
-
applications.each do |
|
118
|
-
(app_cfg[:groups] || {}).each do |
|
120
|
+
applications.each do |_app_name, app_cfg|
|
121
|
+
(app_cfg[:groups] || {}).each do |_gr_name, gr_cfg|
|
119
122
|
(gr_cfg[:processes] || {}).delete(name)
|
120
123
|
end
|
121
124
|
end
|
data/lib/eye/controller.rb
CHANGED
@@ -2,8 +2,6 @@ require 'celluloid'
|
|
2
2
|
require 'yaml'
|
3
3
|
|
4
4
|
require_relative 'utils/pmap'
|
5
|
-
|
6
|
-
require_relative 'utils/leak_19'
|
7
5
|
require_relative 'utils/mini_active_support'
|
8
6
|
|
9
7
|
# Extend all objects with logger
|
@@ -14,6 +12,7 @@ Eye::Sigar
|
|
14
12
|
Eye::SystemResources
|
15
13
|
|
16
14
|
class Eye::Controller
|
15
|
+
|
17
16
|
include Celluloid
|
18
17
|
|
19
18
|
autoload :Load, 'eye/controller/load'
|
@@ -36,7 +35,7 @@ class Eye::Controller
|
|
36
35
|
@applications = []
|
37
36
|
@current_config = Eye::Config.new
|
38
37
|
|
39
|
-
Celluloid
|
38
|
+
Celluloid.logger = Eye::Logger.new('celluloid')
|
40
39
|
|
41
40
|
info "starting #{Eye::ABOUT} <#{$$}>"
|
42
41
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Eye::Controller::Commands
|
2
2
|
|
3
3
|
NOT_IMPORTANT_COMMANDS = [:info_data, :short_data, :debug_data, :history_data, :ping,
|
4
|
-
|
4
|
+
:logger_dev, :match, :explain, :check]
|
5
5
|
|
6
6
|
# Main method, answer for the client command
|
7
7
|
def command(cmd, *args)
|
@@ -5,7 +5,7 @@ module Eye::Controller::Helpers
|
|
5
5
|
str = 'l' + str if Eye::Local.local_runner
|
6
6
|
str += " [#{@applications.map(&:name) * ', '}]" if @applications.present?
|
7
7
|
str += " (v #{ENV['EYE_V']})" if ENV['EYE_V']
|
8
|
-
str += " (in #{Eye::Local.
|
8
|
+
str += " (in #{Eye::Local.home})"
|
9
9
|
$0 = str
|
10
10
|
end
|
11
11
|
|
@@ -16,7 +16,7 @@ module Eye::Controller::Helpers
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def cache_str
|
19
|
-
all_processes.map{ |p| "#{p.full_name}=#{p.state}" } * "\n"
|
19
|
+
all_processes.map { |p| "#{p.full_name}=#{p.state}" } * "\n"
|
20
20
|
end
|
21
21
|
|
22
22
|
def process_by_name(name)
|
data/lib/eye/controller/load.rb
CHANGED
@@ -13,7 +13,7 @@ module Eye::Controller::Load
|
|
13
13
|
obj_strs = args.flatten
|
14
14
|
info "=> loading: #{obj_strs}"
|
15
15
|
|
16
|
-
res =
|
16
|
+
res = {}
|
17
17
|
|
18
18
|
globbing(*obj_strs).each do |filename|
|
19
19
|
res[filename] = catch_load_error(filename) do
|
@@ -35,8 +35,8 @@ private
|
|
35
35
|
# regexp for clean backtrace to show for user
|
36
36
|
BT_REGX = %r[/lib/eye/|lib/celluloid|internal:prelude|logger.rb:|active_support/core_ext|shellwords.rb|kernel/bootstrap].freeze
|
37
37
|
|
38
|
-
def catch_load_error(filename = nil, &
|
39
|
-
{ :
|
38
|
+
def catch_load_error(filename = nil, &_block)
|
39
|
+
{ error: false, config: yield }
|
40
40
|
|
41
41
|
rescue Eye::Dsl::Error, Exception, NoMethodError => ex
|
42
42
|
raise if ex.class.to_s.include?('RR') # skip RR exceptions
|
@@ -45,10 +45,10 @@ private
|
|
45
45
|
|
46
46
|
# filter backtrace for user output
|
47
47
|
bt = (ex.backtrace || [])
|
48
|
-
bt = bt.reject{|line| line.to_s =~ BT_REGX } unless ENV['EYE_FULL_BACKTRACE']
|
48
|
+
bt = bt.reject { |line| line.to_s =~ BT_REGX } unless ENV['EYE_FULL_BACKTRACE']
|
49
49
|
error bt.join("\n")
|
50
50
|
|
51
|
-
res = { :
|
51
|
+
res = { error: true, message: ex.message }
|
52
52
|
res[:backtrace] = bt if bt.present?
|
53
53
|
res
|
54
54
|
end
|
@@ -58,6 +58,8 @@ private
|
|
58
58
|
return res if obj_strs.empty?
|
59
59
|
|
60
60
|
obj_strs.each do |filename|
|
61
|
+
next unless filename
|
62
|
+
|
61
63
|
mask = File.directory?(filename) ? File.join(filename, '{*.eye}') : filename
|
62
64
|
debug { "loading: globbing mask #{mask}" }
|
63
65
|
|
@@ -76,11 +78,7 @@ private
|
|
76
78
|
# return: result, config
|
77
79
|
def parse_config(filename)
|
78
80
|
debug { "parsing: #{filename}" }
|
79
|
-
|
80
|
-
cfg = Eye::Dsl.parse(nil, filename)
|
81
|
-
@current_config.merge(cfg).validate! # just validate summary config here
|
82
|
-
Eye.parsed_config = nil # remove link on config, for better gc
|
83
|
-
cfg
|
81
|
+
Eye::Dsl.parse(nil, filename)
|
84
82
|
end
|
85
83
|
|
86
84
|
# !!! exclusive operation
|
@@ -126,7 +124,7 @@ private
|
|
126
124
|
app.groups.each do |group|
|
127
125
|
@old_groups[group.name] = group
|
128
126
|
group.processes.each do |proc|
|
129
|
-
@old_processes[group.name +
|
127
|
+
@old_processes[group.name + ':' + proc.name] = proc
|
130
128
|
end
|
131
129
|
end
|
132
130
|
|
@@ -139,7 +137,8 @@ private
|
|
139
137
|
|
140
138
|
app = Eye::Application.new(app_name, app_config)
|
141
139
|
@applications << app
|
142
|
-
@added_groups
|
140
|
+
@added_groups = []
|
141
|
+
@added_processes = []
|
143
142
|
|
144
143
|
new_groups = app_config.delete(:groups) || {}
|
145
144
|
new_groups.each do |group_name, group_cfg|
|
@@ -149,8 +148,11 @@ private
|
|
149
148
|
end
|
150
149
|
|
151
150
|
# now, need to clear @old_groups, and @old_processes
|
152
|
-
@old_groups.each
|
153
|
-
|
151
|
+
@old_groups.each do |_, group|
|
152
|
+
group.clear
|
153
|
+
group.send_command(:delete)
|
154
|
+
end
|
155
|
+
@old_processes.each { |_, process| process.send_command(:delete) if process.alive? }
|
154
156
|
|
155
157
|
# schedule monitoring for new groups, processes
|
156
158
|
added_fully_groups = []
|
@@ -161,8 +163,8 @@ private
|
|
161
163
|
end
|
162
164
|
end
|
163
165
|
|
164
|
-
added_fully_groups.each{|group| group.send_command :monitor }
|
165
|
-
@added_processes.each{|process| process.send_command :monitor }
|
166
|
+
added_fully_groups.each { |group| group.send_command :monitor }
|
167
|
+
@added_processes.each { |process| process.send_command :monitor }
|
166
168
|
|
167
169
|
# remove links to prevent memory leaks
|
168
170
|
@old_groups = nil
|
@@ -199,7 +201,7 @@ private
|
|
199
201
|
end
|
200
202
|
|
201
203
|
def update_or_create_process(process_name, process_cfg)
|
202
|
-
postfix =
|
204
|
+
postfix = ':' + process_name
|
203
205
|
name = process_cfg[:group] + postfix
|
204
206
|
key = @old_processes[name] ? name : @old_processes.keys.detect { |n| n.end_with?(postfix) }
|
205
207
|
|