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 (79) hide show
  1. checksums.yaml +4 -4
  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 +11 -8
  31. data/lib/eye/controller/commands.rb +8 -9
  32. data/lib/eye/controller/helpers.rb +1 -0
  33. data/lib/eye/controller/load.rb +11 -7
  34. data/lib/eye/controller/send_command.rb +44 -19
  35. data/lib/eye/controller/show_history.rb +8 -7
  36. data/lib/eye/controller/status.rb +39 -26
  37. data/lib/eye/dsl.rb +3 -3
  38. data/lib/eye/dsl/application_opts.rb +4 -4
  39. data/lib/eye/dsl/config_opts.rb +4 -4
  40. data/lib/eye/dsl/helpers.rb +2 -2
  41. data/lib/eye/dsl/main.rb +2 -2
  42. data/lib/eye/dsl/opts.rb +19 -14
  43. data/lib/eye/dsl/process_opts.rb +1 -1
  44. data/lib/eye/dsl/pure_opts.rb +2 -2
  45. data/lib/eye/dsl/validation.rb +7 -5
  46. data/lib/eye/group.rb +17 -11
  47. data/lib/eye/group/chain.rb +3 -3
  48. data/lib/eye/loader.rb +8 -6
  49. data/lib/eye/logger.rb +14 -5
  50. data/lib/eye/notify.rb +13 -7
  51. data/lib/eye/notify/jabber.rb +2 -2
  52. data/lib/eye/notify/mail.rb +2 -2
  53. data/lib/eye/process.rb +10 -13
  54. data/lib/eye/process/child.rb +1 -1
  55. data/lib/eye/process/commands.rb +34 -32
  56. data/lib/eye/process/config.rb +17 -12
  57. data/lib/eye/process/controller.rb +3 -6
  58. data/lib/eye/process/data.rb +16 -5
  59. data/lib/eye/process/monitor.rb +12 -5
  60. data/lib/eye/process/notify.rb +1 -1
  61. data/lib/eye/process/scheduler.rb +3 -3
  62. data/lib/eye/process/states.rb +10 -13
  63. data/lib/eye/process/states_history.rb +3 -3
  64. data/lib/eye/process/system.rb +17 -21
  65. data/lib/eye/process/trigger.rb +11 -30
  66. data/lib/eye/process/watchers.rb +9 -9
  67. data/lib/eye/server.rb +14 -6
  68. data/lib/eye/settings.rb +4 -4
  69. data/lib/eye/system.rb +10 -7
  70. data/lib/eye/system_resources.rb +4 -4
  71. data/lib/eye/trigger.rb +58 -21
  72. data/lib/eye/trigger/flapping.rb +24 -4
  73. data/lib/eye/trigger/state.rb +28 -0
  74. data/lib/eye/utils/alive_array.rb +1 -1
  75. data/lib/eye/utils/celluloid_klass.rb +5 -0
  76. data/lib/eye/utils/pmap.rb +7 -0
  77. data/lib/eye/utils/tail.rb +1 -1
  78. metadata +39 -23
  79. data/lib/eye/utils/leak_19.rb +0 -7
@@ -31,8 +31,8 @@ class Eye::SystemResources
31
31
  def resources(pid)
32
32
  return {} unless ps_aux[pid]
33
33
 
34
- { :memory => memory(pid),
35
- :cpu => cpu(pid),
34
+ { :memory => memory(pid),
35
+ :cpu => cpu(pid),
36
36
  :start_time => start_time(pid),
37
37
  :pid => pid
38
38
  }
@@ -42,14 +42,14 @@ class Eye::SystemResources
42
42
  def setup
43
43
  @actor ||= PsAxActor.new
44
44
  end
45
-
45
+
46
46
  private
47
47
 
48
48
  def reset!
49
49
  setup.terminate
50
50
  @actor = nil
51
51
  end
52
-
52
+
53
53
  def ps_aux
54
54
  setup
55
55
  @actor.get
@@ -1,13 +1,24 @@
1
1
  class Eye::Trigger
2
- include Eye::Logger::Helpers
3
-
4
2
  autoload :Flapping, 'eye/trigger/flapping'
3
+ autoload :State, 'eye/trigger/state'
5
4
 
6
5
  # ex: { :type => :flapping, :times => 2, :within => 30.seconds}
7
6
 
8
- TYPES = {:flapping => "Flapping"}
7
+ TYPES = {:flapping => "Flapping", :state => "State"}
9
8
 
10
- attr_reader :message, :options
9
+ attr_reader :message, :options, :process
10
+
11
+ extend Eye::Dsl::Validation
12
+
13
+ def self.name_and_class(type)
14
+ type = type.to_sym
15
+ return {:name => type, :type => type} if TYPES[type]
16
+
17
+ if type =~ /\A(.*?)_?[0-9]+\z/
18
+ ctype = $1.to_sym
19
+ return {:name => type, :type => ctype} if TYPES[ctype]
20
+ end
21
+ end
11
22
 
12
23
  def self.get_class(type)
13
24
  klass = eval("Eye::Trigger::#{TYPES[type]}") rescue nil
@@ -15,39 +26,65 @@ class Eye::Trigger
15
26
  klass
16
27
  end
17
28
 
18
- def self.create(options = {}, logger_prefix = nil)
19
- get_class(options[:type]).new(options, logger_prefix)
29
+ def self.create(process, options = {})
30
+ get_class(options[:type]).new(process, options)
20
31
  end
21
32
 
22
33
  def self.validate!(options = {})
23
34
  get_class(options[:type]).validate(options)
24
35
  end
25
36
 
26
- def initialize(options = {}, logger_prefix = nil)
37
+ def initialize(process, options = {})
27
38
  @options = options
28
- @logger = Eye::Logger.new(logger_prefix, "trigger")
39
+ @process = process
29
40
 
30
41
  debug "add #{options}"
31
42
  end
32
43
 
33
- def check(states_history)
34
- @states_history = states_history
44
+ def inspect
45
+ "<#{self.class} @process='#{@process.full_name}' @options=#{@options}>"
46
+ end
35
47
 
36
- res = good?
48
+ def logger_tag
49
+ @process.logger.prefix
50
+ end
37
51
 
38
- if res
39
- debug 'check flapping'
40
- else
41
- debug "!!! #{self.class} recognized !!!"
42
- end
43
-
44
- res
52
+ def logger_sub_tag
53
+ "trigger(#{@options[:type]})"
45
54
  end
46
55
 
47
- def good?
48
- raise 'realize me'
56
+ def notify(transition)
57
+ debug "check"
58
+ @transition = transition
59
+ check(transition)
60
+ rescue => ex
61
+ warn "failed #{ex.message} #{ex.backtrace}"
49
62
  end
50
63
 
51
- extend Eye::Dsl::Validation
64
+ def check(transition)
65
+ raise "realize me"
66
+ end
67
+
68
+ def run_in_process_context(p)
69
+ process.instance_exec(&p) if process.alive?
70
+ end
71
+
72
+ def defer(&block)
73
+ Celluloid::Future.new(&block).value
74
+ end
52
75
 
76
+ def self.register(base)
77
+ name = base.to_s.gsub("Eye::Trigger::", '')
78
+ name = base.to_s
79
+ type = name.underscore.to_sym
80
+ Eye::Trigger::TYPES[type] = name
81
+ Eye::Trigger.const_set(name, base)
82
+ end
83
+
84
+ class Custom < Eye::Trigger
85
+ def self.inherited(base)
86
+ super
87
+ register(base)
88
+ end
89
+ end
53
90
  end
@@ -1,6 +1,6 @@
1
1
  class Eye::Trigger::Flapping < Eye::Trigger
2
2
 
3
- # triggers :flapping, :times => 10, :within => 1.minute,
3
+ # triggers :flapping, :times => 10, :within => 1.minute,
4
4
  # :retry_in => 10.minutes, :retry_times => 15
5
5
 
6
6
  param :times, [Fixnum], true, 5
@@ -13,16 +13,36 @@ class Eye::Trigger::Flapping < Eye::Trigger
13
13
  @last_at = nil
14
14
  end
15
15
 
16
+ def check(transition)
17
+ unless good?
18
+ on_flapping
19
+ end
20
+ end
21
+
22
+ private
23
+
16
24
  def good?
17
- states = @states_history.states_for_period( within, @last_at )
25
+ states = process.states_history.states_for_period( within, @last_at )
18
26
  down_count = states.count{|st| st == :down }
19
27
 
20
28
  if down_count >= times
21
- @last_at = @states_history.last_state_changed_at
29
+ @last_at = process.states_history.last_state_changed_at
22
30
  false
23
31
  else
24
32
  true
25
33
  end
26
34
  end
27
35
 
28
- end
36
+ def on_flapping
37
+ debug "flapping recognized!!!"
38
+
39
+ process.notify :error, 'flapping!'
40
+ process.schedule :unmonitor, Eye::Reason.new(:flapping)
41
+
42
+ return unless retry_in
43
+ return if retry_times && process.flapping_times >= retry_times
44
+
45
+ process.schedule_in(retry_in.to_f, :retry_start_after_flapping)
46
+ end
47
+
48
+ end
@@ -0,0 +1,28 @@
1
+ class Eye::Trigger::State < Eye::Trigger
2
+
3
+ # triggers :state, :to => :up, :from => :starting, :do => ->{ ... }
4
+
5
+ param :to, [Symbol, Array]
6
+ param :from, [Symbol, Array]
7
+ param :event, [Symbol, Array]
8
+ param :do, [Proc]
9
+
10
+ def check(trans)
11
+ if compare(trans.to_name, to) || compare(trans.from_name, from) || compare(trans.event, event)
12
+ debug "trans ok #{trans}, executing proc!"
13
+ run_in_process_context(@options[:do]) if @options[:do]
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def compare(state_name, condition)
20
+ case condition
21
+ when Symbol
22
+ state_name == condition
23
+ when Array
24
+ condition.include?(state_name)
25
+ end
26
+ end
27
+
28
+ end
@@ -2,7 +2,7 @@ class Eye::Utils::AliveArray
2
2
  extend Forwardable
3
3
  include Enumerable
4
4
 
5
- def_delegators :@arr, :[], :<<, :clear, :delete, :size, :empty?, :push,
5
+ def_delegators :@arr, :[], :<<, :clear, :delete, :size, :empty?, :push,
6
6
  :flatten, :present?, :uniq!
7
7
 
8
8
  def initialize(arr = [])
@@ -0,0 +1,5 @@
1
+ class Celluloid::SyncProxy
2
+ def __klass__
3
+ @klass
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ module Enumerable
2
+ # Simple parallel map using Celluloid::Futures
3
+ def pmap(&block)
4
+ futures = map { |elem| Celluloid::Future.new(elem, &block) }
5
+ futures.map { |future| future.value }
6
+ end
7
+ end
@@ -9,7 +9,7 @@ class Eye::Utils::Tail < Array
9
9
 
10
10
  def push(el)
11
11
  super(el)
12
- shift if length > @max_size
12
+ shift if length > @max_size
13
13
  self
14
14
  end
15
15
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eye
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: '0.4'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Konstantin Makarchev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-07-07 00:00:00.000000000 Z
11
+ date: 2013-08-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: celluloid
@@ -16,70 +16,70 @@ dependencies:
16
16
  requirements:
17
17
  - - ~>
18
18
  - !ruby/object:Gem::Version
19
- version: 0.13.0
19
+ version: 0.14.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
- version: 0.13.0
26
+ version: 0.14.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
- version: 0.13.0
33
+ version: 0.14.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
- version: 0.13.0
40
+ version: 0.14.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
- version: '1.2'
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
- version: '1.2'
54
+ version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: activesupport
56
+ name: thor
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ~>
59
+ - - '>='
60
60
  - !ruby/object:Gem::Version
61
- version: 3.2.0
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
- version: 3.2.0
68
+ version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: thor
70
+ name: activesupport
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - '>='
74
74
  - !ruby/object:Gem::Version
75
- version: '0'
75
+ version: '3'
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
- version: '0'
82
+ version: '3'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rake
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -98,16 +98,16 @@ dependencies:
98
98
  name: rspec
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - '>='
101
+ - - <
102
102
  - !ruby/object:Gem::Version
103
- version: '0'
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
- version: '0'
110
+ version: '2.14'
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: rr
113
113
  requirement: !ruby/object:Gem::Requirement
@@ -234,6 +234,20 @@ dependencies:
234
234
  - - '>='
235
235
  - !ruby/object:Gem::Version
236
236
  version: '0'
237
+ - !ruby/object:Gem::Dependency
238
+ name: parallel_tests
239
+ requirement: !ruby/object:Gem::Requirement
240
+ requirements:
241
+ - - '>='
242
+ - !ruby/object:Gem::Version
243
+ version: '0'
244
+ type: :development
245
+ prerelease: false
246
+ version_requirements: !ruby/object:Gem::Requirement
247
+ requirements:
248
+ - - '>='
249
+ - !ruby/object:Gem::Version
250
+ version: '0'
237
251
  description: Process monitoring tool. An alternative to God and Bluepill. With Bluepill
238
252
  like config syntax. Requires MRI Ruby >= 1.9.2. Uses Celluloid and Celluloid::IO.
239
253
  email: kostya27@gmail.com
@@ -328,10 +342,12 @@ files:
328
342
  - lib/eye/system_resources.rb
329
343
  - lib/eye/trigger.rb
330
344
  - lib/eye/trigger/flapping.rb
345
+ - lib/eye/trigger/state.rb
331
346
  - lib/eye/utils.rb
332
347
  - lib/eye/utils/alive_array.rb
333
348
  - lib/eye/utils/celluloid_chain.rb
334
- - lib/eye/utils/leak_19.rb
349
+ - lib/eye/utils/celluloid_klass.rb
350
+ - lib/eye/utils/pmap.rb
335
351
  - lib/eye/utils/tail.rb
336
352
  homepage: http://github.com/kostya/eye
337
353
  licenses:
@@ -1,7 +0,0 @@
1
- # http://stackoverflow.com/questions/7263268/ruby-symbolto-proc-leaks-references-in-1-9-2-p180
2
-
3
- class Symbol
4
- def to_proc
5
- lambda { |x| x.send(self) }
6
- end
7
- end