eye 0.5.1 → 0.5.2
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/CHANGES.md +6 -0
- data/README.md +37 -35
- 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
|
@@ -59,8 +59,9 @@ private
|
|
59
59
|
args = ['*'] if args.empty?
|
60
60
|
res = []
|
61
61
|
matched_objects(*args) do |obj|
|
62
|
-
if
|
62
|
+
if obj.is_a?(Eye::Process)
|
63
63
|
res << obj
|
64
|
+
elsif obj.is_a?(Eye::ChildProcess)
|
64
65
|
else
|
65
66
|
res += obj.processes.to_a
|
66
67
|
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
|