reel-eye 0.3.2 → 0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/.rspec +1 -1
  4. data/.travis.yml +3 -1
  5. data/CHANGES.md +11 -2
  6. data/Gemfile +1 -0
  7. data/README.md +18 -14
  8. data/Rakefile +10 -3
  9. data/bin/eye +41 -27
  10. data/examples/process_thin.rb +1 -1
  11. data/examples/processes/em.rb +2 -2
  12. data/examples/processes/forking.rb +2 -2
  13. data/examples/processes/sample.rb +5 -5
  14. data/examples/rbenv.eye +1 -1
  15. data/examples/sidekiq.eye +2 -2
  16. data/examples/test.eye +10 -6
  17. data/examples/thin-farm.eye +1 -1
  18. data/examples/unicorn.eye +1 -1
  19. data/eye.gemspec +13 -7
  20. data/lib/eye.rb +6 -6
  21. data/lib/eye/application.rb +9 -6
  22. data/lib/eye/checker.rb +51 -21
  23. data/lib/eye/checker/file_size.rb +1 -1
  24. data/lib/eye/checker/http.rb +3 -3
  25. data/lib/eye/checker/memory.rb +1 -1
  26. data/lib/eye/checker/socket.rb +6 -6
  27. data/lib/eye/child_process.rb +7 -11
  28. data/lib/eye/client.rb +6 -6
  29. data/lib/eye/config.rb +2 -2
  30. data/lib/eye/controller.rb +13 -8
  31. data/lib/eye/controller/commands.rb +9 -10
  32. data/lib/eye/controller/helpers.rb +1 -0
  33. data/lib/eye/controller/load.rb +11 -7
  34. data/lib/eye/controller/options.rb +1 -1
  35. data/lib/eye/controller/send_command.rb +44 -19
  36. data/lib/eye/controller/show_history.rb +8 -7
  37. data/lib/eye/controller/status.rb +39 -26
  38. data/lib/eye/dsl.rb +3 -3
  39. data/lib/eye/dsl/application_opts.rb +4 -4
  40. data/lib/eye/dsl/config_opts.rb +4 -4
  41. data/lib/eye/dsl/helpers.rb +2 -2
  42. data/lib/eye/dsl/main.rb +2 -2
  43. data/lib/eye/dsl/opts.rb +19 -14
  44. data/lib/eye/dsl/process_opts.rb +1 -1
  45. data/lib/eye/dsl/pure_opts.rb +2 -2
  46. data/lib/eye/dsl/validation.rb +7 -5
  47. data/lib/eye/group.rb +17 -11
  48. data/lib/eye/group/chain.rb +3 -3
  49. data/lib/eye/http.rb +1 -1
  50. data/lib/eye/http/router.rb +2 -2
  51. data/lib/eye/loader.rb +8 -7
  52. data/lib/eye/logger.rb +14 -5
  53. data/lib/eye/notify.rb +13 -7
  54. data/lib/eye/notify/jabber.rb +2 -2
  55. data/lib/eye/notify/mail.rb +2 -2
  56. data/lib/eye/process.rb +10 -13
  57. data/lib/eye/process/child.rb +1 -1
  58. data/lib/eye/process/commands.rb +34 -32
  59. data/lib/eye/process/config.rb +17 -12
  60. data/lib/eye/process/controller.rb +3 -6
  61. data/lib/eye/process/data.rb +16 -5
  62. data/lib/eye/process/monitor.rb +12 -5
  63. data/lib/eye/process/notify.rb +1 -1
  64. data/lib/eye/process/scheduler.rb +3 -3
  65. data/lib/eye/process/states.rb +10 -13
  66. data/lib/eye/process/states_history.rb +3 -3
  67. data/lib/eye/process/system.rb +17 -21
  68. data/lib/eye/process/trigger.rb +11 -30
  69. data/lib/eye/process/watchers.rb +9 -9
  70. data/lib/eye/server.rb +14 -6
  71. data/lib/eye/settings.rb +4 -4
  72. data/lib/eye/system.rb +10 -7
  73. data/lib/eye/system_resources.rb +4 -4
  74. data/lib/eye/trigger.rb +58 -21
  75. data/lib/eye/trigger/flapping.rb +24 -4
  76. data/lib/eye/trigger/state.rb +28 -0
  77. data/lib/eye/utils/alive_array.rb +1 -1
  78. data/lib/eye/utils/celluloid_klass.rb +5 -0
  79. data/lib/eye/utils/pmap.rb +7 -0
  80. data/lib/eye/utils/tail.rb +1 -1
  81. metadata +252 -271
  82. data/lib/eye/utils/leak_19.rb +0 -7
data/lib/eye/dsl.rb CHANGED
@@ -27,13 +27,13 @@ class Eye::Dsl
27
27
  def parse(content = nil, filename = nil)
28
28
  Eye.parsed_config = Eye::Config.new
29
29
  Eye.parsed_filename = filename
30
-
30
+
31
31
  content = File.read(filename) if content.blank?
32
-
32
+
33
33
  silence_warnings do
34
34
  Kernel.eval(content, Eye::BINDING, filename.to_s)
35
35
  end
36
-
36
+
37
37
  Eye.parsed_config.validate!
38
38
  Eye.parsed_config
39
39
  end
@@ -10,11 +10,11 @@ class Eye::Dsl::ApplicationOpts < Eye::Dsl::Opts
10
10
  [:groups]
11
11
  end
12
12
 
13
- def group(name, &block)
13
+ def group(name, &block)
14
14
  Eye::Dsl.debug "=> group #{name}"
15
-
15
+
16
16
  opts = Eye::Dsl::GroupOpts.new(name, self)
17
- opts.instance_eval(&block)
17
+ opts.instance_eval(&block)
18
18
  if cfg = opts.config
19
19
  @config[:groups] ||= {}
20
20
 
@@ -22,7 +22,7 @@ class Eye::Dsl::ApplicationOpts < Eye::Dsl::Opts
22
22
  @config[:groups][name.to_s] ||= {}
23
23
  @config[:groups][name.to_s].merge!(cfg)
24
24
  @config[:groups][name.to_s][:processes] ||= {}
25
- @config[:groups][name.to_s][:processes].merge!(processes)
25
+ @config[:groups][name.to_s][:processes].merge!(processes)
26
26
  end
27
27
 
28
28
  Eye::Dsl.debug "<= group #{name}"
@@ -3,7 +3,7 @@ class Eye::Dsl::ConfigOpts < Eye::Dsl::PureOpts
3
3
  create_options_methods([:logger], String)
4
4
  create_options_methods([:logger_level], Fixnum)
5
5
  create_options_methods([:http], Hash)
6
-
6
+
7
7
  def set_logger(logger)
8
8
  logger.blank? ? super('') : super
9
9
  end
@@ -21,7 +21,7 @@ class Eye::Dsl::ConfigOpts < Eye::Dsl::PureOpts
21
21
  end
22
22
 
23
23
  def contact(contact_name, contact_type, contact, contact_opts = {})
24
- raise Eye::Dsl::Error, "unknown contact_type #{contact_type}" unless Eye::Notify::TYPES[contact_type]
24
+ raise Eye::Dsl::Error, "unknown contact_type #{contact_type}" unless Eye::Notify::TYPES[contact_type]
25
25
  raise Eye::Dsl::Error, "contact should be a String" unless contact.is_a?(String)
26
26
 
27
27
  notify_hash = @config[contact_type] || (@parent && @parent.config[contact_type]) || Eye::parsed_config.settings[contact_type] || {}
@@ -30,7 +30,7 @@ class Eye::Dsl::ConfigOpts < Eye::Dsl::PureOpts
30
30
  Eye::Notify.validate!(validate_hash)
31
31
 
32
32
  @config[:contacts] ||= {}
33
- @config[:contacts][contact_name.to_s] = {name: contact_name.to_s, type: contact_type,
33
+ @config[:contacts][contact_name.to_s] = {name: contact_name.to_s, type: contact_type,
34
34
  contact: contact, opts: contact_opts}
35
35
  end
36
36
 
@@ -44,5 +44,5 @@ class Eye::Dsl::ConfigOpts < Eye::Dsl::PureOpts
44
44
  @config[:contacts].merge!(cfg[:contacts])
45
45
  end
46
46
  end
47
-
47
+
48
48
  end
@@ -1,5 +1,5 @@
1
1
 
2
- # Dsl Helpers
2
+ # Dsl Helpers
3
3
 
4
4
  # current eye parsed config path
5
5
  def current_config_path
@@ -8,5 +8,5 @@ end
8
8
 
9
9
  # host name
10
10
  def hostname
11
- Eye::System.host
11
+ Eye::System.host
12
12
  end
data/lib/eye/dsl/main.rb CHANGED
@@ -2,7 +2,7 @@ module Eye::Dsl::Main
2
2
  attr_accessor :parsed_config, :parsed_filename
3
3
 
4
4
  def application(name, &block)
5
- Eye::Dsl.debug "=> app: #{name}"
5
+ Eye::Dsl.debug "=> app: #{name}"
6
6
  opts = Eye::Dsl::ApplicationOpts.new(name)
7
7
  opts.instance_eval(&block)
8
8
 
@@ -36,5 +36,5 @@ module Eye::Dsl::Main
36
36
 
37
37
  Eye::Dsl.debug "<= config"
38
38
  end
39
-
39
+
40
40
  end
data/lib/eye/dsl/opts.rb CHANGED
@@ -1,14 +1,14 @@
1
1
  class Eye::Dsl::Opts < Eye::Dsl::PureOpts
2
2
 
3
- STR_OPTIONS = [ :pid_file, :working_dir, :stdout, :stderr, :stdall, :start_command,
3
+ STR_OPTIONS = [ :pid_file, :working_dir, :stdout, :stderr, :stdall, :start_command,
4
4
  :stop_command, :restart_command, :uid, :gid ]
5
5
  create_options_methods(STR_OPTIONS, String)
6
6
 
7
- BOOL_OPTIONS = [ :daemonize, :keep_alive, :control_pid, :auto_start, :stop_on_delete]
7
+ BOOL_OPTIONS = [ :daemonize, :keep_alive, :auto_start, :stop_on_delete, :clear_pid ]
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 ]
11
+ :restart_grace, :stop_grace, :childs_update_period, :restore_in ]
12
12
  create_options_methods(INTERVAL_OPTIONS, [Fixnum, Float])
13
13
 
14
14
  create_options_methods([:environment], Hash)
@@ -32,20 +32,20 @@ class Eye::Dsl::Opts < Eye::Dsl::PureOpts
32
32
 
33
33
  opts.merge!(:type => nac[:type])
34
34
  Eye::Checker.validate!(opts)
35
-
35
+
36
36
  @config[:checks] ||= {}
37
37
  @config[:checks][nac[:name]] = opts
38
38
  end
39
39
 
40
40
  def triggers(type, opts = {})
41
- type = type.to_sym
42
- raise Eye::Dsl::Error, "unknown trigger type #{type}" unless Eye::Trigger::TYPES[type]
43
-
44
- opts.merge!(:type => type)
41
+ nac = Eye::Trigger.name_and_class(type.to_sym)
42
+ raise Eye::Dsl::Error, "unknown trigger type #{type}" unless nac
43
+
44
+ opts.merge!(:type => nac[:type])
45
45
  Eye::Trigger.validate!(opts)
46
46
 
47
47
  @config[:triggers] ||= {}
48
- @config[:triggers][type] = opts
48
+ @config[:triggers][nac[:name]] = opts
49
49
  end
50
50
 
51
51
  # clear checks from parent
@@ -57,14 +57,19 @@ class Eye::Dsl::Opts < Eye::Dsl::PureOpts
57
57
 
58
58
  # clear triggers from parent
59
59
  def notriggers(type)
60
- type = type.to_sym
61
- raise Eye::Dsl::Error, "unknown trigger type #{type}" unless Eye::Trigger::TYPES[type]
62
- @config[:triggers].try :delete, type
60
+ nac = Eye::Trigger.name_and_class(type.to_sym)
61
+ raise Eye::Dsl::Error, "unknown trigger type #{type}" unless nac
62
+ @config[:triggers].try :delete, nac[:name]
63
63
  end
64
64
 
65
+ alias check checks
66
+ alias nocheck nochecks
67
+ alias trigger triggers
68
+ alias notrigger notriggers
69
+
65
70
  def notify(contact, level = :warn)
66
71
  unless Eye::Process::Notify::LEVELS[level]
67
- raise Eye::Dsl::Error, "level should be in #{Eye::Process::Notify::LEVELS.keys}"
72
+ raise Eye::Dsl::Error, "level should be in #{Eye::Process::Notify::LEVELS.keys}"
68
73
  end
69
74
 
70
75
  @config[:notify] ||= {}
@@ -125,7 +130,7 @@ class Eye::Dsl::Opts < Eye::Dsl::PureOpts
125
130
  def with_server(glob = nil, &block)
126
131
  on_server = true
127
132
 
128
- if glob.present?
133
+ if glob.present?
129
134
  host = Eye::System.host
130
135
 
131
136
  if glob.is_a?(Array)
@@ -2,7 +2,7 @@ class Eye::Dsl::ProcessOpts < Eye::Dsl::Opts
2
2
 
3
3
  def monitor_children(&block)
4
4
  opts = Eye::Dsl::ChildProcessOpts.new
5
- opts.instance_eval(&block)
5
+ opts.instance_eval(&block) if block
6
6
  @config[:monitor_children] ||= {}
7
7
  @config[:monitor_children].merge!(opts.config)
8
8
  end
@@ -44,7 +44,7 @@ class Eye::Dsl::PureOpts
44
44
  attr_reader :config, :parent
45
45
 
46
46
  def initialize(name = nil, parent = nil, merge_parent_config = true)
47
- @name = name.to_s
47
+ @name = name.to_s
48
48
  @full_name = @name
49
49
 
50
50
  if parent
@@ -84,7 +84,7 @@ class Eye::Dsl::PureOpts
84
84
  self.class.with_parsed_file(proc) do |path|
85
85
  if File.exists?(path)
86
86
  Eye::Dsl.debug "=> load #{path}"
87
- self.instance_eval(File.read(path))
87
+ self.instance_eval(File.read(path))
88
88
  Eye::Dsl.debug "<= load #{path}"
89
89
  end
90
90
  end
@@ -23,24 +23,26 @@ module Eye::Dsl::Validation
23
23
  defaults[param] = default
24
24
  variants[param] = _variants
25
25
 
26
+ return if param == :do
27
+
26
28
  define_method "#{param}" do
27
- @options[param.to_sym] || default
29
+ @options[param] || default
28
30
  end
29
31
  end
30
32
 
31
- def validate(options = {})
32
- options.each do |param, value|
33
+ def validate(options = {})
34
+ options.each do |param, value|
33
35
  param = param.to_sym
34
36
  types = validates[param]
35
37
  unless types
36
38
  if param != :type
37
- raise Error, "#{self.name} unknown param :#{param} value #{value.inspect}"
39
+ raise Error, "#{self.name} unknown param :#{param} value #{value.inspect}"
38
40
  end
39
41
  end
40
42
 
41
43
  if self.variants[param]
42
44
  if value && !value.is_a?(Proc) && !self.variants[param].include?(value)
43
- raise Error, "#{value.inspect} should within #{self.variants[param].inspect}"
45
+ raise Error, "#{value.inspect} should within #{self.variants[param].inspect}"
44
46
  end
45
47
  end
46
48
 
data/lib/eye/group.rb CHANGED
@@ -5,7 +5,6 @@ class Eye::Group
5
5
 
6
6
  autoload :Chain, 'eye/group/chain'
7
7
 
8
- include Eye::Logger::Helpers
9
8
  include Eye::Process::Scheduler
10
9
  include Eye::Group::Chain
11
10
 
@@ -14,14 +13,21 @@ class Eye::Group
14
13
  def initialize(name, config)
15
14
  @name = name
16
15
  @config = config
17
- @logger = Eye::Logger.new(full_name)
18
16
  @processes = Eye::Utils::AliveArray.new
19
17
  @hidden = (name == '__default__')
20
18
  debug 'created'
21
19
  end
22
20
 
21
+ def logger_tag
22
+ full_name
23
+ end
24
+
25
+ def app_name
26
+ @config[:application]
27
+ end
28
+
23
29
  def full_name
24
- @full_name ||= "#{@config[:application]}:#{@name}"
30
+ @full_name ||= "#{app_name}:#{@name}"
25
31
  end
26
32
 
27
33
  def update_config(cfg)
@@ -47,14 +53,14 @@ class Eye::Group
47
53
 
48
54
  # show current chain
49
55
  if current_scheduled_command
50
- h.update(current_command: current_scheduled_command)
56
+ h.update(current_command: current_scheduled_command)
51
57
 
52
58
  if (chain_commands = scheduler_actions_list) && chain_commands.present?
53
- h.update(chain_commands: chain_commands)
59
+ h.update(chain_commands: chain_commands)
54
60
  end
55
61
 
56
62
  if @chain_processes_current && @chain_processes_count
57
- h.update(chain_progress: [@chain_processes_current, @chain_processes_count])
63
+ h.update(chain_progress: [@chain_processes_current, @chain_processes_count])
58
64
  end
59
65
  end
60
66
 
@@ -71,9 +77,9 @@ class Eye::Group
71
77
  case command
72
78
  when :delete
73
79
  delete *args
74
- when :break_chain
80
+ when :break_chain
75
81
  break_chain *args
76
- else
82
+ else
77
83
  schedule command, *args, Eye::Reason::User.new(command)
78
84
  end
79
85
  end
@@ -110,7 +116,7 @@ class Eye::Group
110
116
  def break_chain
111
117
  info "break chain"
112
118
  scheduler_clear_pending_list
113
- @chain_breaker = true
119
+ @chain_breaker = true
114
120
  end
115
121
 
116
122
  def clear
@@ -125,10 +131,10 @@ private
125
131
 
126
132
  def async_schedule(command, *args)
127
133
  info "send to all processes #{command} #{args.present? ? args*',' : nil}"
128
-
134
+
129
135
  @processes.each do |process|
130
136
  process.send_command(command, *args)
131
- end
137
+ end
132
138
  end
133
139
 
134
140
  end
@@ -17,7 +17,7 @@ private
17
17
  @chain_processes_current = @chain_processes_current.to_i + 1
18
18
 
19
19
  # to skip last sleep
20
- break if @chain_processes_current.to_i == @chain_processes_count.to_i
20
+ break if @chain_processes_current.to_i == @chain_processes_count.to_i
21
21
  break if @chain_breaker
22
22
 
23
23
  # wait next process
@@ -34,7 +34,7 @@ private
34
34
 
35
35
  def chain_schedule_process(process, type, command, *args)
36
36
  debug "chain_schedule_process #{process.name} #{type} #{command}"
37
-
37
+
38
38
  if type == :sync
39
39
  # sync command, with waiting
40
40
  # this is very hackety, because call method of the process without its scheduler
@@ -73,7 +73,7 @@ private
73
73
 
74
74
  {:type => type, :grace => grace}
75
75
  else
76
- # default chain case
76
+ # default chain case
77
77
  {:type => :async, :grace => DEFAULT_CHAIN}
78
78
  end
79
79
  end
data/lib/eye/http.rb CHANGED
@@ -15,7 +15,7 @@ class Eye::Http
15
15
  end
16
16
 
17
17
  def start
18
- stop
18
+ stop
19
19
 
20
20
  @server = Reel::Server.supervise(@host, @port) do |connection|
21
21
  while request = connection.request
@@ -11,11 +11,11 @@ Eye::Http::Router = Cuba.new do
11
11
  on root do
12
12
  res.write Eye::ABOUT
13
13
  end
14
-
14
+
15
15
  on "api/info", param("filter") do |filter|
16
16
  json Eye::Control.command(:raw_info, filter)
17
17
  end
18
-
18
+
19
19
  [:start, :stop, :restart, :delete, :unmonitor, :monitor].each do |act|
20
20
  on put, "api/#{act}", param("filter") do |filter|
21
21
  json Eye::Control.command(act, filter)
data/lib/eye/loader.rb CHANGED
@@ -1,13 +1,14 @@
1
1
  # mini bundler, for embedded server gem installation
2
2
 
3
- gem 'celluloid', '~> 0.13.0'
4
- gem 'celluloid-io', '~> 0.13.0'
3
+ gem 'celluloid', '~> 0.14.0'
4
+ gem 'celluloid-io', '~> 0.14.0'
5
5
  gem 'nio4r'
6
6
  gem 'timers'
7
7
 
8
- gem 'state_machine', '< 1.2'
8
+ gem 'state_machine'
9
9
 
10
- # activesupport
11
- gem 'activesupport', '~> 3.2.0'
12
- gem 'i18n'
13
- gem 'multi_json'
10
+ if RUBY_VERSION == '1.9.2'
11
+ gem 'activesupport', '>= 3', '< 4.0'
12
+ else
13
+ gem 'activesupport', '>= 3'
14
+ end
data/lib/eye/logger.rb CHANGED
@@ -11,17 +11,26 @@ class Eye::Logger
11
11
 
12
12
  self.formatter = Proc.new do |s, d, p, m|
13
13
  "#{d.strftime(FORMAT)} #{s.ljust(5)} -- #{m}\n"
14
- end
14
+ end
15
15
  end
16
16
  end
17
17
 
18
- module Helpers
19
- attr_reader :logger
18
+ module ObjectExt
19
+ def logger_tag
20
+ [Class, Module].include?(self.class) ? to_s : "<#{self.class.to_s}>"
21
+ end
22
+
23
+ def logger_sub_tag
24
+ end
25
+
26
+ def logger
27
+ @logger ||= Eye::Logger.new(logger_tag, logger_sub_tag)
28
+ end
20
29
 
21
30
  Logger::Severity.constants.each do |level|
22
31
  method_name = level.to_s.downcase
23
32
  define_method method_name do |msg|
24
- @logger.send(method_name, msg)
33
+ logger.send(method_name, msg)
25
34
  end
26
35
  end
27
36
  end
@@ -47,7 +56,7 @@ class Eye::Logger
47
56
 
48
57
  @dev_fd = STDOUT if @dev.to_s.downcase == 'stdout'
49
58
  @dev_fd = STDERR if @dev.to_s.downcase == 'stderr'
50
-
59
+
51
60
  @inner_logger = InnerLogger.new(@dev_fd)
52
61
  @inner_logger.level = self.log_level || Logger::INFO
53
62
  end
data/lib/eye/notify.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  class Eye::Notify
2
2
  include Celluloid
3
- include Eye::Logger::Helpers
4
3
  extend Eye::Dsl::Validation
5
4
 
6
5
  autoload :Mail, 'eye/notify/mail'
@@ -19,10 +18,14 @@ class Eye::Notify
19
18
  end
20
19
 
21
20
  def self.notify(contact, message_h)
21
+ contact = contact.to_s
22
22
  settings = Eye::Control.settings
23
- needed_hash = (settings[:contacts] || {})[contact.to_s]
23
+ needed_hash = (settings[:contacts] || {})[contact]
24
24
 
25
- return if needed_hash.blank?
25
+ if needed_hash.blank?
26
+ error "not found contact #{contact}! something wrong with config"
27
+ return
28
+ end
26
29
 
27
30
  create_proc = lambda do |nh|
28
31
  type = nh[:type]
@@ -42,11 +45,14 @@ class Eye::Notify
42
45
  TIMEOUT = 1.minute
43
46
 
44
47
  def initialize(options = {}, message_h = {})
45
- @logger = Eye::Logger.new("#{self.class.name.downcase} - #{options[:contact]}")
46
- debug "created notifier #{options}"
47
-
48
48
  @message_h = message_h
49
49
  @options = options
50
+
51
+ debug "created notifier #{options}"
52
+ end
53
+
54
+ def logger_sub_tag
55
+ @options[:contact]
50
56
  end
51
57
 
52
58
  def async_notify
@@ -70,7 +76,7 @@ class Eye::Notify
70
76
  def message_subject
71
77
  "[#{msg_host}] [#{msg_full_name}] #{msg_message}"
72
78
  end
73
-
79
+
74
80
  def message_body
75
81
  "#{message_subject} at #{msg_at.to_s(:short)}"
76
82
  end