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.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.travis.yml +4 -0
  4. data/CHANGES.md +11 -0
  5. data/README.md +3 -3
  6. data/Rakefile +8 -0
  7. data/bin/eye +0 -316
  8. data/bin/loader_eye +3 -3
  9. data/examples/test.eye +2 -2
  10. data/eye.gemspec +4 -9
  11. data/lib/eye.rb +4 -2
  12. data/lib/eye/application.rb +3 -3
  13. data/lib/eye/checker.rb +14 -5
  14. data/lib/eye/checker/cputime.rb +23 -0
  15. data/lib/eye/checker/file_touched.rb +15 -0
  16. data/lib/eye/checker/http.rb +7 -9
  17. data/lib/eye/checker/memory.rb +1 -1
  18. data/lib/eye/checker/runtime.rb +28 -0
  19. data/lib/eye/checker/socket.rb +4 -4
  20. data/lib/eye/cli.rb +166 -0
  21. data/lib/eye/cli/commands.rb +79 -0
  22. data/lib/eye/cli/render.rb +137 -0
  23. data/lib/eye/cli/server.rb +85 -0
  24. data/lib/eye/client.rb +3 -3
  25. data/lib/eye/config.rb +17 -14
  26. data/lib/eye/controller.rb +6 -10
  27. data/lib/eye/controller/commands.rb +6 -10
  28. data/lib/eye/controller/helpers.rb +1 -1
  29. data/lib/eye/controller/send_command.rb +5 -2
  30. data/lib/eye/controller/status.rb +37 -105
  31. data/lib/eye/dsl.rb +1 -1
  32. data/lib/eye/dsl/application_opts.rb +6 -2
  33. data/lib/eye/dsl/child_process_opts.rb +3 -2
  34. data/lib/eye/dsl/config_opts.rb +2 -2
  35. data/lib/eye/dsl/group_opts.rb +2 -1
  36. data/lib/eye/dsl/main.rb +4 -2
  37. data/lib/eye/dsl/opts.rb +11 -4
  38. data/lib/eye/dsl/validation.rb +49 -43
  39. data/lib/eye/group.rb +1 -1
  40. data/lib/eye/loader.rb +5 -9
  41. data/lib/eye/{settings.rb → local.rb} +1 -1
  42. data/lib/eye/logger.rb +5 -0
  43. data/lib/eye/notify.rb +12 -6
  44. data/lib/eye/notify/jabber.rb +2 -2
  45. data/lib/eye/process/child.rb +3 -1
  46. data/lib/eye/process/commands.rb +2 -2
  47. data/lib/eye/process/controller.rb +1 -1
  48. data/lib/eye/process/trigger.rb +1 -1
  49. data/lib/eye/sigar.rb +5 -0
  50. data/lib/eye/system.rb +7 -6
  51. data/lib/eye/system_resources.rb +46 -41
  52. data/lib/eye/trigger.rb +15 -8
  53. data/lib/eye/trigger/flapping.rb +1 -1
  54. data/lib/eye/trigger/stop_childs.rb +1 -1
  55. data/lib/eye/trigger/transition.rb +15 -0
  56. data/lib/eye/utils.rb +12 -0
  57. data/lib/eye/utils/leak_19.rb +7 -0
  58. data/lib/eye/utils/mini_active_support.rb +106 -0
  59. metadata +24 -15
  60. data/lib/eye/controller/show_history.rb +0 -63
  61. data/lib/eye/trigger/state.rb +0 -11
@@ -20,7 +20,7 @@ class Eye::Dsl
20
20
  class << self
21
21
  attr_accessor :verbose
22
22
 
23
- def debug(msg = "")
23
+ def debug(msg = '')
24
24
  puts msg if verbose
25
25
  end
26
26
 
@@ -3,7 +3,7 @@ class Eye::Dsl::ApplicationOpts < Eye::Dsl::Opts
3
3
  include Eye::Dsl::Chain
4
4
 
5
5
  def disallow_options
6
- [:pid_file, :start_command]
6
+ [:pid_file, :start_command, :daemonize]
7
7
  end
8
8
 
9
9
  def not_seed_options
@@ -15,6 +15,7 @@ class Eye::Dsl::ApplicationOpts < Eye::Dsl::Opts
15
15
 
16
16
  opts = Eye::Dsl::GroupOpts.new(name, self)
17
17
  opts.instance_eval(&block)
18
+
18
19
  if cfg = opts.config
19
20
  @config[:groups] ||= {}
20
21
 
@@ -26,10 +27,13 @@ class Eye::Dsl::ApplicationOpts < Eye::Dsl::Opts
26
27
  end
27
28
 
28
29
  Eye::Dsl.debug "<= group #{name}"
30
+ opts
29
31
  end
30
32
 
31
33
  def process(name, &block)
32
- group("__default__"){ process(name.to_s, &block) }
34
+ res = nil
35
+ group('__default__'){ res = process(name.to_s, &block) }
36
+ res
33
37
  end
34
38
 
35
39
  alias xgroup nop
@@ -6,7 +6,8 @@ class Eye::Dsl::ChildProcessOpts < Eye::Dsl::Opts
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 does not allowed in monitor_children'
10
10
  end
11
+ alias trigger triggers
11
12
 
12
- end
13
+ end
@@ -23,7 +23,7 @@ class Eye::Dsl::ConfigOpts < Eye::Dsl::PureOpts
23
23
 
24
24
  def contact(contact_name, contact_type, contact, contact_opts = {})
25
25
  raise Eye::Dsl::Error, "unknown contact_type #{contact_type}" unless Eye::Notify::TYPES[contact_type]
26
- raise Eye::Dsl::Error, "contact should be a String" unless contact.is_a?(String)
26
+ raise Eye::Dsl::Error, 'contact should be a String' unless contact.is_a?(String)
27
27
 
28
28
  notify_hash = @config[contact_type] || (@parent && @parent.config[contact_type]) || Eye::parsed_config.settings[contact_type] || {}
29
29
  validate_hash = notify_hash.merge(contact_opts).merge(:type => contact_type)
@@ -46,4 +46,4 @@ class Eye::Dsl::ConfigOpts < Eye::Dsl::PureOpts
46
46
  end
47
47
  end
48
48
 
49
- end
49
+ end
@@ -3,7 +3,7 @@ class Eye::Dsl::GroupOpts < Eye::Dsl::Opts
3
3
  include Eye::Dsl::Chain
4
4
 
5
5
  def disallow_options
6
- [:pid_file, :start_command]
6
+ [:pid_file, :start_command, :daemonize]
7
7
  end
8
8
 
9
9
  def not_seed_options
@@ -19,6 +19,7 @@ class Eye::Dsl::GroupOpts < Eye::Dsl::Opts
19
19
  @config[:processes][name.to_s] = opts.config if opts.config
20
20
 
21
21
  Eye::Dsl.debug "<= process #{name}"
22
+ opts
22
23
  end
23
24
 
24
25
  alias xprocess nop
@@ -29,13 +29,15 @@ module Eye::Dsl::Main
29
29
  end
30
30
 
31
31
  def config(&block)
32
- Eye::Dsl.debug "=> config"
32
+ Eye::Dsl.debug '=> config'
33
33
 
34
34
  opts = Eye::Dsl::ConfigOpts.new
35
35
  opts.instance_eval(&block)
36
36
  @parsed_config.settings.merge!(opts.config)
37
37
 
38
- Eye::Dsl.debug "<= config"
38
+ Eye::Dsl.debug '<= config'
39
39
  end
40
40
 
41
+ alias settings config
42
+
41
43
  end
@@ -98,26 +98,33 @@ class Eye::Dsl::Opts < Eye::Dsl::PureOpts
98
98
  end
99
99
 
100
100
  def set_uid(value)
101
- raise Eye::Dsl::Error, ":uid not supported by ruby (needed 2.0)" unless Eye::Settings.supported_setsid?
101
+ raise Eye::Dsl::Error, ':uid not supported (use ruby >= 2.0)' unless Eye::Local.supported_setsid?
102
102
  super
103
103
  end
104
104
 
105
105
  def set_gid(value)
106
- raise Eye::Dsl::Error, ":gid not supported by ruby (needed 2.0)" unless Eye::Settings.supported_setsid?
106
+ raise Eye::Dsl::Error, ':gid not supported (use ruby >= 2.0)' unless Eye::Local.supported_setsid?
107
107
  super
108
108
  end
109
109
 
110
110
  def scoped(&block)
111
111
  h = self.class.new(self.name, self)
112
112
  h.instance_eval(&block)
113
+
113
114
  groups = h.config.delete :groups
114
- processes = h.config.delete :processes
115
115
 
116
116
  if groups.present?
117
117
  config[:groups] ||= {}
118
- config[:groups].merge!(groups)
118
+ groups.each do |name, cfg|
119
+ processes = cfg.delete(:processes) || {}
120
+ config[:groups][name] ||= {}
121
+ config[:groups][name].merge!(cfg)
122
+ config[:groups][name][:processes] ||= {}
123
+ config[:groups][name][:processes].merge!(processes)
124
+ end
119
125
  end
120
126
 
127
+ processes = h.config.delete :processes
121
128
  if processes.present?
122
129
  config[:processes] ||= {}
123
130
  config[:processes].merge!(processes)
@@ -1,66 +1,72 @@
1
1
  module Eye::Dsl::Validation
2
+ def self.included(base)
3
+ base.extend(ClassMethods)
4
+ end
5
+
2
6
  class Error < Exception; end
3
7
 
4
- def inherited(subclass)
5
- subclass.validates = self.validates.clone
6
- subclass.should_bes = self.should_bes.clone
7
- subclass.defaults = self.defaults.clone
8
- subclass.variants = self.variants.clone
9
- end
8
+ module ClassMethods
9
+ def inherited(subclass)
10
+ subclass.validates = self.validates.clone
11
+ subclass.should_bes = self.should_bes.clone
12
+ subclass.defaults = self.defaults.clone
13
+ subclass.variants = self.variants.clone
14
+ end
10
15
 
11
- attr_accessor :validates, :should_bes, :defaults, :variants
16
+ attr_accessor :validates, :should_bes, :defaults, :variants
12
17
 
13
- def validates; @validates ||= {}; end
14
- def should_bes; @should_bes ||= []; end
15
- def defaults; @defaults ||= {}; end
16
- def variants; @variants ||= {}; end
18
+ def validates; @validates ||= {}; end
19
+ def should_bes; @should_bes ||= []; end
20
+ def defaults; @defaults ||= {}; end
21
+ def variants; @variants ||= {}; end
17
22
 
18
- def param(param, types = [], should_be = false, default = nil, _variants = nil)
19
- param = param.to_sym
23
+ def param(param, types = [], should_be = false, default = nil, _variants = nil)
24
+ param = param.to_sym
20
25
 
21
- validates[param] = types
22
- should_bes << param if should_be
23
- defaults[param] = default
24
- variants[param] = _variants
26
+ validates[param] = types
27
+ should_bes << param if should_be
28
+ defaults[param] = default
29
+ variants[param] = _variants
25
30
 
26
- return if param == :do
31
+ return if param == :do
27
32
 
28
- define_method "#{param}" do
29
- @options[param] || default
33
+ define_method "#{param}" do
34
+ @options[param] || default
35
+ end
30
36
  end
31
- end
32
37
 
33
- def validate(options = {})
34
- options.each do |param, value|
35
- param = param.to_sym
36
- types = validates[param]
37
- unless types
38
- if param != :type
39
- raise Error, "#{self.name} unknown param :#{param} value #{value.inspect}"
38
+ def validate(options = {})
39
+ options.each do |param, value|
40
+ param = param.to_sym
41
+ types = validates[param]
42
+ unless types
43
+ if param != :type
44
+ raise Error, "#{self.name} unknown param :#{param} value #{value.inspect}"
45
+ end
40
46
  end
41
- end
42
47
 
43
- if self.variants[param]
44
- if value && !value.is_a?(Proc)
45
- if value.is_a?(Array)
46
- if (value - self.variants[param]).present?
48
+ if self.variants[param]
49
+ if value && !value.is_a?(Proc)
50
+ if value.is_a?(Array)
51
+ if (value - self.variants[param]).present?
52
+ raise Error, "#{value.inspect} should within #{self.variants[param].inspect}"
53
+ end
54
+ elsif !self.variants[param].include?(value)
47
55
  raise Error, "#{value.inspect} should within #{self.variants[param].inspect}"
48
56
  end
49
- elsif !self.variants[param].include?(value)
50
- raise Error, "#{value.inspect} should within #{self.variants[param].inspect}"
51
57
  end
52
58
  end
53
- end
54
59
 
55
- next if types.blank?
60
+ next if types.blank?
56
61
 
57
- types = Array(types)
58
- good = types.any?{|type| value.is_a?(type) }
59
- raise Error, "#{self.name} bad param :#{param} value #{value.inspect}, type #{types.inspect}" unless good
60
- end
62
+ types = Array(types)
63
+ good = types.any?{|type| value.is_a?(type) }
64
+ raise Error, "#{self.name} bad param :#{param} value #{value.inspect}, type #{types.inspect}" unless good
65
+ end
61
66
 
62
- should_bes.each do |param|
63
- raise Error, "#{self.name} for param :#{param} value should be" unless options[param.to_sym] || defaults[param.to_sym]
67
+ should_bes.each do |param|
68
+ raise Error, "#{self.name} for param :#{param} value should be" unless options[param.to_sym] || defaults[param.to_sym]
69
+ end
64
70
  end
65
71
  end
66
72
 
@@ -114,7 +114,7 @@ class Eye::Group
114
114
  end
115
115
 
116
116
  def break_chain
117
- info "break chain"
117
+ info 'break chain'
118
118
  scheduler_clear_pending_list
119
119
  @chain_breaker = true
120
120
  end
@@ -1,14 +1,10 @@
1
- # mini bundler, for embedded server gem installation
1
+ # add gems to $: by `gem` method
2
+ # this is only way when install eye as system wide
2
3
 
3
- gem 'celluloid', '~> 0.14.0'
4
- gem 'celluloid-io', '~> 0.14.0'
4
+ gem 'celluloid', '~> 0.15.0'
5
+ gem 'celluloid-io', '~> 0.15.0'
5
6
  gem 'nio4r'
6
7
  gem 'timers'
7
8
 
8
9
  gem 'state_machine'
9
-
10
- if RUBY_VERSION == '1.9.2'
11
- gem 'activesupport', '>= 3', '< 4.0'
12
- else
13
- gem 'activesupport', '>= 3'
14
- end
10
+ gem 'sigar', '~> 0.7.2'
@@ -1,6 +1,6 @@
1
1
  require 'fileutils'
2
2
 
3
- module Eye::Settings
3
+ module Eye::Local
4
4
  module_function
5
5
 
6
6
  def dir
@@ -56,6 +56,7 @@ class Eye::Logger
56
56
  attr_reader :dev, :log_level
57
57
 
58
58
  def link_logger(dev)
59
+ old_dev = @dev
59
60
  @dev = dev ? dev.to_s : nil
60
61
  @dev_fd = @dev
61
62
 
@@ -64,6 +65,10 @@ class Eye::Logger
64
65
 
65
66
  @inner_logger = InnerLogger.new(@dev_fd)
66
67
  @inner_logger.level = self.log_level || Logger::INFO
68
+
69
+ rescue Errno::ENOENT, Errno::EACCES
70
+ @dev = old_dev
71
+ raise
67
72
  end
68
73
 
69
74
  def log_level=(level)
@@ -1,15 +1,18 @@
1
1
  class Eye::Notify
2
2
  include Celluloid
3
- extend Eye::Dsl::Validation
3
+ include Eye::Dsl::Validation
4
4
 
5
5
  autoload :Mail, 'eye/notify/mail'
6
6
  autoload :Jabber, 'eye/notify/jabber'
7
7
 
8
- TYPES = {:mail => "Mail", :jabber => "Jabber"}
8
+ TYPES = {:mail => 'Mail', :jabber => 'Jabber'}
9
9
 
10
10
  def self.get_class(type)
11
11
  klass = eval("Eye::Notify::#{TYPES[type]}") rescue nil
12
12
  raise "Unknown notify #{type}" unless klass
13
+ if deps = klass.depends_on
14
+ Array(deps).each { |d| require d }
15
+ end
13
16
  klass
14
17
  end
15
18
 
@@ -71,7 +74,7 @@ class Eye::Notify
71
74
  end
72
75
 
73
76
  def execute
74
- raise "realize me"
77
+ raise 'realize me'
75
78
  end
76
79
 
77
80
  param :contact, [String]
@@ -81,17 +84,20 @@ class Eye::Notify
81
84
  end
82
85
 
83
86
  def message_body
84
- "#{message_subject} at #{msg_at.to_s(:short)}"
87
+ "#{message_subject} at #{msg_at.strftime(Eye::Cli::Render::DF)}"
85
88
  end
86
89
 
87
90
  def self.register(base)
88
- name = base.to_s.gsub("Eye::Notify::", '')
91
+ name = base.to_s.gsub('Eye::Notify::', '')
89
92
  type = name.underscore.to_sym
90
93
  Eye::Notify::TYPES[type] = name
91
94
  Eye::Notify.const_set(name, base)
92
95
  Eye::Dsl::ConfigOpts.add_notify(type)
93
96
  end
94
97
 
98
+ def self.depends_on
99
+ end
100
+
95
101
  class Custom < Eye::Notify
96
102
  def self.inherited(base)
97
103
  super
@@ -107,4 +113,4 @@ private
107
113
  end
108
114
  end
109
115
 
110
- end
116
+ end
@@ -1,3 +1,5 @@
1
+ require 'xmpp4r'
2
+
1
3
  class Eye::Notify::Jabber < Eye::Notify
2
4
 
3
5
  # Eye.config do
@@ -11,8 +13,6 @@ class Eye::Notify::Jabber < Eye::Notify
11
13
  param :password, String
12
14
 
13
15
  def execute
14
- require 'xmpp4r'
15
-
16
16
  debug "send jabber #{[host, port, user, password]} - #{[contact, message_body]}"
17
17
 
18
18
  mes = ::Jabber::Message.new(contact, message_body)
@@ -6,8 +6,9 @@ module Eye::Process::Child
6
6
 
7
7
  def add_or_update_childs
8
8
  return unless self[:monitor_children]
9
-
10
9
  return unless self.up?
10
+ return if @updating_childs
11
+ @updating_childs = true
11
12
 
12
13
  unless self.pid
13
14
  warn 'Cant add childs, because no pid'
@@ -41,6 +42,7 @@ module Eye::Process::Child
41
42
  h = {:new => new_childs.size, :removed => removed_childs.size, :exists => exist_childs.size }
42
43
  debug "childs info: #{ h.inspect }"
43
44
 
45
+ @updating_childs = false
44
46
  h
45
47
  end
46
48
 
@@ -88,7 +88,7 @@ private
88
88
 
89
89
  def kill_process
90
90
  unless self.pid
91
- error "try to kill process without pid"
91
+ error 'try to kill process without pid'
92
92
  return
93
93
  end
94
94
 
@@ -145,7 +145,7 @@ private
145
145
 
146
146
  def execute_restart_command
147
147
  unless self.pid
148
- error "try to execute restart_command without pid"
148
+ error 'try to execute restart_command without pid'
149
149
  return
150
150
  end
151
151
 
@@ -43,7 +43,7 @@ module Eye::Process::Controller
43
43
  info "process from pid_file(#{self.pid}) found and already running, so :up"
44
44
  switch :already_running
45
45
  else
46
- warn "process not found, so :unmonitor"
46
+ warn 'process not found, so :unmonitor'
47
47
  schedule :unmonitor, Eye::Reason.new(:'not found')
48
48
  end
49
49
  end
@@ -14,7 +14,7 @@ module Eye::Process::Trigger
14
14
 
15
15
  def check_triggers(transition)
16
16
  return if unmonitored?
17
- self.triggers.each { |trigger| trigger.notify(transition) }
17
+ self.triggers.each { |trigger| trigger.notify(transition, state_reason) }
18
18
  end
19
19
 
20
20
  def retry_start_after_flapping