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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/CHANGES.md +6 -0
  4. data/README.md +44 -32
  5. data/examples/puma.eye +1 -1
  6. data/examples/test.eye +32 -30
  7. data/examples/unicorn.eye +1 -1
  8. data/lib/eye.rb +1 -1
  9. data/lib/eye/checker.rb +24 -1
  10. data/lib/eye/checker/cpu.rb +4 -14
  11. data/lib/eye/checker/cputime.rb +2 -12
  12. data/lib/eye/checker/file_ctime.rb +2 -3
  13. data/lib/eye/checker/file_size.rb +8 -8
  14. data/lib/eye/checker/http.rb +2 -2
  15. data/lib/eye/checker/memory.rb +4 -14
  16. data/lib/eye/checker/runtime.rb +2 -12
  17. data/lib/eye/checker/socket.rb +1 -1
  18. data/lib/eye/cli.rb +6 -0
  19. data/lib/eye/cli/commands.rb +2 -3
  20. data/lib/eye/cli/render.rb +4 -4
  21. data/lib/eye/cli/server.rb +4 -4
  22. data/lib/eye/controller.rb +1 -1
  23. data/lib/eye/controller/load.rb +14 -13
  24. data/lib/eye/controller/send_command.rb +4 -4
  25. data/lib/eye/controller/status.rb +2 -1
  26. data/lib/eye/dsl.rb +1 -1
  27. data/lib/eye/dsl/child_process_opts.rb +2 -2
  28. data/lib/eye/dsl/opts.rb +5 -1
  29. data/lib/eye/dsl/validation.rb +2 -2
  30. data/lib/eye/group/chain.rb +2 -2
  31. data/lib/eye/notify.rb +3 -3
  32. data/lib/eye/process.rb +7 -7
  33. data/lib/eye/process/children.rb +60 -0
  34. data/lib/eye/process/commands.rb +40 -37
  35. data/lib/eye/process/config.rb +5 -5
  36. data/lib/eye/process/controller.rb +8 -8
  37. data/lib/eye/process/data.rb +4 -4
  38. data/lib/eye/process/monitor.rb +17 -17
  39. data/lib/eye/process/scheduler.rb +1 -1
  40. data/lib/eye/process/states.rb +3 -3
  41. data/lib/eye/process/system.rb +3 -3
  42. data/lib/eye/process/validate.rb +1 -1
  43. data/lib/eye/process/watchers.rb +6 -6
  44. data/lib/eye/server.rb +1 -1
  45. data/lib/eye/system.rb +4 -4
  46. data/lib/eye/system_resources.rb +3 -3
  47. data/lib/eye/trigger.rb +4 -6
  48. data/lib/eye/trigger/flapping.rb +2 -2
  49. data/lib/eye/trigger/stop_children.rb +14 -0
  50. metadata +4 -4
  51. data/lib/eye/process/child.rb +0 -60
  52. data/lib/eye/trigger/stop_childs.rb +0 -10
@@ -2,7 +2,7 @@ require 'net/http'
2
2
 
3
3
  class Eye::Checker::Http < Eye::Checker::Defer
4
4
 
5
- # checks :http, :every => 5.seconds, :times => 1,
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
@@ -1,11 +1,9 @@
1
- class Eye::Checker::Memory < Eye::Checker
1
+ class Eye::Checker::Memory < Eye::Checker::Measure
2
2
 
3
- # checks :memory, :every => 3.seconds, :below => 80.megabytes, :times => [3,5]
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(#{human_value(below)})"
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
- def good?(value)
20
- if below
21
- value < below
22
- else
23
- true
24
- end
25
- end
26
-
27
- end
17
+ end
@@ -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
- def good?(value)
21
- if below
22
- value < below
23
- else
24
- true
25
- end
26
- end
27
-
28
- end
18
+ end
@@ -1,6 +1,6 @@
1
1
  class Eye::Checker::Socket < Eye::Checker::Defer
2
2
 
3
- # checks :socket, :every => 5.seconds, :times => 1,
3
+ # check :socket, :every => 5.seconds, :times => 1,
4
4
  # :addr => "unix:/var/run/daemon.sock", :timeout => 3.seconds,
5
5
  #
6
6
  # Available parameters:
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
@@ -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 does not answer, timeouted...'
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
@@ -1,7 +1,7 @@
1
1
  module Eye::Cli::Render
2
2
  private
3
3
  def render_info(data)
4
- error!("unexpected server answer #{data.inspect}") unless data.is_a?(Hash)
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 answer #{data.inspect}") unless data.is_a?(Hash)
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 answer #{data.inspect}") unless data.is_a?(Hash)
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:\n"
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|
@@ -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 runned in 15 seconds, something crazy wrong'
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), :started => true
61
- else
62
- say 'started!', :green
62
+ say_load_result cmd(:load, *configs)
63
63
  end
64
64
  end
65
65
 
@@ -40,7 +40,7 @@ class Eye::Controller
40
40
  Celluloid::logger = Eye::Logger.new('celluloid')
41
41
  Eye::SystemResources.cache
42
42
 
43
- info "starting #{Eye::ABOUT} (#{$$})"
43
+ info "starting #{Eye::ABOUT} <#{$$}>"
44
44
  end
45
45
 
46
46
  def settings
@@ -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 "load: #{obj_strs}"
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 "load: config error <#{filename}>: #{ex.message}"
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 "load: globbing mask #{mask}"
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 "parse #{filename}"
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 "load #{filename}"
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 'create objects'
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 "update app #{app_name}"
141
+ debug "updating app: #{app_name}"
141
142
  else
142
- debug "create app #{app_name}"
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 "update group #{group_name}"
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 "create group #{group_name}"
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 "update process #{name}"
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 "create process #{name}"
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, "cant match targets from different applications: #{res.map(&:full_name)}"
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.childs.present?
154
- childs = p.childs.values
155
- res += childs.select do |ch|
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 (obj.is_a?(Eye::Process) || obj.is_a?(Eye::ChildProcess))
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
@@ -43,7 +43,7 @@ class Eye::Dsl
43
43
  end
44
44
 
45
45
  def check_name(name)
46
- raise Error, "not allow ':' in name '#{name}'" if name.to_s.include?(':')
46
+ raise Error, "':' is not allowed in name '#{name}'" if name.to_s.include?(':')
47
47
  end
48
48
  end
49
49
  end
@@ -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, :childs_update_period,
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 does not allowed in monitor_children'
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, :childs_update_period, :restore_in ]
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)
@@ -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
@@ -3,7 +3,7 @@ module Eye::Group::Chain
3
3
  private
4
4
 
5
5
  def chain_schedule(type, grace, command, *args)
6
- info "start #{type} with #{grace}s chain #{command} #{args}"
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 "Unknown notify #{type}" unless klass
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 "not found contact #{contact}! something wrong with config"
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 'realize me'
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 :Child, 'eye/process/child'
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
- :childs, :triggers, :name, :state_reason, :flapping_times
21
+ :children, :triggers, :name, :state_reason, :flapping_times
22
22
 
23
23
  def initialize(config)
24
- raise 'pid file should be' unless config[:pid_file]
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
- @childs = {}
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 "create with config: #{@config.inspect}"
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 childs methods
67
- include Eye::Process::Child
66
+ # manage child methods
67
+ include Eye::Process::Children
68
68
 
69
69
  # manage triggers methods
70
70
  include Eye::Process::Trigger