reel-eye 0.5.1 → 0.5.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/CHANGES.md +6 -0
- data/README.md +44 -32
- data/examples/puma.eye +1 -1
- data/examples/test.eye +32 -30
- data/examples/unicorn.eye +1 -1
- data/lib/eye.rb +1 -1
- data/lib/eye/checker.rb +24 -1
- data/lib/eye/checker/cpu.rb +4 -14
- data/lib/eye/checker/cputime.rb +2 -12
- data/lib/eye/checker/file_ctime.rb +2 -3
- data/lib/eye/checker/file_size.rb +8 -8
- data/lib/eye/checker/http.rb +2 -2
- data/lib/eye/checker/memory.rb +4 -14
- data/lib/eye/checker/runtime.rb +2 -12
- data/lib/eye/checker/socket.rb +1 -1
- data/lib/eye/cli.rb +6 -0
- data/lib/eye/cli/commands.rb +2 -3
- data/lib/eye/cli/render.rb +4 -4
- data/lib/eye/cli/server.rb +4 -4
- data/lib/eye/controller.rb +1 -1
- data/lib/eye/controller/load.rb +14 -13
- data/lib/eye/controller/send_command.rb +4 -4
- data/lib/eye/controller/status.rb +2 -1
- data/lib/eye/dsl.rb +1 -1
- data/lib/eye/dsl/child_process_opts.rb +2 -2
- data/lib/eye/dsl/opts.rb +5 -1
- data/lib/eye/dsl/validation.rb +2 -2
- data/lib/eye/group/chain.rb +2 -2
- data/lib/eye/notify.rb +3 -3
- data/lib/eye/process.rb +7 -7
- data/lib/eye/process/children.rb +60 -0
- data/lib/eye/process/commands.rb +40 -37
- data/lib/eye/process/config.rb +5 -5
- data/lib/eye/process/controller.rb +8 -8
- data/lib/eye/process/data.rb +4 -4
- data/lib/eye/process/monitor.rb +17 -17
- data/lib/eye/process/scheduler.rb +1 -1
- data/lib/eye/process/states.rb +3 -3
- data/lib/eye/process/system.rb +3 -3
- data/lib/eye/process/validate.rb +1 -1
- data/lib/eye/process/watchers.rb +6 -6
- data/lib/eye/server.rb +1 -1
- data/lib/eye/system.rb +4 -4
- data/lib/eye/system_resources.rb +3 -3
- data/lib/eye/trigger.rb +4 -6
- data/lib/eye/trigger/flapping.rb +2 -2
- data/lib/eye/trigger/stop_children.rb +14 -0
- metadata +4 -4
- data/lib/eye/process/child.rb +0 -60
- data/lib/eye/trigger/stop_childs.rb +0 -10
data/lib/eye/checker/http.rb
CHANGED
@@ -2,7 +2,7 @@ require 'net/http'
|
|
2
2
|
|
3
3
|
class Eye::Checker::Http < Eye::Checker::Defer
|
4
4
|
|
5
|
-
#
|
5
|
+
# check :http, :every => 5.seconds, :times => 1,
|
6
6
|
# :url => "http://127.0.0.1:3000/", :kind => :success, :pattern => /OK/, :timeout => 3.seconds
|
7
7
|
|
8
8
|
param :url, String, true
|
@@ -93,4 +93,4 @@ private
|
|
93
93
|
end
|
94
94
|
end
|
95
95
|
|
96
|
-
end
|
96
|
+
end
|
data/lib/eye/checker/memory.rb
CHANGED
@@ -1,11 +1,9 @@
|
|
1
|
-
class Eye::Checker::Memory < Eye::Checker
|
1
|
+
class Eye::Checker::Memory < Eye::Checker::Measure
|
2
2
|
|
3
|
-
#
|
4
|
-
|
5
|
-
param :below, [Fixnum, Float], true
|
3
|
+
# check :memory, :every => 3.seconds, :below => 80.megabytes, :times => [3,5]
|
6
4
|
|
7
5
|
def check_name
|
8
|
-
@check_name ||= "memory(#{
|
6
|
+
@check_name ||= "memory(#{measure_str})"
|
9
7
|
end
|
10
8
|
|
11
9
|
def get_value
|
@@ -16,12 +14,4 @@ class Eye::Checker::Memory < Eye::Checker
|
|
16
14
|
"#{value.to_i / 1024 / 1024}Mb"
|
17
15
|
end
|
18
16
|
|
19
|
-
|
20
|
-
if below
|
21
|
-
value < below
|
22
|
-
else
|
23
|
-
true
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
end
|
17
|
+
end
|
data/lib/eye/checker/runtime.rb
CHANGED
@@ -1,9 +1,7 @@
|
|
1
|
-
class Eye::Checker::Runtime < Eye::Checker
|
1
|
+
class Eye::Checker::Runtime < Eye::Checker::Measure
|
2
2
|
|
3
3
|
# check :runtime, :every => 1.minute, :below => 120.minutes
|
4
4
|
|
5
|
-
param :below, [Fixnum, Float], true
|
6
|
-
|
7
5
|
def get_value
|
8
6
|
st = Eye::SystemResources.start_time(@pid)
|
9
7
|
if st
|
@@ -17,12 +15,4 @@ class Eye::Checker::Runtime < Eye::Checker
|
|
17
15
|
"#{value / 60}m"
|
18
16
|
end
|
19
17
|
|
20
|
-
|
21
|
-
if below
|
22
|
-
value < below
|
23
|
-
else
|
24
|
-
true
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
end
|
18
|
+
end
|
data/lib/eye/checker/socket.rb
CHANGED
data/lib/eye/cli.rb
CHANGED
@@ -13,6 +13,9 @@ class Eye::Cli < Thor
|
|
13
13
|
desc "info [MASK]", "processes info"
|
14
14
|
def info(mask = nil)
|
15
15
|
res = cmd(:info_data, *Array(mask))
|
16
|
+
if mask && res[:subtree] && res[:subtree].empty?
|
17
|
+
error!("command :info, objects not found!")
|
18
|
+
end
|
16
19
|
say render_info(res)
|
17
20
|
say
|
18
21
|
end
|
@@ -41,6 +44,9 @@ class Eye::Cli < Thor
|
|
41
44
|
desc "history [MASK,...]", "processes history"
|
42
45
|
def history(*masks)
|
43
46
|
res = cmd(:history_data, *masks)
|
47
|
+
if !masks.empty? && res && res.empty?
|
48
|
+
error!("command :history, objects not found!")
|
49
|
+
end
|
44
50
|
say render_history(res)
|
45
51
|
say
|
46
52
|
end
|
data/lib/eye/cli/commands.rb
CHANGED
@@ -15,9 +15,9 @@ private
|
|
15
15
|
res = _cmd(cmd, *args)
|
16
16
|
|
17
17
|
if res == :not_started
|
18
|
-
error! "socket(#{Eye::Local.socket_path}) not found, did you `eye load`?"
|
18
|
+
error! "socket(#{Eye::Local.socket_path}) not found, did you run `eye load`?"
|
19
19
|
elsif res == :timeouted
|
20
|
-
error! 'eye
|
20
|
+
error! 'eye timed out without responding...'
|
21
21
|
end
|
22
22
|
|
23
23
|
res
|
@@ -26,7 +26,6 @@ private
|
|
26
26
|
def say_load_result(res = {}, opts = {})
|
27
27
|
error!(res) unless res.is_a?(Hash)
|
28
28
|
say_filename = (res.size > 1)
|
29
|
-
say 'eye started!', :green if opts[:started]
|
30
29
|
error = false
|
31
30
|
res.each do |filename, _res|
|
32
31
|
say "#{filename}: ", nil, true if say_filename
|
data/lib/eye/cli/render.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Eye::Cli::Render
|
2
2
|
private
|
3
3
|
def render_info(data)
|
4
|
-
error!("unexpected server
|
4
|
+
error!("unexpected server response #{data.inspect}") unless data.is_a?(Hash)
|
5
5
|
|
6
6
|
make_str data
|
7
7
|
end
|
@@ -62,7 +62,7 @@ private
|
|
62
62
|
end
|
63
63
|
|
64
64
|
def render_debug_info(data)
|
65
|
-
error!("unexpected server
|
65
|
+
error!("unexpected server response #{data.inspect}") unless data.is_a?(Hash)
|
66
66
|
|
67
67
|
s = ""
|
68
68
|
|
@@ -90,7 +90,7 @@ private
|
|
90
90
|
end
|
91
91
|
|
92
92
|
def render_history(data)
|
93
|
-
error!("unexpected server
|
93
|
+
error!("unexpected server response #{data.inspect}") unless data.is_a?(Hash)
|
94
94
|
|
95
95
|
res = []
|
96
96
|
data.each do |name, data|
|
@@ -103,7 +103,7 @@ private
|
|
103
103
|
def detail_process_info(name, history)
|
104
104
|
return if history.empty?
|
105
105
|
|
106
|
-
res = "\033[1m#{name}\033[0m
|
106
|
+
res = "\033[1m#{name}\033[0m\n"
|
107
107
|
history = history.reverse
|
108
108
|
|
109
109
|
history.chunk{|h| [h[:state], h[:reason].to_s] }.each do |_, hist|
|
data/lib/eye/cli/server.rb
CHANGED
@@ -51,15 +51,15 @@ private
|
|
51
51
|
File.open(Eye::Local.pid_path, 'w'){|f| f.write(pid) }
|
52
52
|
|
53
53
|
unless wait_server
|
54
|
-
error! 'server not
|
54
|
+
error! 'server has not started in 15 seconds, something is very wrong'
|
55
55
|
end
|
56
56
|
|
57
57
|
configs.unshift(Eye::Local.eyeconfig) if File.exists?(Eye::Local.eyeconfig)
|
58
58
|
|
59
|
+
say 'eye started!', :green
|
60
|
+
|
59
61
|
if !configs.empty?
|
60
|
-
say_load_result cmd(:load, *configs)
|
61
|
-
else
|
62
|
-
say 'started!', :green
|
62
|
+
say_load_result cmd(:load, *configs)
|
63
63
|
end
|
64
64
|
end
|
65
65
|
|
data/lib/eye/controller.rb
CHANGED
data/lib/eye/controller/load.rb
CHANGED
@@ -11,7 +11,7 @@ module Eye::Controller::Load
|
|
11
11
|
def load(*args)
|
12
12
|
h = args.extract_options!
|
13
13
|
obj_strs = args.flatten
|
14
|
-
info "
|
14
|
+
info "loading: #{obj_strs}"
|
15
15
|
|
16
16
|
res = Hash.new
|
17
17
|
|
@@ -42,7 +42,7 @@ private
|
|
42
42
|
rescue Eye::Dsl::Error, Exception, NoMethodError => ex
|
43
43
|
raise if ex.class.to_s.include?('RR') # skip RR exceptions
|
44
44
|
|
45
|
-
error "
|
45
|
+
error "loading: config error <#{filename}>: #{ex.message}"
|
46
46
|
|
47
47
|
# filter backtrace for user output
|
48
48
|
bt = (ex.backtrace || [])
|
@@ -65,7 +65,7 @@ private
|
|
65
65
|
filename
|
66
66
|
end
|
67
67
|
|
68
|
-
debug "
|
68
|
+
debug "loading: globbing mask #{mask}"
|
69
69
|
|
70
70
|
sub = []
|
71
71
|
Dir[mask].each do |config_path|
|
@@ -81,16 +81,17 @@ private
|
|
81
81
|
|
82
82
|
# return: result, config
|
83
83
|
def parse_config(filename)
|
84
|
-
debug "
|
84
|
+
debug "parsing: #{filename}"
|
85
85
|
|
86
86
|
cfg = Eye::Dsl.parse(nil, filename)
|
87
87
|
@current_config.merge(cfg).validate! # just validate summary config here
|
88
|
+
Eye.parsed_config = nil # remove link on config, for better gc
|
88
89
|
cfg
|
89
90
|
end
|
90
91
|
|
91
92
|
# !!! exclusive operation
|
92
93
|
def load_config(filename, config)
|
93
|
-
info "
|
94
|
+
info "loading: #{filename}"
|
94
95
|
new_cfg = @current_config.merge(config)
|
95
96
|
new_cfg.validate!
|
96
97
|
|
@@ -111,7 +112,7 @@ private
|
|
111
112
|
|
112
113
|
# create objects as diff, from configs
|
113
114
|
def create_objects(apps_config, changed_apps = [])
|
114
|
-
debug '
|
115
|
+
debug 'creating objects'
|
115
116
|
|
116
117
|
apps_config.each do |app_name, app_cfg|
|
117
118
|
update_or_create_application(app_name, app_cfg.clone) if changed_apps.include?(app_name)
|
@@ -137,9 +138,9 @@ private
|
|
137
138
|
|
138
139
|
@applications.delete(app)
|
139
140
|
|
140
|
-
debug "
|
141
|
+
debug "updating app: #{app_name}"
|
141
142
|
else
|
142
|
-
debug "
|
143
|
+
debug "creating app: #{app_name}"
|
143
144
|
end
|
144
145
|
|
145
146
|
app = Eye::Application.new(app_name, app_config)
|
@@ -182,13 +183,13 @@ private
|
|
182
183
|
|
183
184
|
def update_or_create_group(group_name, group_config)
|
184
185
|
group = if @old_groups[group_name]
|
185
|
-
debug "
|
186
|
+
debug "updating group: #{group_name}"
|
186
187
|
group = @old_groups.delete(group_name)
|
187
188
|
group.schedule :update_config, group_config, Eye::Reason::User.new(:'load config')
|
188
189
|
group.clear
|
189
190
|
group
|
190
191
|
else
|
191
|
-
debug "
|
192
|
+
debug "creating group: #{group_name}"
|
192
193
|
gr = Eye::Group.new(group_name, group_config)
|
193
194
|
@added_groups << gr
|
194
195
|
gr
|
@@ -209,16 +210,16 @@ private
|
|
209
210
|
key = @old_processes[name] ? name : @old_processes.keys.detect { |n| n.end_with?(postfix) }
|
210
211
|
|
211
212
|
if @old_processes[key]
|
212
|
-
debug "
|
213
|
+
debug "updating process: #{name}"
|
213
214
|
process = @old_processes.delete(key)
|
214
215
|
process.schedule :update_config, process_cfg, Eye::Reason::User.new(:'load config')
|
215
216
|
process
|
216
217
|
else
|
217
|
-
debug "
|
218
|
+
debug "creating process: #{name}"
|
218
219
|
process = Eye::Process.new(process_cfg)
|
219
220
|
@added_processes << process
|
220
221
|
process
|
221
222
|
end
|
222
223
|
end
|
223
224
|
|
224
|
-
end
|
225
|
+
end
|
@@ -124,7 +124,7 @@ private
|
|
124
124
|
return apps if apps.size > 0
|
125
125
|
|
126
126
|
if objs.map(&:app_name).uniq.size > 1
|
127
|
-
raise Error, "
|
127
|
+
raise Error, "cannot match targets from different applications: #{res.map(&:full_name)}"
|
128
128
|
end
|
129
129
|
end
|
130
130
|
|
@@ -150,9 +150,9 @@ private
|
|
150
150
|
res << p if p.name =~ r || p.full_name =~ r
|
151
151
|
|
152
152
|
# child matching
|
153
|
-
if p.
|
154
|
-
|
155
|
-
res +=
|
153
|
+
if p.children.present?
|
154
|
+
children = p.children.values
|
155
|
+
res += children.select do |ch|
|
156
156
|
name = ch.name rescue ''
|
157
157
|
full_name = ch.full_name rescue ''
|
158
158
|
name =~ r || full_name =~ r
|
@@ -60,8 +60,9 @@ private
|
|
60
60
|
args = ['*'] if args.empty?
|
61
61
|
res = []
|
62
62
|
matched_objects(*args) do |obj|
|
63
|
-
if
|
63
|
+
if obj.is_a?(Eye::Process)
|
64
64
|
res << obj
|
65
|
+
elsif obj.is_a?(Eye::ChildProcess)
|
65
66
|
else
|
66
67
|
res += obj.processes.to_a
|
67
68
|
end
|
data/lib/eye/dsl.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
class Eye::Dsl::ChildProcessOpts < Eye::Dsl::Opts
|
2
2
|
|
3
3
|
def allow_options
|
4
|
-
[:stop_command, :restart_command, :
|
4
|
+
[:stop_command, :restart_command, :children_update_period,
|
5
5
|
:stop_signals, :stop_grace, :stop_timeout, :restart_timeout]
|
6
6
|
end
|
7
7
|
|
8
8
|
def triggers(*args)
|
9
|
-
raise Eye::Dsl::Error, 'triggers
|
9
|
+
raise Eye::Dsl::Error, 'triggers not allowed in monitor_children'
|
10
10
|
end
|
11
11
|
alias trigger triggers
|
12
12
|
|
data/lib/eye/dsl/opts.rb
CHANGED
@@ -8,7 +8,7 @@ class Eye::Dsl::Opts < Eye::Dsl::PureOpts
|
|
8
8
|
create_options_methods(BOOL_OPTIONS, [TrueClass, FalseClass])
|
9
9
|
|
10
10
|
INTERVAL_OPTIONS = [ :check_alive_period, :start_timeout, :restart_timeout, :stop_timeout, :start_grace,
|
11
|
-
:restart_grace, :stop_grace, :
|
11
|
+
:restart_grace, :stop_grace, :children_update_period, :restore_in ]
|
12
12
|
create_options_methods(INTERVAL_OPTIONS, [Fixnum, Float])
|
13
13
|
|
14
14
|
create_options_methods([:environment], Hash)
|
@@ -111,6 +111,10 @@ class Eye::Dsl::Opts < Eye::Dsl::PureOpts
|
|
111
111
|
set_daemonize true
|
112
112
|
end
|
113
113
|
|
114
|
+
def clear_bundler_env
|
115
|
+
env('GEM_PATH' => nil, 'GEM_HOME' => nil, 'RUBYOPT' => nil, 'BUNDLE_BIN_PATH' => nil, 'BUNDLE_GEMFILE' => nil)
|
116
|
+
end
|
117
|
+
|
114
118
|
def scoped(&block)
|
115
119
|
h = self.class.new(self.name, self)
|
116
120
|
h.instance_eval(&block)
|
data/lib/eye/dsl/validation.rb
CHANGED
@@ -49,10 +49,10 @@ module Eye::Dsl::Validation
|
|
49
49
|
if value && !value.is_a?(Proc)
|
50
50
|
if value.is_a?(Array)
|
51
51
|
if (value - self.variants[param]).present?
|
52
|
-
raise Error, "#{value.inspect} should within #{self.variants[param].inspect}"
|
52
|
+
raise Error, "#{value.inspect} should be within #{self.variants[param].inspect}"
|
53
53
|
end
|
54
54
|
elsif !self.variants[param].include?(value)
|
55
|
-
raise Error, "#{value.inspect} should within #{self.variants[param].inspect}"
|
55
|
+
raise Error, "#{value.inspect} should be within #{self.variants[param].inspect}"
|
56
56
|
end
|
57
57
|
end
|
58
58
|
end
|
data/lib/eye/group/chain.rb
CHANGED
@@ -3,7 +3,7 @@ module Eye::Group::Chain
|
|
3
3
|
private
|
4
4
|
|
5
5
|
def chain_schedule(type, grace, command, *args)
|
6
|
-
info "
|
6
|
+
info "starting #{type} with #{grace}s chain #{command} #{args}"
|
7
7
|
|
8
8
|
@chain_processes_count = @processes.size
|
9
9
|
@chain_processes_current = 0
|
@@ -78,4 +78,4 @@ private
|
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
81
|
-
end
|
81
|
+
end
|
data/lib/eye/notify.rb
CHANGED
@@ -9,7 +9,7 @@ class Eye::Notify
|
|
9
9
|
|
10
10
|
def self.get_class(type)
|
11
11
|
klass = eval("Eye::Notify::#{TYPES[type]}") rescue nil
|
12
|
-
raise "
|
12
|
+
raise "unknown notifier :#{type}" unless klass
|
13
13
|
if deps = klass.depends_on
|
14
14
|
Array(deps).each { |d| require d }
|
15
15
|
end
|
@@ -26,7 +26,7 @@ class Eye::Notify
|
|
26
26
|
needed_hash = (settings[:contacts] || {})[contact]
|
27
27
|
|
28
28
|
if needed_hash.blank?
|
29
|
-
error "
|
29
|
+
error "contact #{contact} not found; check your configuration"
|
30
30
|
return
|
31
31
|
end
|
32
32
|
|
@@ -74,7 +74,7 @@ class Eye::Notify
|
|
74
74
|
end
|
75
75
|
|
76
76
|
def execute
|
77
|
-
raise
|
77
|
+
raise NotImplementedError
|
78
78
|
end
|
79
79
|
|
80
80
|
param :contact, [String]
|
data/lib/eye/process.rb
CHANGED
@@ -11,22 +11,22 @@ class Eye::Process
|
|
11
11
|
autoload :System, 'eye/process/system'
|
12
12
|
autoload :Controller, 'eye/process/controller'
|
13
13
|
autoload :StatesHistory, 'eye/process/states_history'
|
14
|
-
autoload :
|
14
|
+
autoload :Children, 'eye/process/children'
|
15
15
|
autoload :Trigger, 'eye/process/trigger'
|
16
16
|
autoload :Notify, 'eye/process/notify'
|
17
17
|
autoload :Scheduler, 'eye/process/scheduler'
|
18
18
|
autoload :Validate, 'eye/process/validate'
|
19
19
|
|
20
20
|
attr_accessor :pid, :watchers, :config, :states_history,
|
21
|
-
:
|
21
|
+
:children, :triggers, :name, :state_reason, :flapping_times
|
22
22
|
|
23
23
|
def initialize(config)
|
24
|
-
raise '
|
24
|
+
raise 'you must supply a pid_file location' unless config[:pid_file]
|
25
25
|
|
26
26
|
@config = prepare_config(config)
|
27
27
|
|
28
28
|
@watchers = {}
|
29
|
-
@
|
29
|
+
@children = {}
|
30
30
|
@triggers = []
|
31
31
|
@name = @config[:name]
|
32
32
|
@flapping_times = 0
|
@@ -34,7 +34,7 @@ class Eye::Process
|
|
34
34
|
@states_history = Eye::Process::StatesHistory.new(100)
|
35
35
|
@states_history << :unmonitored
|
36
36
|
|
37
|
-
debug "
|
37
|
+
debug "creating with config: #{@config.inspect}"
|
38
38
|
|
39
39
|
add_triggers
|
40
40
|
|
@@ -63,8 +63,8 @@ class Eye::Process
|
|
63
63
|
# system methods:
|
64
64
|
include Eye::Process::System
|
65
65
|
|
66
|
-
# manage
|
67
|
-
include Eye::Process::
|
66
|
+
# manage child methods
|
67
|
+
include Eye::Process::Children
|
68
68
|
|
69
69
|
# manage triggers methods
|
70
70
|
include Eye::Process::Trigger
|