eye 0.3.2 → 0.4
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 +1 -0
- data/.rspec +1 -1
- data/.travis.yml +3 -1
- data/CHANGES.md +11 -2
- data/Gemfile +1 -0
- data/README.md +18 -14
- data/Rakefile +10 -3
- data/bin/eye +41 -27
- data/examples/process_thin.rb +1 -1
- data/examples/processes/em.rb +2 -2
- data/examples/processes/forking.rb +2 -2
- data/examples/processes/sample.rb +5 -5
- data/examples/rbenv.eye +1 -1
- data/examples/sidekiq.eye +2 -2
- data/examples/test.eye +10 -6
- data/examples/thin-farm.eye +1 -1
- data/examples/unicorn.eye +1 -1
- data/eye.gemspec +13 -7
- data/lib/eye.rb +6 -6
- data/lib/eye/application.rb +9 -6
- data/lib/eye/checker.rb +51 -21
- data/lib/eye/checker/file_size.rb +1 -1
- data/lib/eye/checker/http.rb +3 -3
- data/lib/eye/checker/memory.rb +1 -1
- data/lib/eye/checker/socket.rb +6 -6
- data/lib/eye/child_process.rb +7 -11
- data/lib/eye/client.rb +6 -6
- data/lib/eye/config.rb +2 -2
- data/lib/eye/controller.rb +11 -8
- data/lib/eye/controller/commands.rb +8 -9
- data/lib/eye/controller/helpers.rb +1 -0
- data/lib/eye/controller/load.rb +11 -7
- data/lib/eye/controller/send_command.rb +44 -19
- data/lib/eye/controller/show_history.rb +8 -7
- data/lib/eye/controller/status.rb +39 -26
- data/lib/eye/dsl.rb +3 -3
- data/lib/eye/dsl/application_opts.rb +4 -4
- data/lib/eye/dsl/config_opts.rb +4 -4
- data/lib/eye/dsl/helpers.rb +2 -2
- data/lib/eye/dsl/main.rb +2 -2
- data/lib/eye/dsl/opts.rb +19 -14
- data/lib/eye/dsl/process_opts.rb +1 -1
- data/lib/eye/dsl/pure_opts.rb +2 -2
- data/lib/eye/dsl/validation.rb +7 -5
- data/lib/eye/group.rb +17 -11
- data/lib/eye/group/chain.rb +3 -3
- data/lib/eye/loader.rb +8 -6
- data/lib/eye/logger.rb +14 -5
- data/lib/eye/notify.rb +13 -7
- data/lib/eye/notify/jabber.rb +2 -2
- data/lib/eye/notify/mail.rb +2 -2
- data/lib/eye/process.rb +10 -13
- data/lib/eye/process/child.rb +1 -1
- data/lib/eye/process/commands.rb +34 -32
- data/lib/eye/process/config.rb +17 -12
- data/lib/eye/process/controller.rb +3 -6
- data/lib/eye/process/data.rb +16 -5
- data/lib/eye/process/monitor.rb +12 -5
- data/lib/eye/process/notify.rb +1 -1
- data/lib/eye/process/scheduler.rb +3 -3
- data/lib/eye/process/states.rb +10 -13
- data/lib/eye/process/states_history.rb +3 -3
- data/lib/eye/process/system.rb +17 -21
- data/lib/eye/process/trigger.rb +11 -30
- data/lib/eye/process/watchers.rb +9 -9
- data/lib/eye/server.rb +14 -6
- data/lib/eye/settings.rb +4 -4
- data/lib/eye/system.rb +10 -7
- data/lib/eye/system_resources.rb +4 -4
- data/lib/eye/trigger.rb +58 -21
- data/lib/eye/trigger/flapping.rb +24 -4
- data/lib/eye/trigger/state.rb +28 -0
- data/lib/eye/utils/alive_array.rb +1 -1
- data/lib/eye/utils/celluloid_klass.rb +5 -0
- data/lib/eye/utils/pmap.rb +7 -0
- data/lib/eye/utils/tail.rb +1 -1
- metadata +39 -23
- data/lib/eye/utils/leak_19.rb +0 -7
data/lib/eye/client.rb
CHANGED
@@ -7,11 +7,11 @@ class Eye::Client
|
|
7
7
|
def initialize(socket_path)
|
8
8
|
@socket_path = socket_path
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
def command(cmd, *args)
|
12
|
-
attempt_command([cmd, *args]
|
12
|
+
attempt_command(Marshal.dump([cmd, *args]))
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
def attempt_command(pack)
|
16
16
|
Timeout.timeout(Eye::Settings.client_timeout) do
|
17
17
|
return send_request(pack)
|
@@ -23,10 +23,10 @@ class Eye::Client
|
|
23
23
|
|
24
24
|
def send_request(pack)
|
25
25
|
UNIXSocket.open(@socket_path) do |socket|
|
26
|
-
socket.
|
26
|
+
socket.write(pack)
|
27
27
|
data = socket.read
|
28
|
-
res = Marshal.load(data) rescue :
|
28
|
+
res = Marshal.load(data) rescue :corrupred_data
|
29
29
|
end
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
end
|
data/lib/eye/config.rb
CHANGED
@@ -32,7 +32,7 @@ class Eye::Config
|
|
32
32
|
|
33
33
|
# Check dublicates of the full pid_file
|
34
34
|
|
35
|
-
dubl_pids = all_processes.each_with_object(Hash.new(0)) do |o, h|
|
35
|
+
dubl_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
|
@@ -43,7 +43,7 @@ class Eye::Config
|
|
43
43
|
end
|
44
44
|
|
45
45
|
# Check dublicates of the full_name
|
46
|
-
dubl_names = all_processes.each_with_object(Hash.new(0)) do |o, h|
|
46
|
+
dubl_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
|
data/lib/eye/controller.rb
CHANGED
@@ -6,10 +6,13 @@ require 'active_support/core_ext/object/blank'
|
|
6
6
|
require 'active_support/core_ext/object/try'
|
7
7
|
require 'active_support/core_ext/numeric'
|
8
8
|
require 'active_support/core_ext/string/filters'
|
9
|
+
require 'active_support/core_ext/array/extract_options'
|
9
10
|
|
10
|
-
require_relative 'utils/
|
11
|
+
require_relative 'utils/celluloid_klass'
|
12
|
+
require_relative 'utils/pmap'
|
11
13
|
|
12
|
-
|
14
|
+
# Extend all objects with logger
|
15
|
+
Object.send(:include, Eye::Logger::ObjectExt)
|
13
16
|
|
14
17
|
class Eye::Controller
|
15
18
|
include Celluloid
|
@@ -22,7 +25,6 @@ class Eye::Controller
|
|
22
25
|
autoload :ShowHistory, 'eye/controller/show_history'
|
23
26
|
autoload :Options, 'eye/controller/options'
|
24
27
|
|
25
|
-
include Eye::Logger::Helpers
|
26
28
|
include Eye::Controller::Load
|
27
29
|
include Eye::Controller::Helpers
|
28
30
|
include Eye::Controller::Commands
|
@@ -37,12 +39,9 @@ class Eye::Controller
|
|
37
39
|
@applications = []
|
38
40
|
@current_config = Eye::Config.new
|
39
41
|
|
40
|
-
|
41
|
-
@logger = Eye.logger
|
42
|
-
Celluloid::logger = Eye.logger
|
43
|
-
|
42
|
+
Celluloid::logger = Eye::Logger.new('celluloid')
|
44
43
|
Eye::SystemResources.setup
|
45
|
-
|
44
|
+
|
46
45
|
info "starting #{Eye::ABOUT} (#{$$})"
|
47
46
|
end
|
48
47
|
|
@@ -50,4 +49,8 @@ class Eye::Controller
|
|
50
49
|
current_config.settings
|
51
50
|
end
|
52
51
|
|
52
|
+
def logger_tag
|
53
|
+
'Eye'
|
54
|
+
end
|
55
|
+
|
53
56
|
end
|
@@ -6,8 +6,8 @@ module Eye::Controller::Commands
|
|
6
6
|
|
7
7
|
start_at = Time.now
|
8
8
|
cmd = cmd.to_sym
|
9
|
-
|
10
|
-
res = case cmd
|
9
|
+
|
10
|
+
res = case cmd
|
11
11
|
when :start, :stop, :restart, :unmonitor, :monitor
|
12
12
|
send_command(cmd, *args)
|
13
13
|
when :delete
|
@@ -23,7 +23,7 @@ module Eye::Controller::Commands
|
|
23
23
|
when :xinfo
|
24
24
|
info_string_debug(*args)
|
25
25
|
when :oinfo
|
26
|
-
info_string_short
|
26
|
+
info_string_short(*args)
|
27
27
|
when :history
|
28
28
|
history_string(*args)
|
29
29
|
when :quit
|
@@ -47,22 +47,21 @@ module Eye::Controller::Commands
|
|
47
47
|
|
48
48
|
else
|
49
49
|
:unknown_command
|
50
|
-
end
|
50
|
+
end
|
51
51
|
|
52
52
|
GC.start
|
53
53
|
info "client command: #{cmd} #{args * ', '} (#{Time.now - start_at}s)"
|
54
54
|
|
55
|
-
res
|
55
|
+
res
|
56
56
|
end
|
57
57
|
|
58
58
|
private
|
59
59
|
|
60
60
|
def quit
|
61
|
-
info '
|
61
|
+
info 'Quit!'
|
62
|
+
Eye::System.send_signal($$, :TERM)
|
62
63
|
sleep 1
|
63
|
-
Eye::System.send_signal(
|
64
|
-
sleep 2
|
65
|
-
Eye::System.send_signal($$, 9)
|
64
|
+
Eye::System.send_signal($$, :KILL)
|
66
65
|
end
|
67
66
|
|
68
67
|
end
|
data/lib/eye/controller/load.rb
CHANGED
@@ -8,7 +8,9 @@ module Eye::Controller::Load
|
|
8
8
|
{ filename => catch_load_error(filename) { parse_config(filename).to_h } }
|
9
9
|
end
|
10
10
|
|
11
|
-
def load(*
|
11
|
+
def load(*args)
|
12
|
+
h = args.extract_options!
|
13
|
+
obj_strs = args.flatten
|
12
14
|
info "load: #{obj_strs}"
|
13
15
|
|
14
16
|
res = Hash.new
|
@@ -24,6 +26,8 @@ module Eye::Controller::Load
|
|
24
26
|
set_proc_line
|
25
27
|
save_cache
|
26
28
|
|
29
|
+
info "loaded: #{obj_strs}, selfpid <#{$$}>"
|
30
|
+
|
27
31
|
res
|
28
32
|
end
|
29
33
|
|
@@ -68,7 +72,7 @@ private
|
|
68
72
|
sub << config_path
|
69
73
|
end
|
70
74
|
sub = [mask] if sub.empty?
|
71
|
-
|
75
|
+
|
72
76
|
res += sub
|
73
77
|
end
|
74
78
|
|
@@ -76,7 +80,7 @@ private
|
|
76
80
|
end
|
77
81
|
|
78
82
|
# return: result, config
|
79
|
-
def parse_config(filename)
|
83
|
+
def parse_config(filename)
|
80
84
|
raise Eye::Dsl::Error, "config file '#{filename}' not found!" unless File.exists?(filename)
|
81
85
|
debug "parse #{filename}"
|
82
86
|
|
@@ -90,7 +94,7 @@ private
|
|
90
94
|
info "load #{filename}"
|
91
95
|
new_cfg = @current_config.merge(config)
|
92
96
|
new_cfg.validate!
|
93
|
-
|
97
|
+
|
94
98
|
load_options(new_cfg.settings)
|
95
99
|
create_objects(new_cfg.applications, config.application_names)
|
96
100
|
@current_config = new_cfg
|
@@ -150,7 +154,7 @@ private
|
|
150
154
|
group.resort_processes
|
151
155
|
end
|
152
156
|
|
153
|
-
# now, need to clear @old_groups, and @old_processes
|
157
|
+
# now, need to clear @old_groups, and @old_processes
|
154
158
|
@old_groups.each{|_, group| group.clear; group.send_command(:delete) }
|
155
159
|
@old_processes.each{|_, process| process.send_command(:delete) if process.alive? }
|
156
160
|
|
@@ -159,7 +163,7 @@ private
|
|
159
163
|
@added_groups.each do |group|
|
160
164
|
if group.processes.size > 0 && (group.processes.pure - @added_processes).size == 0
|
161
165
|
added_fully_groups << group
|
162
|
-
@added_processes -= group.processes.pure
|
166
|
+
@added_processes -= group.processes.pure
|
163
167
|
end
|
164
168
|
end
|
165
169
|
|
@@ -205,7 +209,7 @@ private
|
|
205
209
|
debug "update process #{process_name}"
|
206
210
|
process = @old_processes.delete(process_name)
|
207
211
|
process.schedule :update_config, process_cfg, Eye::Reason::User.new(:'load config')
|
208
|
-
process
|
212
|
+
process
|
209
213
|
else
|
210
214
|
debug "create process #{process_name}"
|
211
215
|
process = Eye::Process.new(process_cfg)
|
@@ -1,9 +1,9 @@
|
|
1
1
|
module Eye::Controller::SendCommand
|
2
2
|
|
3
|
-
def send_command(command, *
|
4
|
-
matched_objects(*
|
3
|
+
def send_command(command, *args)
|
4
|
+
matched_objects(*args) do |obj|
|
5
5
|
if command.to_sym == :delete
|
6
|
-
remove_object_from_tree(obj)
|
6
|
+
remove_object_from_tree(obj)
|
7
7
|
|
8
8
|
set_proc_line
|
9
9
|
save_cache
|
@@ -13,29 +13,39 @@ module Eye::Controller::SendCommand
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
def match(*
|
17
|
-
matched_objects(*
|
18
|
-
end
|
16
|
+
def match(*args)
|
17
|
+
matched_objects(*args)
|
18
|
+
end
|
19
19
|
|
20
|
-
def signal(
|
21
|
-
matched_objects(*
|
22
|
-
obj.send_command :signal,
|
20
|
+
def signal(signal, *args)
|
21
|
+
matched_objects(*args) do |obj|
|
22
|
+
obj.send_command :signal, signal || 0
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
def break_chain(*
|
27
|
-
matched_objects(*
|
26
|
+
def break_chain(*args)
|
27
|
+
matched_objects(*args) do |obj|
|
28
28
|
obj.send_command(:break_chain)
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
32
|
private
|
33
33
|
|
34
|
-
|
34
|
+
class Error < Exception; end
|
35
|
+
|
36
|
+
def matched_objects(*args, &block)
|
37
|
+
h = args.extract_options!
|
38
|
+
obj_strs = args
|
39
|
+
|
35
40
|
objs = find_objects(*obj_strs)
|
36
41
|
res = objs.map(&:full_name)
|
37
42
|
objs.each{|obj| block[obj] } if block
|
38
|
-
res
|
43
|
+
{:result => res}
|
44
|
+
|
45
|
+
rescue Error => ex
|
46
|
+
error ex.message
|
47
|
+
|
48
|
+
{:error => ex.message}
|
39
49
|
end
|
40
50
|
|
41
51
|
def remove_object_from_tree(obj)
|
@@ -54,17 +64,17 @@ private
|
|
54
64
|
if klass == Eye::Process
|
55
65
|
@applications.each{|app| app.groups.each{|gr| gr.processes.delete(obj) }}
|
56
66
|
@current_config.delete_process(obj.name)
|
57
|
-
end
|
67
|
+
end
|
58
68
|
end
|
59
69
|
|
60
70
|
# find object to action, restart ... (app, group or process)
|
61
71
|
# nil if not found
|
62
72
|
def find_objects(*obj_strs)
|
63
73
|
return [] if obj_strs.blank?
|
64
|
-
return @applications.dup if obj_strs.size == 1 && (obj_strs[0].strip == 'all' || obj_strs[0].strip == '*')
|
74
|
+
return @applications.dup if obj_strs.size == 1 && (obj_strs[0].to_s.strip == 'all' || obj_strs[0].to_s.strip == '*')
|
65
75
|
|
66
76
|
res = Eye::Utils::AliveArray.new
|
67
|
-
obj_strs.map{|c| c.split(",")}.flatten.each do |mask|
|
77
|
+
obj_strs.map{|c| c.to_s.split(",")}.flatten.each do |mask|
|
68
78
|
res += find_objects_by_mask(mask.to_s.strip)
|
69
79
|
end
|
70
80
|
res
|
@@ -76,15 +86,16 @@ private
|
|
76
86
|
if res.size > 1
|
77
87
|
final = Eye::Utils::AliveArray.new
|
78
88
|
|
89
|
+
# try to find exactly matched
|
79
90
|
if mask[-1] != '*'
|
80
|
-
# try to find exactly matched
|
81
91
|
r = right_regexp(mask)
|
82
92
|
res.each do |obj|
|
83
93
|
final << obj if obj.full_name =~ r
|
84
94
|
end
|
85
95
|
end
|
86
96
|
|
87
|
-
|
97
|
+
res = final if final.present?
|
98
|
+
final = Eye::Utils::AliveArray.new
|
88
99
|
|
89
100
|
# remove inherited targets
|
90
101
|
res.each do |obj|
|
@@ -93,7 +104,21 @@ private
|
|
93
104
|
end
|
94
105
|
|
95
106
|
res = final
|
96
|
-
|
107
|
+
|
108
|
+
# try to remove objects with different applications
|
109
|
+
fapps, apps = [], []
|
110
|
+
res.each do |obj|
|
111
|
+
if obj.is_a?(Eye::Application)
|
112
|
+
fapps << obj.name
|
113
|
+
else
|
114
|
+
apps << obj.app_name
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
if (apps).uniq.size > 1 || (fapps.size > 0 && (apps | fapps).size > fapps.size)
|
119
|
+
raise Error, "cant match targets from different applications: #{res.map(&:full_name)}"
|
120
|
+
end
|
121
|
+
end
|
97
122
|
|
98
123
|
res
|
99
124
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Eye::Controller::ShowHistory
|
2
2
|
|
3
|
-
def history_string(*
|
4
|
-
data = history_data(*
|
3
|
+
def history_string(*args)
|
4
|
+
data = history_data(*args)
|
5
5
|
|
6
6
|
res = []
|
7
7
|
data.each do |name, data|
|
@@ -11,9 +11,9 @@ module Eye::Controller::ShowHistory
|
|
11
11
|
res * "\n"
|
12
12
|
end
|
13
13
|
|
14
|
-
def history_data(*
|
14
|
+
def history_data(*args)
|
15
15
|
res = {}
|
16
|
-
get_processes_for_history(*
|
16
|
+
get_processes_for_history(*args).each do |process|
|
17
17
|
res[process.full_name] = process.schedule_history.reject{|c| c[:state] == :check_crash }
|
18
18
|
end
|
19
19
|
res
|
@@ -21,11 +21,12 @@ module Eye::Controller::ShowHistory
|
|
21
21
|
|
22
22
|
private
|
23
23
|
|
24
|
-
def get_processes_for_history(*
|
24
|
+
def get_processes_for_history(*args)
|
25
|
+
args = ['*'] if args.empty?
|
25
26
|
res = []
|
26
|
-
matched_objects(*
|
27
|
+
matched_objects(*args) do |obj|
|
27
28
|
if (obj.is_a?(Eye::Process) || obj.is_a?(Eye::ChildProcess))
|
28
|
-
res << obj
|
29
|
+
res << obj
|
29
30
|
else
|
30
31
|
res += obj.processes.to_a
|
31
32
|
end
|
@@ -1,35 +1,23 @@
|
|
1
1
|
module Eye::Controller::Status
|
2
2
|
|
3
|
-
def
|
4
|
-
|
5
|
-
return @applications unless mask
|
6
|
-
matched_objects(mask){|obj| res << obj }
|
7
|
-
res
|
8
|
-
end
|
9
|
-
|
10
|
-
def info_data(mask = nil)
|
11
|
-
{:subtree => info_objects(mask).map{|a| a.status_data } }
|
12
|
-
end
|
13
|
-
|
14
|
-
def info_data_debug(mask = nil)
|
15
|
-
{:subtree => info_objects(mask).map{|a| a.status_data(true) } }
|
3
|
+
def info_string(*args)
|
4
|
+
make_str(info_data(*args)).to_s
|
16
5
|
end
|
17
6
|
|
18
|
-
def
|
19
|
-
make_str(info_data(mask)).to_s
|
20
|
-
end
|
21
|
-
|
22
|
-
def info_string_short
|
7
|
+
def info_string_short(*args)
|
23
8
|
make_str({:subtree => @applications.map{|a| a.status_data_short } }).to_s
|
24
9
|
end
|
25
10
|
|
26
|
-
def info_string_debug(
|
27
|
-
|
11
|
+
def info_string_debug(*args)
|
12
|
+
h = args.extract_options!
|
13
|
+
actors = Celluloid::Actor.all.map{|actor| actor.__klass__ }.group_by{|a| a}.map{|k,v| [k, v.size]}.sort_by{|a|a[1]}.reverse
|
28
14
|
|
29
15
|
str = <<-S
|
30
16
|
About: #{Eye::ABOUT}
|
31
17
|
Info: #{resources_str(Eye::SystemResources.resources($$))}
|
32
18
|
Ruby: #{RUBY_DESCRIPTION}
|
19
|
+
Gems: #{%w|Celluloid Celluloid::IO ActiveSupport StateMachine NIO|.map{|c| gem_version(c) }}
|
20
|
+
Checks: #{Eye::Checker::TYPES}, #{Eye::Trigger::TYPES}
|
33
21
|
Logger: #{Eye::Logger.dev}
|
34
22
|
Socket: #{Eye::Settings::socket_path}
|
35
23
|
Pid: #{Eye::Settings::pid_path}
|
@@ -37,9 +25,9 @@ Actors: #{actors.inspect}
|
|
37
25
|
|
38
26
|
S
|
39
27
|
|
40
|
-
str += make_str(info_data_debug) + "\n" if
|
28
|
+
str += make_str(info_data_debug) + "\n" if h[:processes].present?
|
41
29
|
|
42
|
-
if
|
30
|
+
if h[:config].present?
|
43
31
|
str += "\nCurrent config: \n"
|
44
32
|
str += YAML.dump(current_config.to_h)
|
45
33
|
end
|
@@ -48,7 +36,22 @@ Actors: #{actors.inspect}
|
|
48
36
|
str
|
49
37
|
end
|
50
38
|
|
51
|
-
|
39
|
+
def info_data(*args)
|
40
|
+
{:subtree => info_objects(*args).map{|a| a.status_data } }
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def info_data_debug(*args)
|
46
|
+
{:subtree => info_objects(*args).map{|a| a.status_data(true) } }
|
47
|
+
end
|
48
|
+
|
49
|
+
def info_objects(*args)
|
50
|
+
res = []
|
51
|
+
return @applications if args.empty?
|
52
|
+
matched_objects(*args){|obj| res << obj }
|
53
|
+
res
|
54
|
+
end
|
52
55
|
|
53
56
|
def make_str(data, level = -1)
|
54
57
|
return nil if data.blank?
|
@@ -75,7 +78,7 @@ private
|
|
75
78
|
str += " (chain: #{data[:debug][:chain].map(&:to_i)})"
|
76
79
|
end
|
77
80
|
elsif data[:state]
|
78
|
-
str += ' ' + data[:state].to_s
|
81
|
+
str += ' ' + data[:state].to_s
|
79
82
|
str += ' (' + resources_str(data[:resources]) + ')' if data[:resources].present? && data[:state].to_sym == :up
|
80
83
|
str += " (#{data[:state_reason]} at #{data[:state_changed_at].to_s(:short)})" if data[:state_reason] && data[:state] == 'unmonitored'
|
81
84
|
elsif data[:current_command]
|
@@ -100,11 +103,11 @@ private
|
|
100
103
|
|
101
104
|
def resources_str(r)
|
102
105
|
return '' if r.blank?
|
103
|
-
|
106
|
+
|
104
107
|
res = "#{r[:start_time]}, #{r[:cpu]}%"
|
105
108
|
res += ", #{r[:memory] / 1024}Mb" if r[:memory]
|
106
109
|
res += ", <#{r[:pid]}>"
|
107
|
-
|
110
|
+
|
108
111
|
res
|
109
112
|
end
|
110
113
|
|
@@ -123,4 +126,14 @@ private
|
|
123
126
|
apps
|
124
127
|
end
|
125
128
|
|
129
|
+
def gem_version(klass)
|
130
|
+
v = nil
|
131
|
+
begin
|
132
|
+
v = eval("#{klass}::VERSION::STRING")
|
133
|
+
rescue
|
134
|
+
v = eval("#{klass}::VERSION") rescue ''
|
135
|
+
end
|
136
|
+
"#{klass}=#{v}"
|
137
|
+
end
|
138
|
+
|
126
139
|
end
|