eye 0.6.2 → 0.6.3

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 (44) hide show
  1. checksums.yaml +13 -5
  2. data/CHANGES.md +8 -0
  3. data/README.md +5 -3
  4. data/bin/{runner → leye} +0 -0
  5. data/examples/delayed_job.eye +28 -0
  6. data/examples/sidekiq.eye +2 -2
  7. data/examples/stress_test.eye +18 -0
  8. data/lib/eye.rb +1 -1
  9. data/lib/eye/application.rb +1 -1
  10. data/lib/eye/checker.rb +2 -2
  11. data/lib/eye/checker/http.rb +1 -1
  12. data/lib/eye/child_process.rb +1 -1
  13. data/lib/eye/cli.rb +9 -2
  14. data/lib/eye/cli/server.rb +1 -2
  15. data/lib/eye/controller/commands.rb +1 -1
  16. data/lib/eye/controller/load.rb +9 -9
  17. data/lib/eye/controller/options.rb +1 -1
  18. data/lib/eye/controller/status.rb +2 -2
  19. data/lib/eye/dsl/application_opts.rb +2 -2
  20. data/lib/eye/dsl/config_opts.rb +0 -2
  21. data/lib/eye/dsl/group_opts.rb +2 -2
  22. data/lib/eye/dsl/main.rb +6 -6
  23. data/lib/eye/dsl/opts.rb +12 -4
  24. data/lib/eye/dsl/pure_opts.rb +4 -5
  25. data/lib/eye/group.rb +1 -1
  26. data/lib/eye/group/chain.rb +2 -2
  27. data/lib/eye/local.rb +3 -3
  28. data/lib/eye/logger.rb +21 -11
  29. data/lib/eye/notify.rb +3 -3
  30. data/lib/eye/notify/jabber.rb +1 -1
  31. data/lib/eye/notify/mail.rb +1 -1
  32. data/lib/eye/process.rb +1 -1
  33. data/lib/eye/process/children.rb +1 -1
  34. data/lib/eye/process/commands.rb +9 -6
  35. data/lib/eye/process/config.rb +1 -1
  36. data/lib/eye/process/monitor.rb +2 -2
  37. data/lib/eye/process/scheduler.rb +2 -2
  38. data/lib/eye/process/system.rb +2 -13
  39. data/lib/eye/process/watchers.rb +2 -2
  40. data/lib/eye/system.rb +1 -2
  41. data/lib/eye/trigger.rb +2 -2
  42. data/lib/eye/trigger/flapping.rb +1 -1
  43. data/lib/eye/trigger/stop_children.rb +1 -1
  44. metadata +45 -43
checksums.yaml CHANGED
@@ -1,7 +1,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 8695cf6cc62b0a083c7470bc0b3f338ce5e678f2
4
- data.tar.gz: f0ed23ed079228bcb897149b265e8a7f2faa5774
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ Yzg5NjVhMzljODliZWQ5OTZiOWM4NzYyMTc2YTgzYWVlOWY5MTRhYw==
5
+ data.tar.gz: !binary |-
6
+ MzQzY2FjY2Y3ZDllYTdjZjE0OGZhY2FhZDdkYTA2ZmE0Y2FjNzIyMg==
5
7
  SHA512:
6
- metadata.gz: 36c299addb4c2dcf551930f02770f91842b9b896e86bafbaf485833b9fc489ceb4bdaecb1d35438e830afc6ff81d353ada49d6677a10ca0d6cb0a29f7b5957ea
7
- data.tar.gz: 193455755372b1e5bed00a954c16ec79af9b531bc2c0574f58b7f75ff90951ccaedb62771bc9eae167883a617e481f18feb3a6d91c990681117d982f49b3e770
8
+ metadata.gz: !binary |-
9
+ ZDMzMzRhZWY3YTk1ZjA5NWVhZjljZjlhOTcwODVjNjYwM2Q1NDY3ZThjN2Vj
10
+ ZDA2NWI4MDg3YmExNmRmZDMwNWQ0ZDY5MmNjYzAzMTViMmE3MjlkOTBmOTAw
11
+ NWJhMjUwZjE3YzI0MTA1MDM3YTZiN2RiZDA3OGJlOTY4MjIyYTM=
12
+ data.tar.gz: !binary |-
13
+ NDdhNTkxM2NlMzE4NzI3ZjlmNzUxODFiYzBkZDA3OTM2Mzc2ZGRiNTU2OGQ1
14
+ ZGE1YzE2OTU3NDNkZDFiODQ3YjE3YTc4OWM5YzU4M2NiMmVhNmYwMWExZTQ0
15
+ ZjFjMGU5YjBiNzRjZjZiMjM4ODYwNGEwNGYyMjAzNjI2Y2RlOTI=
data/CHANGES.md CHANGED
@@ -1,3 +1,11 @@
1
+ 0.6.3
2
+ -----
3
+ * Add custom logger #81
4
+ * Revert check by procline, this was hack, fix for #62 should be in 0.7
5
+ * Fix ruby path, and expand_paths #69, #75
6
+ * Add json info `eye info -j`
7
+ * Rename local runner to `leye`
8
+
1
9
  0.6.2
2
10
  -----
3
11
  * Add user defined command #65
data/README.md CHANGED
@@ -24,7 +24,7 @@ We wanted something more robust and production stable.
24
24
 
25
25
  We wanted the features of bluepill and god, with a few extras like chains, nested configuring, mask matching, easy debug configs
26
26
 
27
- I hope we've success, we're using eye in production and are quite happy.
27
+ I hope we've succeeded, we're using eye in production and are quite happy.
28
28
 
29
29
  ### Config example
30
30
 
@@ -205,8 +205,10 @@ Process states and events:
205
205
  [![Eye](https://raw.github.com/kostya/stuff/master/eye/mprocess.png)](https://raw.github.com/kostya/stuff/master/eye/process.png)
206
206
 
207
207
 
208
- EyeHttp Gem:
208
+ [EyeHttp Gem](https://github.com/kostya/eye-http)
209
209
 
210
- https://github.com/kostya/eye-http
210
+ [Eye related projects](https://github.com/kostya/eye/wiki/Related-projects)
211
+
212
+ [Articles](https://github.com/kostya/eye/wiki/Articles)
211
213
 
212
214
  Thanks `Bluepill` for the nice config ideas.
File without changes
@@ -0,0 +1,28 @@
1
+ cwd = File.expand_path(File.join(File.dirname(__FILE__), %w[ ../ ../ ]))
2
+
3
+ config_path = File.join(cwd, %w{ config dj.yml } )
4
+
5
+ workers_count = if File.exists?(config_path)
6
+ YAML.load_file(config_path).try(:[], :workers) || 5
7
+ else
8
+ 5
9
+ end
10
+
11
+ Eye.application 'delayed_job' do
12
+ working_dir cwd
13
+ stop_on_delete true
14
+
15
+ group 'dj' do
16
+ chain grace: 5.seconds
17
+
18
+ (1 .. workers_count).each do |i|
19
+ process "dj-#{i}" do
20
+ pid_file "tmp/pids/delayed_job.#{i}.pid"
21
+ start_command "rake jobs:work"
22
+ daemonize true
23
+ stop_signals [:INT, 30.seconds, :TERM, 10.seconds, :KILL]
24
+ stdall "log/dj-#{i}.log"
25
+ end
26
+ end
27
+ end
28
+ end
@@ -4,11 +4,11 @@ def sidekiq_process(proxy, name)
4
4
  rails_env = proxy.env['RAILS_ENV']
5
5
 
6
6
  proxy.process(name) do
7
- start_command "ruby ./bin/sidekiq -e #{rails_env} -C ./config/sidekiq.#{rails_env}.yml"
7
+ start_command "bin/sidekiq -e #{rails_env} -C ./config/sidekiq.#{rails_env}.yml"
8
8
  pid_file "tmp/pids/#{name}.pid"
9
9
  stdall "log/#{name}.log"
10
10
  daemonize true
11
- stop_signals [:QUIT, 5.seconds, :TERM, 5.seconds, :KILL]
11
+ stop_signals [:USR1, 0, :TERM, 10.seconds, :KILL]
12
12
 
13
13
  check :cpu, :every => 30, :below => 100, :times => 5
14
14
  check :memory, :every => 30, :below => 300.megabytes, :times => 5
@@ -0,0 +1,18 @@
1
+ # this is not example, just config for eye stress test
2
+
3
+ PREFIX = ENV['PRE'] || 1
4
+
5
+ Eye.app :stress_test do
6
+ working_dir "/tmp"
7
+
8
+ 100.times do |i|
9
+ process "sleep-#{i}" do
10
+ pid_file "sleep-#{PREFIX}-#{i}.pid"
11
+ start_command "sleep 120"
12
+ daemonize true
13
+
14
+ checks :cpu, :every => 5.seconds, :below => 10, :times => 5
15
+ checks :memory, :every => 6.seconds, :below => 50.megabytes, :times => 5
16
+ end
17
+ end
18
+ end
data/lib/eye.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Eye
2
- VERSION = "0.6.2"
2
+ VERSION = "0.6.3"
3
3
  ABOUT = "Eye v#{VERSION} (c) 2012-2014 @kostya"
4
4
  PROCLINE = "eye monitoring v#{VERSION}"
5
5
 
@@ -6,7 +6,7 @@ class Eye::Application
6
6
  @groups = Eye::Utils::AliveArray.new
7
7
  @name = name
8
8
  @config = config
9
- debug 'created'
9
+ debug { 'created' }
10
10
  end
11
11
 
12
12
  def logger_tag
@@ -66,7 +66,7 @@ class Eye::Checker
66
66
  @full_name = @process.full_name if @process
67
67
  @initialized_at = Time.now
68
68
 
69
- debug "create checker, with #{options}"
69
+ debug { "create checker, with #{options}" }
70
70
 
71
71
  @value = nil
72
72
  @values = Eye::Utils::Tail.new(max_tries)
@@ -96,7 +96,7 @@ class Eye::Checker
96
96
 
97
97
  def check
98
98
  if initial_grace && (Time.now - @initialized_at < initial_grace)
99
- debug 'skipped initial grace'
99
+ debug { 'skipped initial grace' }
100
100
  return true
101
101
  else
102
102
  @options[:initial_grace] = nil
@@ -33,7 +33,7 @@ class Eye::Checker::Http < Eye::Checker::Defer
33
33
  {:result => res}
34
34
 
35
35
  rescue Timeout::Error => ex
36
- debug ex.inspect
36
+ debug { ex.inspect }
37
37
 
38
38
  if defined?(Net::OpenTimeout) # for ruby 2.0
39
39
  mes = ex.class.is_a?(Net::OpenTimeout) ? "OpenTimeout<#{@open_timeout}>" : "ReadTimeout<#{@read_timeout}>"
@@ -37,7 +37,7 @@ class Eye::ChildProcess
37
37
 
38
38
  @watchers = {}
39
39
 
40
- debug "start monitoring CHILD config: #{@config.inspect}"
40
+ debug { "start monitoring CHILD config: #{@config.inspect}" }
41
41
 
42
42
  start_checkers
43
43
  end
@@ -13,13 +13,20 @@ class Eye::Cli < Thor
13
13
  include Eye::Cli::Render
14
14
 
15
15
  desc "info [MASK]", "processes info"
16
+ method_option :json, :type => :boolean, :aliases => "-j"
16
17
  def info(mask = nil)
17
18
  res = cmd(:info_data, *Array(mask))
18
19
  if mask && res[:subtree] && res[:subtree].empty?
19
20
  error!("command :info, objects not found!")
20
21
  end
21
- say render_info(res)
22
- say
22
+
23
+ if options[:json]
24
+ require 'json'
25
+ say JSON.dump(res)
26
+ else
27
+ say render_info(res)
28
+ say
29
+ end
23
30
  end
24
31
 
25
32
  desc "status NAME", "return exit status for process name 0-up, 3-unmonitored"
@@ -13,8 +13,7 @@ private
13
13
  end
14
14
 
15
15
  def ruby_path
16
- require 'rbconfig'
17
- RbConfig::CONFIG['bindir'] + '/ruby'
16
+ RbConfig.ruby
18
17
  end
19
18
 
20
19
  def ensure_loader_path
@@ -37,7 +37,7 @@ module Eye::Controller::Commands
37
37
  when :ping
38
38
  :pong
39
39
  when :logger_dev
40
- Eye::Logger.dev
40
+ Eye::Logger.dev.to_s
41
41
 
42
42
  # object commands, for api
43
43
  when :info_data
@@ -64,7 +64,7 @@ private
64
64
  filename
65
65
  end
66
66
 
67
- debug "loading: globbing mask #{mask}"
67
+ debug { "loading: globbing mask #{mask}" }
68
68
 
69
69
  sub = []
70
70
  Dir[mask].each do |config_path|
@@ -80,7 +80,7 @@ private
80
80
 
81
81
  # return: result, config
82
82
  def parse_config(filename)
83
- debug "parsing: #{filename}"
83
+ debug { "parsing: #{filename}" }
84
84
 
85
85
  cfg = Eye::Dsl.parse(nil, filename)
86
86
  @current_config.merge(cfg).validate!(false) # just validate summary config here
@@ -111,7 +111,7 @@ private
111
111
 
112
112
  # create objects as diff, from configs
113
113
  def create_objects(apps_config, changed_apps = [])
114
- debug 'creating objects'
114
+ debug { 'creating objects' }
115
115
 
116
116
  apps_config.each do |app_name, app_cfg|
117
117
  update_or_create_application(app_name, app_cfg.clone) if changed_apps.include?(app_name)
@@ -137,9 +137,9 @@ private
137
137
 
138
138
  @applications.delete(app)
139
139
 
140
- debug "updating app: #{app_name}"
140
+ debug { "updating app: #{app_name}" }
141
141
  else
142
- debug "creating app: #{app_name}"
142
+ debug { "creating app: #{app_name}" }
143
143
  end
144
144
 
145
145
  app = Eye::Application.new(app_name, app_config)
@@ -182,13 +182,13 @@ private
182
182
 
183
183
  def update_or_create_group(group_name, group_config)
184
184
  group = if @old_groups[group_name]
185
- debug "updating group: #{group_name}"
185
+ debug { "updating group: #{group_name}" }
186
186
  group = @old_groups.delete(group_name)
187
187
  group.schedule :update_config, group_config, Eye::Reason::User.new(:'load config')
188
188
  group.clear
189
189
  group
190
190
  else
191
- debug "creating group: #{group_name}"
191
+ debug { "creating group: #{group_name}" }
192
192
  gr = Eye::Group.new(group_name, group_config)
193
193
  @added_groups << gr
194
194
  gr
@@ -209,12 +209,12 @@ private
209
209
  key = @old_processes[name] ? name : @old_processes.keys.detect { |n| n.end_with?(postfix) }
210
210
 
211
211
  if @old_processes[key]
212
- debug "updating process: #{name}"
212
+ debug { "updating process: #{name}" }
213
213
  process = @old_processes.delete(key)
214
214
  process.schedule :update_config, process_cfg, Eye::Reason::User.new(:'load config')
215
215
  process
216
216
  else
217
- debug "creating process: #{name}"
217
+ debug { "creating process: #{name}" }
218
218
  process = Eye::Process.new(process_cfg)
219
219
  @added_processes << process
220
220
  process
@@ -15,4 +15,4 @@ module Eye::Controller::Options
15
15
  warn "Warning, set http options not in reel-eye gem" if opts.present?
16
16
  end
17
17
 
18
- end
18
+ end
@@ -8,8 +8,8 @@ module Eye::Controller::Status
8
8
  :about => Eye::ABOUT,
9
9
  :resources => Eye::SystemResources.resources($$),
10
10
  :ruby => RUBY_DESCRIPTION,
11
- :gems => %w|Celluloid Celluloid::IO StateMachine NIO Sigar|.map{|c| gem_version(c) },
12
- :logger => Eye::Logger.args.present? ? [Eye::Logger.dev, *Eye::Logger.args] : Eye::Logger.dev,
11
+ :gems => %w|Celluloid Celluloid::IO StateMachine NIO Timers Sigar|.map{|c| gem_version(c) },
12
+ :logger => Eye::Logger.args.present? ? [Eye::Logger.dev.to_s, *Eye::Logger.args] : Eye::Logger.dev.to_s,
13
13
  :pid_path => Eye::Local::pid_path,
14
14
  :sock_path => Eye::Local::socket_path,
15
15
  :actors => actors
@@ -12,7 +12,7 @@ class Eye::Dsl::ApplicationOpts < Eye::Dsl::Opts
12
12
 
13
13
  def group(name, &block)
14
14
  Eye::Dsl.check_name(name)
15
- Eye::Dsl.debug "=> group #{name}"
15
+ Eye::Dsl.debug { "=> group #{name}" }
16
16
 
17
17
  opts = Eye::Dsl::GroupOpts.new(name, self)
18
18
  opts.instance_eval(&block)
@@ -24,7 +24,7 @@ class Eye::Dsl::ApplicationOpts < Eye::Dsl::Opts
24
24
  Eye::Utils.deep_merge!(@config[:groups][name.to_s], cfg)
25
25
  end
26
26
 
27
- Eye::Dsl.debug "<= group #{name}"
27
+ Eye::Dsl.debug { "<= group #{name}" }
28
28
  opts
29
29
  end
30
30
 
@@ -7,8 +7,6 @@ class Eye::Dsl::ConfigOpts < Eye::Dsl::PureOpts
7
7
  if args.empty?
8
8
  @config[:logger]
9
9
  else
10
- str = args[0]
11
- raise Eye::Dsl::Error, "logger should be a String #{str.inspect}" if !(str.is_a?(String) || str == nil)
12
10
  @config[:logger] = args
13
11
  end
14
12
  end
@@ -13,7 +13,7 @@ class Eye::Dsl::GroupOpts < Eye::Dsl::Opts
13
13
  def process(name, &block)
14
14
  Eye::Dsl.check_name(name)
15
15
 
16
- Eye::Dsl.debug "=> process #{name}"
16
+ Eye::Dsl.debug { "=> process #{name}" }
17
17
 
18
18
  opts = Eye::Dsl::ProcessOpts.new(name, self)
19
19
  opts.instance_eval(&block)
@@ -21,7 +21,7 @@ class Eye::Dsl::GroupOpts < Eye::Dsl::Opts
21
21
  @config[:processes][name.to_s] ||= {}
22
22
  Eye::Utils.deep_merge!(@config[:processes][name.to_s], opts.config) if opts.config
23
23
 
24
- Eye::Dsl.debug "<= process #{name}"
24
+ Eye::Dsl.debug { "<= process #{name}" }
25
25
  opts
26
26
  end
27
27
 
@@ -5,7 +5,7 @@ module Eye::Dsl::Main
5
5
  Eye::Dsl.check_name(name)
6
6
  name = name.to_s
7
7
 
8
- Eye::Dsl.debug "=> app: #{name}"
8
+ Eye::Dsl.debug { "=> app: #{name}" }
9
9
 
10
10
  if name == '__default__'
11
11
  @parsed_default_app ||= Eye::Dsl::ApplicationOpts.new(name)
@@ -16,7 +16,7 @@ module Eye::Dsl::Main
16
16
  @parsed_config.applications[name] = opts.config if opts.config
17
17
  end
18
18
 
19
- Eye::Dsl.debug "<= app: #{name}"
19
+ Eye::Dsl.debug { "<= app: #{name}" }
20
20
  end
21
21
 
22
22
  alias project application
@@ -29,11 +29,11 @@ module Eye::Dsl::Main
29
29
  Eye::Dsl::Opts.with_parsed_file(glob) do |mask|
30
30
  Dir[mask].each do |path|
31
31
  loaded = true
32
- Eye::Dsl.debug "=> load #{path}"
32
+ Eye::Dsl.debug { "=> load #{path}" }
33
33
  Eye.parsed_filename = path
34
34
  res = Kernel.load(path)
35
35
  Eye.info "load: subload #{path} (#{res})"
36
- Eye::Dsl.debug "<= load #{path}"
36
+ Eye::Dsl.debug { "<= load #{path}" }
37
37
  end
38
38
  end
39
39
 
@@ -44,13 +44,13 @@ module Eye::Dsl::Main
44
44
  end
45
45
 
46
46
  def config(&block)
47
- Eye::Dsl.debug '=> config'
47
+ Eye::Dsl.debug { '=> config' }
48
48
 
49
49
  opts = Eye::Dsl::ConfigOpts.new
50
50
  opts.instance_eval(&block)
51
51
  Eye::Utils.deep_merge!(@parsed_config.settings, opts.config)
52
52
 
53
- Eye::Dsl.debug '<= config'
53
+ Eye::Dsl.debug { '<= config' }
54
54
  end
55
55
 
56
56
  alias settings config
@@ -13,7 +13,6 @@ class Eye::Dsl::Opts < Eye::Dsl::PureOpts
13
13
  create_options_methods(INTERVAL_OPTIONS, [Fixnum, Float])
14
14
 
15
15
  create_options_methods([:environment], Hash)
16
- create_options_methods([:stop_signals], Array)
17
16
  create_options_methods([:umask], Fixnum)
18
17
 
19
18
 
@@ -95,9 +94,18 @@ class Eye::Dsl::Opts < Eye::Dsl::PureOpts
95
94
  @config[:notify].delete(contact.to_s)
96
95
  end
97
96
 
98
- def set_stop_signals(value)
99
- super
100
- validate_signals(value)
97
+ def stop_signals(*args)
98
+ if args.count == 0
99
+ return @config[:stop_signals]
100
+ end
101
+
102
+ signals = Array(args).flatten
103
+ validate_signals(signals)
104
+ @config[:stop_signals] = signals
105
+ end
106
+
107
+ def stop_signals=(s)
108
+ stop_signals(s)
101
109
  end
102
110
 
103
111
  def set_environment(value)
@@ -83,9 +83,9 @@ class Eye::Dsl::PureOpts
83
83
  if proc.is_a?(String)
84
84
  self.class.with_parsed_file(proc) do |path|
85
85
  if File.exists?(path)
86
- Eye::Dsl.debug "=> load #{path}"
86
+ Eye::Dsl.debug { "=> load #{path}" }
87
87
  self.instance_eval(File.read(path))
88
- Eye::Dsl.debug "<= load #{path}"
88
+ Eye::Dsl.debug { "<= load #{path}" }
89
89
  end
90
90
  end
91
91
  else
@@ -106,11 +106,10 @@ private
106
106
  def self.with_parsed_file(file_name)
107
107
  saved_parsed_filename = Eye.parsed_filename
108
108
 
109
- require 'pathname'
110
109
 
111
110
  real_filename = Eye.parsed_filename && File.symlink?(Eye.parsed_filename) ? File.readlink(Eye.parsed_filename) : Eye.parsed_filename
112
111
  dirname = File.dirname(real_filename) rescue nil
113
- path = Pathname.new(file_name).expand_path(dirname).to_s
112
+ path = File.expand_path(file_name, dirname)
114
113
 
115
114
  Eye.parsed_filename = path
116
115
  yield path
@@ -118,4 +117,4 @@ private
118
117
  Eye.parsed_filename = saved_parsed_filename
119
118
  end
120
119
 
121
- end
120
+ end
@@ -15,7 +15,7 @@ class Eye::Group
15
15
  @config = config
16
16
  @processes = Eye::Utils::AliveArray.new
17
17
  @hidden = (name == '__default__')
18
- debug 'created'
18
+ debug { 'created' }
19
19
  end
20
20
 
21
21
  def logger_tag
@@ -26,14 +26,14 @@ private
26
26
  break if @chain_breaker
27
27
  end
28
28
 
29
- debug "chain finished #{Time.now - started_at}s"
29
+ debug { "chain finished #{Time.now - started_at}s" }
30
30
 
31
31
  @chain_processes_count = nil
32
32
  @chain_processes_current = nil
33
33
  end
34
34
 
35
35
  def chain_schedule_process(process, type, command, *args)
36
- debug "chain_schedule_process #{process.name} #{type} #{command}"
36
+ debug { "chain_schedule_process #{process.name} #{type} #{command}" }
37
37
 
38
38
  if type == :sync
39
39
  # sync command, with waiting
@@ -5,7 +5,7 @@ module Eye::Local
5
5
  def dir
6
6
  @dir ||= begin
7
7
  if root?
8
- '/var/run/eye'
8
+ '/var/run/eye'
9
9
  else
10
10
  File.expand_path(File.join(home, '.eye'))
11
11
  end
@@ -35,11 +35,11 @@ module Eye::Local
35
35
  end
36
36
 
37
37
  def path(path)
38
- File.join(dir, path)
38
+ File.expand_path(path, dir)
39
39
  end
40
40
 
41
41
  def ensure_eye_dir
42
- FileUtils.mkdir_p( dir )
42
+ FileUtils.mkdir_p(dir)
43
43
  end
44
44
 
45
45
  def socket_path
@@ -10,7 +10,7 @@ class Eye::Logger
10
10
  super
11
11
 
12
12
  self.formatter = Proc.new do |s, d, p, m|
13
- "#{d.strftime(FORMAT)} $#{$$} #{s.ljust(5)} -- #{m}\n"
13
+ "#{d.strftime(FORMAT)} #{s.ljust(5)} -- #{m}\n"
14
14
  end
15
15
  end
16
16
  end
@@ -29,8 +29,8 @@ class Eye::Logger
29
29
 
30
30
  Logger::Severity.constants.each do |level|
31
31
  method_name = level.to_s.downcase
32
- define_method method_name do |msg|
33
- logger.send(method_name, msg)
32
+ define_method method_name do |msg = nil, &block|
33
+ logger.send(method_name, msg, &block)
34
34
  end
35
35
  end
36
36
 
@@ -42,8 +42,12 @@ class Eye::Logger
42
42
 
43
43
  Logger::Severity.constants.each do |level|
44
44
  method_name = level.to_s.downcase
45
- define_method method_name do |msg|
46
- self.class.inner_logger.send(method_name, "#{prefix_str}#{msg}")
45
+ define_method method_name do |msg = nil, &block|
46
+ if block
47
+ self.class.inner_logger.send(method_name) { "#{prefix_str}#{block.call}" }
48
+ else
49
+ self.class.inner_logger.send(method_name, "#{prefix_str}#{msg}")
50
+ end
47
51
  end
48
52
  end
49
53
 
@@ -57,17 +61,23 @@ class Eye::Logger
57
61
 
58
62
  def link_logger(dev, *args)
59
63
  old_dev = @dev
60
- @dev = dev ? dev.to_s : nil
61
- @dev_fd = @dev
64
+ @dev = @dev_fd = dev
62
65
  @args = args
63
66
 
64
- @dev_fd = STDOUT if @dev.to_s.downcase == 'stdout'
65
- @dev_fd = STDERR if @dev.to_s.downcase == 'stderr'
67
+ if dev.nil?
68
+ @inner_logger = InnerLogger.new(nil)
69
+ elsif dev.is_a?(String)
70
+ @dev_fd = STDOUT if @dev.to_s.downcase == 'stdout'
71
+ @dev_fd = STDERR if @dev.to_s.downcase == 'stderr'
72
+ @inner_logger = InnerLogger.new(@dev_fd, *args)
73
+ else
74
+ @inner_logger = dev
75
+ end
66
76
 
67
- @inner_logger = InnerLogger.new(@dev_fd, *args)
68
77
  @inner_logger.level = self.log_level || Logger::INFO
69
78
 
70
- rescue Errno::ENOENT, Errno::EACCES
79
+ rescue Exception
80
+ @inner_logger = nil
71
81
  @dev = old_dev
72
82
  raise
73
83
  end
@@ -56,7 +56,7 @@ class Eye::Notify
56
56
  @message_h = message_h
57
57
  @options = options
58
58
 
59
- debug "created notifier #{options}"
59
+ debug { "created notifier #{options}" }
60
60
  end
61
61
 
62
62
  def logger_sub_tag
@@ -69,9 +69,9 @@ class Eye::Notify
69
69
  end
70
70
 
71
71
  def notify
72
- debug "start notify #{@message_h}"
72
+ debug { "start notify #{@message_h}" }
73
73
  execute
74
- debug "end notify #{@message_h}"
74
+ debug { "end notify #{@message_h}" }
75
75
  terminate
76
76
  end
77
77
 
@@ -13,7 +13,7 @@ class Eye::Notify::Jabber < Eye::Notify
13
13
  param :password, String
14
14
 
15
15
  def execute
16
- debug "send jabber #{[host, port, user, password]} - #{[contact, message_body]}"
16
+ debug { "send jabber #{[host, port, user, password]} - #{[contact, message_body]}" }
17
17
 
18
18
  mes = ::Jabber::Message.new(contact, message_body)
19
19
  mes.set_type(:normal)
@@ -26,7 +26,7 @@ class Eye::Notify::Mail < Eye::Notify
26
26
 
27
27
  def smtp
28
28
  args = [host, port, domain, user, password, auth]
29
- debug "called smtp with #{args}"
29
+ debug { "called smtp with #{args}" }
30
30
  smtp = Net::SMTP.new host, port
31
31
  smtp.enable_starttls if starttls
32
32
 
@@ -36,7 +36,7 @@ class Eye::Process
36
36
  @states_history = Eye::Process::StatesHistory.new(100)
37
37
  @states_history << :unmonitored
38
38
 
39
- debug "creating with config: #{@config.inspect}"
39
+ debug { "creating with config: #{@config.inspect}" }
40
40
 
41
41
  add_triggers
42
42
 
@@ -40,7 +40,7 @@ module Eye::Process::Children
40
40
  end
41
41
 
42
42
  h = {:new => new_children.size, :removed => removed_children.size, :exists => exist_children.size }
43
- debug "children info: #{ h.inspect }"
43
+ debug { "children info: #{ h.inspect }" }
44
44
 
45
45
  @updating_children = false
46
46
  h
@@ -1,7 +1,7 @@
1
1
  module Eye::Process::Commands
2
2
 
3
3
  def start_process
4
- debug 'start_process command'
4
+ debug { 'start_process command' }
5
5
 
6
6
  switch :starting
7
7
 
@@ -14,7 +14,7 @@ module Eye::Process::Commands
14
14
  result = self[:daemonize] ? daemonize_process : execute_process
15
15
 
16
16
  if !result[:error]
17
- debug "process <#{self.pid}> started successfully"
17
+ debug { "process <#{self.pid}> started successfully" }
18
18
  switch :started
19
19
  else
20
20
  error "process <#{self.pid}> failed to start (#{result[:error].inspect})"
@@ -38,7 +38,7 @@ module Eye::Process::Commands
38
38
  end
39
39
 
40
40
  def stop_process
41
- debug 'stop_process command'
41
+ debug { 'stop_process command' }
42
42
 
43
43
  switch :stopping
44
44
 
@@ -64,7 +64,7 @@ module Eye::Process::Commands
64
64
  end
65
65
 
66
66
  def restart_process
67
- debug 'restart_process command'
67
+ debug { 'restart_process command' }
68
68
 
69
69
  switch :restarting
70
70
 
@@ -131,7 +131,7 @@ private
131
131
  sleep_grace(:stop_grace)
132
132
 
133
133
  else # default command
134
- debug "executing: `kill -TERM #{self.pid}` with stop_grace: #{self[:stop_grace].to_f}s"
134
+ debug { "executing: `kill -TERM #{self.pid}` with stop_grace: #{self[:stop_grace].to_f}s" }
135
135
  send_signal(:TERM)
136
136
 
137
137
  sleep_grace(:stop_grace)
@@ -292,7 +292,10 @@ private
292
292
  while signals.present?
293
293
  delay = signals.shift
294
294
  signal = signals.shift
295
- sleep (delay.to_f)
295
+ if wait_for_condition(delay.to_f, 0.3){ !process_really_running? }
296
+ info 'has terminated'
297
+ break
298
+ end
296
299
  send_signal(signal) if signal
297
300
  end
298
301
  else
@@ -58,7 +58,7 @@ module Eye::Process::Config
58
58
  @full_name = nil
59
59
  @logger = nil
60
60
 
61
- debug "updating config to: #{@config.inspect}"
61
+ debug { "updating config to: #{@config.inspect}" }
62
62
 
63
63
  remove_triggers
64
64
  add_triggers
@@ -26,7 +26,7 @@ private
26
26
  return false
27
27
  end
28
28
  else
29
- debug 'process was not found'
29
+ debug { 'process was not found' }
30
30
  return false
31
31
  end
32
32
  end
@@ -97,7 +97,7 @@ private
97
97
  schedule :unmonitor, Eye::Reason.new(:crashed)
98
98
  end
99
99
  else
100
- debug 'check crashed: skipped, process is not in down'
100
+ debug { 'check crashed: skipped, process is not in down' }
101
101
  end
102
102
  end
103
103
 
@@ -27,9 +27,9 @@ module Eye::Process::Scheduler
27
27
  end
28
28
 
29
29
  def schedule_in(interval, command, *args, &block)
30
- debug "schedule_in #{interval} :#{command} #{args}"
30
+ debug { "schedule_in #{interval} :#{command} #{args}" }
31
31
  after(interval.to_f) do
32
- debug "scheduled_in #{interval} :#{command} #{args}"
32
+ debug { "scheduled_in #{interval} :#{command} #{args}" }
33
33
  schedule(command, *args, &block)
34
34
  end
35
35
  end
@@ -8,17 +8,6 @@ module Eye::Process::System
8
8
  _pid > 0 ? _pid : nil
9
9
  end
10
10
 
11
- # check pid from pid_file, in case when server reboot, or something
12
- # sometimes pid can be one of the eye-self(lwp) pid, we dont want
13
- # eye to die
14
- if res && res != self.pid
15
- cmd = Eye::Sigar.proc_args(res)[0].to_s rescue ''
16
- if res == $$ || cmd.start_with?(Eye::PROCLINE)
17
- error "Wtf? O_o load eye-self(lwp) pid_file #{res} #{$$} '#{cmd}'"
18
- return
19
- end
20
- end
21
-
22
11
  res
23
12
  end
24
13
 
@@ -55,14 +44,14 @@ module Eye::Process::System
55
44
 
56
45
  def process_pid_running?(pid)
57
46
  res = Eye::System.check_pid_alive(pid)
58
- debug "process_really_running?: (#{pid}) #{res.inspect}"
47
+ debug { "process_really_running?: <#{pid}> #{res.inspect}" }
59
48
  !!res[:result]
60
49
  end
61
50
 
62
51
  def send_signal(code)
63
52
  res = Eye::System.send_signal(self.pid, code)
64
53
 
65
- msg = "send_signal #{code} to #{self.pid}"
54
+ msg = "send_signal #{code} to <#{self.pid}>"
66
55
  msg += ", error<#{res[:error]}>" if res[:error]
67
56
  info msg
68
57
 
@@ -35,10 +35,10 @@ private
35
35
  def add_watcher(type, period = 2, subject = nil, &block)
36
36
  return if @watchers[type]
37
37
 
38
- debug "adding watcher: #{type}(#{period})"
38
+ debug { "adding watcher: #{type}(#{period})" }
39
39
 
40
40
  timer = every(period.to_f) do
41
- debug "check #{type}"
41
+ debug { "check #{type}" }
42
42
  block.call(subject)
43
43
  end
44
44
 
@@ -1,5 +1,4 @@
1
1
  require 'shellwords'
2
- require 'pathname'
3
2
  require 'etc'
4
3
  require 'timeout'
5
4
 
@@ -101,7 +100,7 @@ module Eye::System
101
100
 
102
101
  # normalize file
103
102
  def normalized_file(file, working_dir = nil)
104
- Pathname.new(file).expand_path(working_dir).to_s
103
+ File.expand_path(file, working_dir)
105
104
  end
106
105
 
107
106
  def spawn_options(config = {})
@@ -49,7 +49,7 @@ class Eye::Trigger
49
49
  @process = process
50
50
  @full_name = @process.full_name if @process
51
51
 
52
- debug "add #{options}"
52
+ debug { "add #{options}" }
53
53
  end
54
54
 
55
55
  def inspect
@@ -65,7 +65,7 @@ class Eye::Trigger
65
65
  end
66
66
 
67
67
  def notify(transition, reason)
68
- debug "check (:#{transition.event}) :#{transition.from} => :#{transition.to}"
68
+ debug { "check (:#{transition.event}) :#{transition.from} => :#{transition.to}" }
69
69
  @reason = reason
70
70
  @transition = transition
71
71
 
@@ -27,7 +27,7 @@ private
27
27
  end
28
28
 
29
29
  def on_flapping
30
- debug 'flapping recognized!!!'
30
+ debug { 'flapping recognized!!!' }
31
31
 
32
32
  process.notify :error, 'flapping!'
33
33
  process.schedule :unmonitor, Eye::Reason.new(:flapping)
@@ -10,7 +10,7 @@ class Eye::Trigger::StopChildren < Eye::Trigger
10
10
  param_default :event, [:stopped, :crashed]
11
11
 
12
12
  def check(trans)
13
- debug 'stopping children'
13
+ debug { 'stopping children' }
14
14
  process.children.pmap { |pid, c| c.stop }
15
15
  end
16
16
 
metadata CHANGED
@@ -1,251 +1,251 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eye
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.2
4
+ version: 0.6.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Konstantin Makarchev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-17 00:00:00.000000000 Z
11
+ date: 2014-10-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: celluloid
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ~>
18
18
  - !ruby/object:Gem::Version
19
19
  version: 0.15.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ~>
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.15.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: celluloid-io
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ~>
32
32
  - !ruby/object:Gem::Version
33
33
  version: 0.15.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ~>
39
39
  - !ruby/object:Gem::Version
40
40
  version: 0.15.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: state_machine
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - ! '>='
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - ! '>='
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: thor
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ">="
59
+ - - ! '>='
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ">="
66
+ - - ! '>='
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: sigar
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - "~>"
73
+ - - ~>
74
74
  - !ruby/object:Gem::Version
75
75
  version: 0.7.2
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - "~>"
80
+ - - ~>
81
81
  - !ruby/object:Gem::Version
82
82
  version: 0.7.2
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rake
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ">="
87
+ - - ! '>='
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - ">="
94
+ - - ! '>='
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: rspec
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - "<"
101
+ - - <
102
102
  - !ruby/object:Gem::Version
103
103
  version: '2.14'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - "<"
108
+ - - <
109
109
  - !ruby/object:Gem::Version
110
110
  version: '2.14'
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: rr
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - ">="
115
+ - - ! '>='
116
116
  - !ruby/object:Gem::Version
117
117
  version: '0'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - ">="
122
+ - - ! '>='
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: ruby-graphviz
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
- - - ">="
129
+ - - ! '>='
130
130
  - !ruby/object:Gem::Version
131
131
  version: '0'
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
- - - ">="
136
+ - - ! '>='
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: forking
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
- - - ">="
143
+ - - ! '>='
144
144
  - !ruby/object:Gem::Version
145
145
  version: '0'
146
146
  type: :development
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
- - - ">="
150
+ - - ! '>='
151
151
  - !ruby/object:Gem::Version
152
152
  version: '0'
153
153
  - !ruby/object:Gem::Dependency
154
154
  name: fakeweb
155
155
  requirement: !ruby/object:Gem::Requirement
156
156
  requirements:
157
- - - ">="
157
+ - - ! '>='
158
158
  - !ruby/object:Gem::Version
159
159
  version: '0'
160
160
  type: :development
161
161
  prerelease: false
162
162
  version_requirements: !ruby/object:Gem::Requirement
163
163
  requirements:
164
- - - ">="
164
+ - - ! '>='
165
165
  - !ruby/object:Gem::Version
166
166
  version: '0'
167
167
  - !ruby/object:Gem::Dependency
168
168
  name: eventmachine
169
169
  requirement: !ruby/object:Gem::Requirement
170
170
  requirements:
171
- - - ">="
171
+ - - ! '>='
172
172
  - !ruby/object:Gem::Version
173
173
  version: 1.0.3
174
174
  type: :development
175
175
  prerelease: false
176
176
  version_requirements: !ruby/object:Gem::Requirement
177
177
  requirements:
178
- - - ">="
178
+ - - ! '>='
179
179
  - !ruby/object:Gem::Version
180
180
  version: 1.0.3
181
181
  - !ruby/object:Gem::Dependency
182
182
  name: sinatra
183
183
  requirement: !ruby/object:Gem::Requirement
184
184
  requirements:
185
- - - ">="
185
+ - - ! '>='
186
186
  - !ruby/object:Gem::Version
187
187
  version: '0'
188
188
  type: :development
189
189
  prerelease: false
190
190
  version_requirements: !ruby/object:Gem::Requirement
191
191
  requirements:
192
- - - ">="
192
+ - - ! '>='
193
193
  - !ruby/object:Gem::Version
194
194
  version: '0'
195
195
  - !ruby/object:Gem::Dependency
196
196
  name: thin
197
197
  requirement: !ruby/object:Gem::Requirement
198
198
  requirements:
199
- - - ">="
199
+ - - ! '>='
200
200
  - !ruby/object:Gem::Version
201
201
  version: '0'
202
202
  type: :development
203
203
  prerelease: false
204
204
  version_requirements: !ruby/object:Gem::Requirement
205
205
  requirements:
206
- - - ">="
206
+ - - ! '>='
207
207
  - !ruby/object:Gem::Version
208
208
  version: '0'
209
209
  - !ruby/object:Gem::Dependency
210
210
  name: xmpp4r
211
211
  requirement: !ruby/object:Gem::Requirement
212
212
  requirements:
213
- - - ">="
213
+ - - ! '>='
214
214
  - !ruby/object:Gem::Version
215
215
  version: '0'
216
216
  type: :development
217
217
  prerelease: false
218
218
  version_requirements: !ruby/object:Gem::Requirement
219
219
  requirements:
220
- - - ">="
220
+ - - ! '>='
221
221
  - !ruby/object:Gem::Version
222
222
  version: '0'
223
223
  - !ruby/object:Gem::Dependency
224
224
  name: coveralls
225
225
  requirement: !ruby/object:Gem::Requirement
226
226
  requirements:
227
- - - ">="
227
+ - - ! '>='
228
228
  - !ruby/object:Gem::Version
229
229
  version: '0'
230
230
  type: :development
231
231
  prerelease: false
232
232
  version_requirements: !ruby/object:Gem::Requirement
233
233
  requirements:
234
- - - ">="
234
+ - - ! '>='
235
235
  - !ruby/object:Gem::Version
236
236
  version: '0'
237
237
  - !ruby/object:Gem::Dependency
238
238
  name: simplecov
239
239
  requirement: !ruby/object:Gem::Requirement
240
240
  requirements:
241
- - - ">="
241
+ - - ! '>='
242
242
  - !ruby/object:Gem::Version
243
243
  version: 0.8.1
244
244
  type: :development
245
245
  prerelease: false
246
246
  version_requirements: !ruby/object:Gem::Requirement
247
247
  requirements:
248
- - - ">="
248
+ - - ! '>='
249
249
  - !ruby/object:Gem::Version
250
250
  version: 0.8.1
251
251
  description: Process monitoring tool. Inspired from Bluepill and God. Requires Ruby(MRI)
@@ -253,22 +253,23 @@ description: Process monitoring tool. Inspired from Bluepill and God. Requires R
253
253
  email: eye-rb@googlegroups.com
254
254
  executables:
255
255
  - eye
256
+ - leye
256
257
  - loader_eye
257
- - runner
258
258
  extensions: []
259
259
  extra_rdoc_files: []
260
260
  files:
261
- - ".gitignore"
262
- - ".rspec"
263
- - ".travis.yml"
261
+ - .gitignore
262
+ - .rspec
263
+ - .travis.yml
264
264
  - CHANGES.md
265
265
  - Gemfile
266
266
  - LICENSE
267
267
  - README.md
268
268
  - Rakefile
269
269
  - bin/eye
270
+ - bin/leye
270
271
  - bin/loader_eye
271
- - bin/runner
272
+ - examples/delayed_job.eye
272
273
  - examples/dependency.eye
273
274
  - examples/notify.eye
274
275
  - examples/plugin/README.md
@@ -282,6 +283,7 @@ files:
282
283
  - examples/puma.eye
283
284
  - examples/rbenv.eye
284
285
  - examples/sidekiq.eye
286
+ - examples/stress_test.eye
285
287
  - examples/test.eye
286
288
  - examples/thin-farm.eye
287
289
  - examples/unicorn.eye
@@ -380,12 +382,12 @@ require_paths:
380
382
  - lib
381
383
  required_ruby_version: !ruby/object:Gem::Requirement
382
384
  requirements:
383
- - - ">="
385
+ - - ! '>='
384
386
  - !ruby/object:Gem::Version
385
387
  version: 1.9.2
386
388
  required_rubygems_version: !ruby/object:Gem::Requirement
387
389
  requirements:
388
- - - ">="
390
+ - - ! '>='
389
391
  - !ruby/object:Gem::Version
390
392
  version: 1.3.6
391
393
  requirements: []