eye 0.4.2 → 0.5
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.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.travis.yml +4 -0
- data/CHANGES.md +11 -0
- data/README.md +3 -3
- data/Rakefile +8 -0
- data/bin/eye +0 -316
- data/bin/loader_eye +3 -3
- data/examples/test.eye +2 -2
- data/eye.gemspec +4 -9
- data/lib/eye.rb +4 -2
- data/lib/eye/application.rb +3 -3
- data/lib/eye/checker.rb +14 -5
- data/lib/eye/checker/cputime.rb +23 -0
- data/lib/eye/checker/file_touched.rb +15 -0
- data/lib/eye/checker/http.rb +7 -9
- data/lib/eye/checker/memory.rb +1 -1
- data/lib/eye/checker/runtime.rb +28 -0
- data/lib/eye/checker/socket.rb +4 -4
- data/lib/eye/cli.rb +166 -0
- data/lib/eye/cli/commands.rb +79 -0
- data/lib/eye/cli/render.rb +137 -0
- data/lib/eye/cli/server.rb +85 -0
- data/lib/eye/client.rb +3 -3
- data/lib/eye/config.rb +17 -14
- data/lib/eye/controller.rb +6 -10
- data/lib/eye/controller/commands.rb +6 -10
- data/lib/eye/controller/helpers.rb +1 -1
- data/lib/eye/controller/send_command.rb +5 -2
- data/lib/eye/controller/status.rb +37 -105
- data/lib/eye/dsl.rb +1 -1
- data/lib/eye/dsl/application_opts.rb +6 -2
- data/lib/eye/dsl/child_process_opts.rb +3 -2
- data/lib/eye/dsl/config_opts.rb +2 -2
- data/lib/eye/dsl/group_opts.rb +2 -1
- data/lib/eye/dsl/main.rb +4 -2
- data/lib/eye/dsl/opts.rb +11 -4
- data/lib/eye/dsl/validation.rb +49 -43
- data/lib/eye/group.rb +1 -1
- data/lib/eye/loader.rb +5 -9
- data/lib/eye/{settings.rb → local.rb} +1 -1
- data/lib/eye/logger.rb +5 -0
- data/lib/eye/notify.rb +12 -6
- data/lib/eye/notify/jabber.rb +2 -2
- data/lib/eye/process/child.rb +3 -1
- data/lib/eye/process/commands.rb +2 -2
- data/lib/eye/process/controller.rb +1 -1
- data/lib/eye/process/trigger.rb +1 -1
- data/lib/eye/sigar.rb +5 -0
- data/lib/eye/system.rb +7 -6
- data/lib/eye/system_resources.rb +46 -41
- data/lib/eye/trigger.rb +15 -8
- data/lib/eye/trigger/flapping.rb +1 -1
- data/lib/eye/trigger/stop_childs.rb +1 -1
- data/lib/eye/trigger/transition.rb +15 -0
- data/lib/eye/utils.rb +12 -0
- data/lib/eye/utils/leak_19.rb +7 -0
- data/lib/eye/utils/mini_active_support.rb +106 -0
- metadata +24 -15
- data/lib/eye/controller/show_history.rb +0 -63
- data/lib/eye/trigger/state.rb +0 -11
@@ -0,0 +1,137 @@
|
|
1
|
+
module Eye::Cli::Render
|
2
|
+
private
|
3
|
+
DF = '%d %b %H:%M'
|
4
|
+
|
5
|
+
def render_info(data)
|
6
|
+
error!("unexpected server answer #{data.inspect}") unless data.is_a?(Hash)
|
7
|
+
|
8
|
+
make_str data
|
9
|
+
end
|
10
|
+
|
11
|
+
def make_str(data, level = -1)
|
12
|
+
return nil if !data || data.empty?
|
13
|
+
|
14
|
+
if data.is_a?(Array)
|
15
|
+
data.map{|el| make_str(el, level) }.compact * "\n"
|
16
|
+
else
|
17
|
+
str = nil
|
18
|
+
|
19
|
+
if data[:name]
|
20
|
+
return make_str(data[:subtree], level) if data[:name] == '__default__'
|
21
|
+
|
22
|
+
off = level * 2
|
23
|
+
off_str = ' ' * off
|
24
|
+
|
25
|
+
short_state = (data[:type] == :application && data[:states])
|
26
|
+
is_text = data[:state] || data[:states]
|
27
|
+
|
28
|
+
name = (data[:type] == :application && !is_text) ? "\033[1m#{data[:name]}\033[0m" : data[:name].to_s
|
29
|
+
off_len = short_state ? 20 : 35
|
30
|
+
str = off_str + (name + ' ').ljust(off_len - off, is_text ? '.' : ' ')
|
31
|
+
|
32
|
+
if short_state
|
33
|
+
str += ' ' + data[:states].map { |k, v| "#{k}:#{v}" }.join(', ')
|
34
|
+
elsif data[:state]
|
35
|
+
str += ' ' + data[:state].to_s
|
36
|
+
str += ' (' + resources_str(data[:resources]) + ')' if data[:resources] && data[:state].to_sym == :up
|
37
|
+
str += " (#{data[:state_reason]} at #{data[:state_changed_at].strftime(DF)})" if data[:state_reason] && data[:state] == 'unmonitored'
|
38
|
+
elsif data[:current_command]
|
39
|
+
chain_progress = if data[:chain_progress]
|
40
|
+
" #{data[:chain_progress][0]} of #{data[:chain_progress][1]}" rescue ''
|
41
|
+
end
|
42
|
+
str += " \e[1;33m[#{data[:current_command]}#{chain_progress}]\033[0m"
|
43
|
+
str += " (#{data[:chain_commands] * ', '})" if data[:chain_commands]
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
if data[:subtree].nil?
|
49
|
+
str
|
50
|
+
elsif !data[:subtree] && data[:type] != :application
|
51
|
+
nil
|
52
|
+
else
|
53
|
+
[str, make_str(data[:subtree], level + 1)].compact * "\n"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def resources_str(r)
|
59
|
+
return '' if !r || r.empty?
|
60
|
+
memory, cpu, start_time, pid = r[:memory], r[:cpu], r[:start_time], r[:pid]
|
61
|
+
return '' unless memory && cpu && start_time
|
62
|
+
|
63
|
+
res = "#{Eye::Utils.human_time(start_time)}, #{cpu.to_i}%"
|
64
|
+
res += ", #{memory / 1024 / 1024}Mb"
|
65
|
+
res += ", <#{pid}>"
|
66
|
+
|
67
|
+
res
|
68
|
+
end
|
69
|
+
|
70
|
+
def render_debug_info(data)
|
71
|
+
error!("unexpected server answer #{data.inspect}") unless data.is_a?(Hash)
|
72
|
+
|
73
|
+
s = ""
|
74
|
+
|
75
|
+
config_yaml = data.delete(:config_yaml)
|
76
|
+
|
77
|
+
data.each do |k, v|
|
78
|
+
s << "#{"#{k}:".ljust(10)} "
|
79
|
+
|
80
|
+
case k
|
81
|
+
when :resources
|
82
|
+
s << resources_str(v)
|
83
|
+
else
|
84
|
+
s << "#{v}"
|
85
|
+
end
|
86
|
+
|
87
|
+
s << "\n"
|
88
|
+
end
|
89
|
+
|
90
|
+
s << "\n"
|
91
|
+
|
92
|
+
if config_yaml
|
93
|
+
s << "Current config:\n"
|
94
|
+
s << config_yaml
|
95
|
+
end
|
96
|
+
|
97
|
+
s
|
98
|
+
end
|
99
|
+
|
100
|
+
def render_history(data)
|
101
|
+
error!("unexpected server answer #{data.inspect}") unless data.is_a?(Hash)
|
102
|
+
|
103
|
+
res = []
|
104
|
+
data.each do |name, data|
|
105
|
+
res << detail_process_info(name, data)
|
106
|
+
end
|
107
|
+
|
108
|
+
res * "\n"
|
109
|
+
end
|
110
|
+
|
111
|
+
def detail_process_info(name, history)
|
112
|
+
return if history.empty?
|
113
|
+
|
114
|
+
res = "\033[1m#{name}\033[0m:\n"
|
115
|
+
history = history.reverse
|
116
|
+
|
117
|
+
history.chunk{|h| [h[:state], h[:reason].to_s] }.each do |_, hist|
|
118
|
+
if hist.size >= 3
|
119
|
+
res << detail_process_info_string(hist[0])
|
120
|
+
res << detail_process_info_string(:state => "... #{hist.size - 2} times", :reason => '...', :at => hist[-1][:at])
|
121
|
+
res << detail_process_info_string(hist[-1])
|
122
|
+
else
|
123
|
+
hist.each do |h|
|
124
|
+
res << detail_process_info_string(h)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
res
|
130
|
+
end
|
131
|
+
|
132
|
+
def detail_process_info_string(h)
|
133
|
+
state = h[:state].to_s.ljust(14)
|
134
|
+
"#{Time.at(h[:at]).strftime(DF)} - #{state} (#{h[:reason]})\n"
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module Eye::Cli::Server
|
2
|
+
private
|
3
|
+
|
4
|
+
def server_started?
|
5
|
+
_cmd(:ping) == :pong
|
6
|
+
end
|
7
|
+
|
8
|
+
def loader_path
|
9
|
+
filename = File.expand_path(File.join(File.dirname(__FILE__), %w[.. .. .. bin loader_eye]))
|
10
|
+
File.exists?(filename) ? filename : nil
|
11
|
+
end
|
12
|
+
|
13
|
+
def ruby_path
|
14
|
+
require 'rbconfig'
|
15
|
+
RbConfig::CONFIG['bindir'] + '/ruby'
|
16
|
+
end
|
17
|
+
|
18
|
+
def ensure_loader_path
|
19
|
+
unless loader_path
|
20
|
+
error! "start monitoring needs to run under ruby with installed gem 'eye'"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def server_start_foreground(conf = nil)
|
25
|
+
ensure_loader_path
|
26
|
+
Eye::Local.ensure_eye_dir
|
27
|
+
|
28
|
+
if server_started?
|
29
|
+
_cmd(:quit) && sleep(1) # stop previous server
|
30
|
+
end
|
31
|
+
|
32
|
+
args = []
|
33
|
+
args += ['-c', conf] if conf
|
34
|
+
args += ['-l', 'stdout']
|
35
|
+
|
36
|
+
Process.exec(ruby_path, loader_path, *args)
|
37
|
+
end
|
38
|
+
|
39
|
+
def server_start(configs)
|
40
|
+
ensure_loader_path
|
41
|
+
Eye::Local.ensure_eye_dir
|
42
|
+
|
43
|
+
ensure_stop_previous_server
|
44
|
+
|
45
|
+
args = []
|
46
|
+
opts = {:out => '/dev/null', :err => '/dev/null', :in => '/dev/null',
|
47
|
+
:chdir => '/', :pgroup => true}
|
48
|
+
|
49
|
+
pid = Process.spawn(ruby_path, loader_path, *args, opts)
|
50
|
+
Process.detach(pid)
|
51
|
+
File.open(Eye::Local.pid_path, 'w'){|f| f.write(pid) }
|
52
|
+
|
53
|
+
unless wait_server
|
54
|
+
error! 'server not runned in 15 seconds, something crazy wrong'
|
55
|
+
end
|
56
|
+
|
57
|
+
configs.unshift(Eye::Local.eyeconfig) if File.exists?(Eye::Local.eyeconfig)
|
58
|
+
|
59
|
+
if !configs.empty?
|
60
|
+
say_load_result cmd(:load, *configs), :started => true
|
61
|
+
else
|
62
|
+
say 'started!', :green
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def ensure_stop_previous_server
|
67
|
+
Eye::Local.ensure_eye_dir
|
68
|
+
pid = File.read(Eye::Local.pid_path).to_i rescue nil
|
69
|
+
if pid
|
70
|
+
Process.kill(9, pid) rescue nil
|
71
|
+
end
|
72
|
+
File.delete(Eye::Local.pid_path) rescue nil
|
73
|
+
true
|
74
|
+
end
|
75
|
+
|
76
|
+
def wait_server(timeout = 15)
|
77
|
+
Timeout.timeout(timeout) do
|
78
|
+
sleep 0.3 while !server_started?
|
79
|
+
end
|
80
|
+
true
|
81
|
+
rescue Timeout::Error
|
82
|
+
false
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
data/lib/eye/client.rb
CHANGED
@@ -13,7 +13,7 @@ class Eye::Client
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def attempt_command(pack)
|
16
|
-
Timeout.timeout(Eye::
|
16
|
+
Timeout.timeout(Eye::Local.client_timeout) do
|
17
17
|
return send_request(pack)
|
18
18
|
end
|
19
19
|
|
@@ -25,8 +25,8 @@ class Eye::Client
|
|
25
25
|
UNIXSocket.open(@socket_path) do |socket|
|
26
26
|
socket.write(pack)
|
27
27
|
data = socket.read
|
28
|
-
res = Marshal.load(data) rescue :
|
28
|
+
res = Marshal.load(data) rescue :corrupted_data
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
end
|
32
|
+
end
|
data/lib/eye/config.rb
CHANGED
@@ -30,33 +30,36 @@ class Eye::Config
|
|
30
30
|
raise Eye::Dsl::Error, "blank pid_file for: #{no_pid_file.map{|c| c[:name]} * ', '}"
|
31
31
|
end
|
32
32
|
|
33
|
-
# Check
|
33
|
+
# Check duplicates of the full pid_file
|
34
34
|
|
35
|
-
|
35
|
+
dupl_pids = all_processes.each_with_object(Hash.new(0)) do |o, h|
|
36
36
|
ex_pid_file = Eye::System.normalized_file(o[:pid_file], o[:working_dir])
|
37
37
|
h[ex_pid_file] += 1
|
38
38
|
end
|
39
|
-
|
39
|
+
dupl_pids = dupl_pids.select{|k,v| v>1}
|
40
40
|
|
41
|
-
if
|
42
|
-
raise Eye::Dsl::Error, "
|
41
|
+
if dupl_pids.present?
|
42
|
+
raise Eye::Dsl::Error, "duplicate pid_files: #{dupl_pids.inspect}"
|
43
43
|
end
|
44
44
|
|
45
|
-
# Check
|
46
|
-
|
45
|
+
# Check duplicates of the full_name
|
46
|
+
dupl_names = all_processes.each_with_object(Hash.new(0)) do |o, h|
|
47
47
|
full_name = "#{o[:application]}:#{o[:group]}:#{o[:name]}"
|
48
48
|
h[full_name] += 1
|
49
49
|
end
|
50
|
-
|
50
|
+
dupl_names = dupl_names.select{|k,v| v>1}
|
51
51
|
|
52
|
-
if
|
53
|
-
raise Eye::Dsl::Error, "
|
52
|
+
if dupl_names.present?
|
53
|
+
raise Eye::Dsl::Error, "duplicate names: #{dupl_names.inspect}"
|
54
54
|
end
|
55
55
|
|
56
56
|
# validate processes with their own validate
|
57
57
|
all_processes.each do |process_cfg|
|
58
58
|
Eye::Process.validate process_cfg
|
59
59
|
end
|
60
|
+
|
61
|
+
# just to be sure ENV was not removed
|
62
|
+
ENV[''] rescue raise Eye::Dsl::Error.new("ENV is not a hash '#{ENV.inspect}'")
|
60
63
|
end
|
61
64
|
|
62
65
|
def processes
|
@@ -73,16 +76,16 @@ class Eye::Config
|
|
73
76
|
|
74
77
|
def delete_group(name)
|
75
78
|
applications.each do |app_name, app_cfg|
|
76
|
-
app_cfg[:groups].delete(name)
|
79
|
+
(app_cfg[:groups] || {}).delete(name)
|
77
80
|
end
|
78
81
|
end
|
79
82
|
|
80
83
|
def delete_process(name)
|
81
84
|
applications.each do |app_name, app_cfg|
|
82
|
-
app_cfg[:groups].each do |gr_name, gr_cfg|
|
83
|
-
gr_cfg[:processes].delete(name)
|
85
|
+
(app_cfg[:groups] || {}).each do |gr_name, gr_cfg|
|
86
|
+
(gr_cfg[:processes] || {}).delete(name)
|
84
87
|
end
|
85
88
|
end
|
86
89
|
end
|
87
90
|
|
88
|
-
end
|
91
|
+
end
|
data/lib/eye/controller.rb
CHANGED
@@ -1,19 +1,17 @@
|
|
1
1
|
require 'celluloid'
|
2
|
-
|
3
2
|
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
|
-
require 'active_support/core_ext/array/extract_options'
|
10
3
|
|
11
4
|
require_relative 'utils/celluloid_klass'
|
12
5
|
require_relative 'utils/pmap'
|
13
6
|
|
7
|
+
require_relative 'utils/leak_19'
|
8
|
+
require_relative 'utils/mini_active_support'
|
9
|
+
|
14
10
|
# Extend all objects with logger
|
15
11
|
Object.send(:include, Eye::Logger::ObjectExt)
|
16
12
|
|
13
|
+
Eye::Sigar # needs to preload
|
14
|
+
|
17
15
|
class Eye::Controller
|
18
16
|
include Celluloid
|
19
17
|
|
@@ -22,7 +20,6 @@ class Eye::Controller
|
|
22
20
|
autoload :Commands, 'eye/controller/commands'
|
23
21
|
autoload :Status, 'eye/controller/status'
|
24
22
|
autoload :SendCommand, 'eye/controller/send_command'
|
25
|
-
autoload :ShowHistory, 'eye/controller/show_history'
|
26
23
|
autoload :Options, 'eye/controller/options'
|
27
24
|
|
28
25
|
include Eye::Controller::Load
|
@@ -30,7 +27,6 @@ class Eye::Controller
|
|
30
27
|
include Eye::Controller::Commands
|
31
28
|
include Eye::Controller::Status
|
32
29
|
include Eye::Controller::SendCommand
|
33
|
-
include Eye::Controller::ShowHistory
|
34
30
|
include Eye::Controller::Options
|
35
31
|
|
36
32
|
attr_reader :applications, :current_config
|
@@ -42,7 +38,7 @@ class Eye::Controller
|
|
42
38
|
@current_config = Eye::Config.new
|
43
39
|
|
44
40
|
Celluloid::logger = Eye::Logger.new('celluloid')
|
45
|
-
Eye::SystemResources.
|
41
|
+
Eye::SystemResources.cache
|
46
42
|
|
47
43
|
info "starting #{Eye::ABOUT} (#{$$})"
|
48
44
|
end
|
@@ -16,14 +16,6 @@ module Eye::Controller::Commands
|
|
16
16
|
signal(*args)
|
17
17
|
when :load
|
18
18
|
load(*args)
|
19
|
-
when :info
|
20
|
-
info_string(*args)
|
21
|
-
when :xinfo
|
22
|
-
info_string_debug(*args)
|
23
|
-
when :oinfo
|
24
|
-
info_string_short(*args)
|
25
|
-
when :history
|
26
|
-
history_string(*args)
|
27
19
|
when :quit
|
28
20
|
quit
|
29
21
|
when :check
|
@@ -38,9 +30,13 @@ module Eye::Controller::Commands
|
|
38
30
|
Eye::Logger.dev
|
39
31
|
|
40
32
|
# object commands, for api
|
41
|
-
when :
|
33
|
+
when :info_data
|
42
34
|
info_data(*args)
|
43
|
-
when :
|
35
|
+
when :short_data
|
36
|
+
short_data(*args)
|
37
|
+
when :debug_data
|
38
|
+
debug_data(*args)
|
39
|
+
when :history_data
|
44
40
|
history_data(*args)
|
45
41
|
|
46
42
|
else
|
@@ -35,8 +35,11 @@ private
|
|
35
35
|
|
36
36
|
rescue Error => ex
|
37
37
|
log_ex(ex)
|
38
|
-
|
39
38
|
{:error => ex.message}
|
39
|
+
|
40
|
+
rescue Celluloid::DeadActorError => ex
|
41
|
+
log_ex(ex)
|
42
|
+
{:error => "'#{ex.message}', try again!"}
|
40
43
|
end
|
41
44
|
|
42
45
|
def remove_object_from_tree(obj)
|
@@ -75,7 +78,7 @@ private
|
|
75
78
|
end
|
76
79
|
|
77
80
|
res = Eye::Utils::AliveArray.new
|
78
|
-
obj_strs.map{|c| c.to_s.split(
|
81
|
+
obj_strs.map{|c| c.to_s.split(',')}.flatten.each do |mask|
|
79
82
|
objs = find_objects_by_mask(mask.to_s.strip)
|
80
83
|
objs.select! { |obj| obj.app_name == h[:application] } if h[:application]
|
81
84
|
res += objs
|
@@ -1,50 +1,42 @@
|
|
1
1
|
module Eye::Controller::Status
|
2
2
|
|
3
|
-
def
|
4
|
-
make_str(info_data(*args)).to_s
|
5
|
-
end
|
6
|
-
|
7
|
-
def info_string_short(*args)
|
8
|
-
make_str({:subtree => @applications.map{|a| a.status_data_short } }).to_s
|
9
|
-
end
|
10
|
-
|
11
|
-
def info_string_debug(*args)
|
3
|
+
def debug_data(*args)
|
12
4
|
h = args.extract_options!
|
13
5
|
actors = Celluloid::Actor.all.map{|actor| actor.__klass__ }.group_by{|a| a}.map{|k,v| [k, v.size]}.sort_by{|a|a[1]}.reverse
|
14
6
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
S
|
7
|
+
res = {
|
8
|
+
:about => Eye::ABOUT,
|
9
|
+
:resources => Eye::SystemResources.resources($$),
|
10
|
+
:ruby => RUBY_DESCRIPTION,
|
11
|
+
:gems => %w|Celluloid Celluloid::IO StateMachine NIO Sigar|.map{|c| gem_version(c) },
|
12
|
+
:logger => Eye::Logger.dev,
|
13
|
+
:pid_path => Eye::Local::pid_path,
|
14
|
+
:actors => actors
|
15
|
+
}
|
26
16
|
|
27
|
-
|
17
|
+
res[:config_yaml] = YAML.dump(current_config.to_h) if h[:config].present?
|
28
18
|
|
29
|
-
|
30
|
-
str += "\nCurrent config: \n"
|
31
|
-
str += YAML.dump(current_config.to_h)
|
32
|
-
end
|
33
|
-
|
34
|
-
GC.start
|
35
|
-
str
|
19
|
+
res
|
36
20
|
end
|
37
21
|
|
38
22
|
def info_data(*args)
|
39
23
|
{:subtree => info_objects(*args).map{|a| a.status_data } }
|
40
24
|
end
|
41
25
|
|
42
|
-
|
26
|
+
def short_data(*args)
|
27
|
+
{:subtree => @applications.map{|a| a.status_data_short } }
|
28
|
+
end
|
43
29
|
|
44
|
-
def
|
45
|
-
|
30
|
+
def history_data(*args)
|
31
|
+
res = {}
|
32
|
+
history_objects(*args).each do |process|
|
33
|
+
res[process.full_name] = process.schedule_history.reject{|c| c[:state] == :check_crash }
|
34
|
+
end
|
35
|
+
res
|
46
36
|
end
|
47
37
|
|
38
|
+
private
|
39
|
+
|
48
40
|
def info_objects(*args)
|
49
41
|
res = []
|
50
42
|
return @applications if args.empty?
|
@@ -52,79 +44,6 @@ private
|
|
52
44
|
res
|
53
45
|
end
|
54
46
|
|
55
|
-
def make_str(data, level = -1)
|
56
|
-
return nil if data.blank?
|
57
|
-
|
58
|
-
if data.is_a?(Array)
|
59
|
-
data.map{|el| make_str(el, level) }.compact * "\n"
|
60
|
-
else
|
61
|
-
str = nil
|
62
|
-
|
63
|
-
if data[:name]
|
64
|
-
return make_str(data[:subtree], level) if data[:name] == '__default__'
|
65
|
-
|
66
|
-
off = level * 2
|
67
|
-
off_str = ' ' * off
|
68
|
-
name = (data[:type] == :application && data[:state].blank?) ? "\033[1m#{data[:name]}\033[0m" : data[:name].to_s
|
69
|
-
off_len = (data[:type] == :application && !data[:state].blank?) ? 20 : 35
|
70
|
-
str = off_str + (name + ' ').ljust(off_len - off, data[:state] ? '.' : ' ')
|
71
|
-
|
72
|
-
if data[:debug]
|
73
|
-
str += ' | ' + debug_str(data[:debug])
|
74
|
-
|
75
|
-
# for group show chain data
|
76
|
-
if data[:debug][:chain]
|
77
|
-
str += " (chain: #{data[:debug][:chain].map(&:to_i)})"
|
78
|
-
end
|
79
|
-
elsif data[:state]
|
80
|
-
str += ' ' + data[:state].to_s
|
81
|
-
str += ' (' + resources_str(data[:resources]) + ')' if data[:resources].present? && data[:state].to_sym == :up
|
82
|
-
str += " (#{data[:state_reason]} at #{data[:state_changed_at].to_s(:short)})" if data[:state_reason] && data[:state] == 'unmonitored'
|
83
|
-
elsif data[:current_command]
|
84
|
-
chain_progress = if data[:chain_progress]
|
85
|
-
" #{data[:chain_progress][0]} of #{data[:chain_progress][1]}" rescue ''
|
86
|
-
end
|
87
|
-
str += " \e[1;33m[#{data[:current_command]}#{chain_progress}]\033[0m"
|
88
|
-
str += " (#{data[:chain_commands] * ', '})" if data[:chain_commands]
|
89
|
-
end
|
90
|
-
|
91
|
-
end
|
92
|
-
|
93
|
-
if data[:subtree].nil?
|
94
|
-
str
|
95
|
-
elsif data[:subtree].blank? && data[:type] != :application
|
96
|
-
nil
|
97
|
-
else
|
98
|
-
[str, make_str(data[:subtree], level + 1)].compact * "\n"
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
def resources_str(r)
|
104
|
-
return '' if r.blank?
|
105
|
-
|
106
|
-
res = "#{r[:start_time]}, #{r[:cpu]}%"
|
107
|
-
res += ", #{r[:memory] / 1024}Mb" if r[:memory]
|
108
|
-
res += ", <#{r[:pid]}>"
|
109
|
-
|
110
|
-
res
|
111
|
-
end
|
112
|
-
|
113
|
-
def debug_str(debug)
|
114
|
-
return '' unless debug
|
115
|
-
|
116
|
-
q = 'q(' + (debug[:queue] || []) * ',' + ')'
|
117
|
-
w = 'w(' + (debug[:watchers] || []) * ',' + ')'
|
118
|
-
|
119
|
-
[w, q] * '; '
|
120
|
-
end
|
121
|
-
|
122
|
-
def status_applications(app = nil)
|
123
|
-
apps = app.present? ? @applications.select{|a| a.name == app} : nil
|
124
|
-
apps = @applications unless apps
|
125
|
-
apps
|
126
|
-
end
|
127
|
-
|
128
47
|
def gem_version(klass)
|
129
48
|
v = nil
|
130
49
|
begin
|
@@ -135,4 +54,17 @@ private
|
|
135
54
|
"#{klass}=#{v}"
|
136
55
|
end
|
137
56
|
|
138
|
-
|
57
|
+
def history_objects(*args)
|
58
|
+
args = ['*'] if args.empty?
|
59
|
+
res = []
|
60
|
+
matched_objects(*args) do |obj|
|
61
|
+
if (obj.is_a?(Eye::Process) || obj.is_a?(Eye::ChildProcess))
|
62
|
+
res << obj
|
63
|
+
else
|
64
|
+
res += obj.processes.to_a
|
65
|
+
end
|
66
|
+
end
|
67
|
+
Eye::Utils::AliveArray.new(res)
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|