reel-eye 0.4.1 → 0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.travis.yml +4 -0
- data/CHANGES.md +17 -1
- data/README.md +3 -3
- data/Rakefile +8 -0
- data/bin/eye +0 -316
- data/bin/loader_eye +3 -3
- data/examples/test.eye +2 -2
- data/eye.gemspec +6 -10
- data/lib/eye.rb +4 -2
- data/lib/eye/application.rb +3 -3
- data/lib/eye/checker.rb +35 -7
- data/lib/eye/checker/cputime.rb +23 -0
- data/lib/eye/checker/file_touched.rb +15 -0
- data/lib/eye/checker/http.rb +7 -9
- data/lib/eye/checker/memory.rb +1 -1
- data/lib/eye/checker/runtime.rb +28 -0
- data/lib/eye/checker/socket.rb +4 -4
- data/lib/eye/cli.rb +166 -0
- data/lib/eye/cli/commands.rb +79 -0
- data/lib/eye/cli/render.rb +137 -0
- data/lib/eye/cli/server.rb +85 -0
- data/lib/eye/client.rb +3 -3
- data/lib/eye/config.rb +17 -14
- data/lib/eye/controller.rb +6 -10
- data/lib/eye/controller/commands.rb +6 -10
- data/lib/eye/controller/helpers.rb +1 -1
- data/lib/eye/controller/send_command.rb +5 -2
- data/lib/eye/controller/status.rb +38 -106
- data/lib/eye/dsl.rb +1 -1
- data/lib/eye/dsl/application_opts.rb +6 -2
- data/lib/eye/dsl/child_process_opts.rb +3 -2
- data/lib/eye/dsl/config_opts.rb +2 -2
- data/lib/eye/dsl/group_opts.rb +2 -1
- data/lib/eye/dsl/main.rb +4 -2
- data/lib/eye/dsl/opts.rb +11 -4
- data/lib/eye/dsl/validation.rb +49 -43
- data/lib/eye/group.rb +1 -1
- data/lib/eye/http.rb +4 -9
- data/lib/eye/http/router.rb +1 -1
- data/lib/eye/loader.rb +5 -9
- data/lib/eye/{settings.rb → local.rb} +1 -1
- data/lib/eye/logger.rb +5 -0
- data/lib/eye/notify.rb +12 -6
- data/lib/eye/notify/jabber.rb +2 -2
- data/lib/eye/process/child.rb +3 -1
- data/lib/eye/process/commands.rb +2 -2
- data/lib/eye/process/controller.rb +1 -1
- data/lib/eye/process/trigger.rb +1 -1
- data/lib/eye/sigar.rb +5 -0
- data/lib/eye/system.rb +8 -7
- data/lib/eye/system_resources.rb +46 -41
- data/lib/eye/trigger.rb +15 -8
- data/lib/eye/trigger/flapping.rb +1 -1
- data/lib/eye/trigger/stop_childs.rb +1 -1
- data/lib/eye/trigger/transition.rb +15 -0
- data/lib/eye/utils.rb +12 -0
- data/lib/eye/utils/leak_19.rb +7 -0
- data/lib/eye/utils/mini_active_support.rb +106 -0
- metadata +40 -17
- data/lib/eye/controller/show_history.rb +0 -63
- data/lib/eye/trigger/state.rb +0 -11
data/lib/eye/group.rb
CHANGED
data/lib/eye/http.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
|
-
gem 'reel', '~> 0.4.0
|
1
|
+
gem 'reel', '~> 0.4.0'
|
2
|
+
gem 'reel-rack'
|
2
3
|
gem 'cuba'
|
3
4
|
|
4
|
-
require 'reel'
|
5
|
+
require 'reel/rack/server'
|
5
6
|
|
6
7
|
class Eye::Http
|
7
8
|
autoload :Router, 'eye/http/router'
|
@@ -16,13 +17,7 @@ class Eye::Http
|
|
16
17
|
|
17
18
|
def start
|
18
19
|
stop
|
19
|
-
|
20
|
-
@server = Reel::Server.supervise(@host, @port) do |connection|
|
21
|
-
while request = connection.request
|
22
|
-
status, headers, body = @router.call(Rack::MockRequest.env_for(request.url, :method => request.method, :input => request.body))
|
23
|
-
connection.respond(Reel::Response.new(status, headers, body))
|
24
|
-
end
|
25
|
-
end
|
20
|
+
@server = Reel::Rack::Server.supervise(@router, :Host => @host, :Port => port)
|
26
21
|
end
|
27
22
|
|
28
23
|
def stop
|
data/lib/eye/http/router.rb
CHANGED
@@ -13,7 +13,7 @@ Eye::Http::Router = Cuba.new do
|
|
13
13
|
end
|
14
14
|
|
15
15
|
on "api/info", param("filter") do |filter|
|
16
|
-
json Eye::Control.command(:
|
16
|
+
json Eye::Control.command(:info_data, filter)
|
17
17
|
end
|
18
18
|
|
19
19
|
[:start, :stop, :restart, :delete, :unmonitor, :monitor].each do |act|
|
data/lib/eye/loader.rb
CHANGED
@@ -1,14 +1,10 @@
|
|
1
|
-
#
|
1
|
+
# add gems to $: by `gem` method
|
2
|
+
# this is only way when install eye as system wide
|
2
3
|
|
3
|
-
gem 'celluloid', '~> 0.
|
4
|
-
gem 'celluloid-io', '~> 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'
|
data/lib/eye/logger.rb
CHANGED
@@ -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)
|
data/lib/eye/notify.rb
CHANGED
@@ -1,15 +1,18 @@
|
|
1
1
|
class Eye::Notify
|
2
2
|
include Celluloid
|
3
|
-
|
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 =>
|
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
|
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.
|
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(
|
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
|
data/lib/eye/notify/jabber.rb
CHANGED
@@ -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)
|
data/lib/eye/process/child.rb
CHANGED
@@ -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
|
|
data/lib/eye/process/commands.rb
CHANGED
@@ -88,7 +88,7 @@ private
|
|
88
88
|
|
89
89
|
def kill_process
|
90
90
|
unless self.pid
|
91
|
-
error
|
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
|
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
|
46
|
+
warn 'process not found, so :unmonitor'
|
47
47
|
schedule :unmonitor, Eye::Reason.new(:'not found')
|
48
48
|
end
|
49
49
|
end
|
data/lib/eye/process/trigger.rb
CHANGED
@@ -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
|
data/lib/eye/sigar.rb
ADDED
data/lib/eye/system.rb
CHANGED
@@ -55,13 +55,15 @@ module Eye::System
|
|
55
55
|
# :environment
|
56
56
|
# :stdin, :stdout, :stderr
|
57
57
|
def daemonize(cmd, cfg = {})
|
58
|
-
|
59
|
-
|
60
|
-
Process.detach(pid)
|
58
|
+
pid = ::Process::spawn(prepare_env(cfg), *Shellwords.shellwords(cmd), spawn_options(cfg))
|
59
|
+
|
61
60
|
{:pid => pid, :exitstatus => 0}
|
62
61
|
|
63
62
|
rescue Errno::ENOENT, Errno::EACCES => ex
|
64
63
|
{:error => ex}
|
64
|
+
|
65
|
+
ensure
|
66
|
+
Process.detach(pid) if pid
|
65
67
|
end
|
66
68
|
|
67
69
|
# Execute cmd with blocking, return status (be careful: inside actor blocks it mailbox, use with defer)
|
@@ -70,8 +72,7 @@ module Eye::System
|
|
70
72
|
# :environment
|
71
73
|
# :stdin, :stdout, :stderr
|
72
74
|
def execute(cmd, cfg = {})
|
73
|
-
|
74
|
-
pid = Process::spawn(prepare_env(cfg), *Shellwords.shellwords(cmd), opts)
|
75
|
+
pid = ::Process::spawn(prepare_env(cfg), *Shellwords.shellwords(cmd), spawn_options(cfg))
|
75
76
|
|
76
77
|
timeout = cfg[:timeout] || 1.second
|
77
78
|
status = 0
|
@@ -142,7 +143,7 @@ module Eye::System
|
|
142
143
|
o.update(err: [config[:stderr], 'a']) if config[:stderr]
|
143
144
|
o.update(in: config[:stdin]) if config[:stdin]
|
144
145
|
|
145
|
-
if Eye::
|
146
|
+
if Eye::Local.root?
|
146
147
|
o.update(uid: Etc.getpwnam(config[:uid]).uid) if config[:uid]
|
147
148
|
o.update(gid: Etc.getpwnam(config[:gid]).gid) if config[:gid]
|
148
149
|
end
|
@@ -156,7 +157,7 @@ module Eye::System
|
|
156
157
|
env = {}
|
157
158
|
|
158
159
|
(config[:environment] || {}).each do |k,v|
|
159
|
-
env[k.to_s] = v
|
160
|
+
env[k.to_s] = v && v.to_s
|
160
161
|
end
|
161
162
|
|
162
163
|
env
|
data/lib/eye/system_resources.rb
CHANGED
@@ -6,31 +6,33 @@ class Eye::SystemResources
|
|
6
6
|
class << self
|
7
7
|
|
8
8
|
def memory(pid)
|
9
|
-
|
9
|
+
cache.proc_mem(pid).try(:resident)
|
10
10
|
end
|
11
11
|
|
12
12
|
def cpu(pid)
|
13
|
-
|
13
|
+
if cpu = cache.proc_cpu(pid)
|
14
|
+
cpu.percent * 100
|
15
|
+
end
|
14
16
|
end
|
15
17
|
|
16
18
|
def childs(parent_pid)
|
17
|
-
parent_pid
|
19
|
+
cache.childs(parent_pid)
|
20
|
+
end
|
18
21
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
+
def start_time(pid) # unixtime
|
23
|
+
if cpu = cache.proc_cpu(pid)
|
24
|
+
cpu.start_time.to_i / 1000
|
22
25
|
end
|
23
|
-
|
24
|
-
childs
|
25
26
|
end
|
26
27
|
|
27
|
-
|
28
|
-
|
28
|
+
# total cpu usage in seconds
|
29
|
+
def cputime(pid)
|
30
|
+
if cpu = cache.proc_cpu(pid)
|
31
|
+
cpu.total.to_f / 1000
|
32
|
+
end
|
29
33
|
end
|
30
34
|
|
31
35
|
def resources(pid)
|
32
|
-
return {} unless ps_aux[pid]
|
33
|
-
|
34
36
|
{ :memory => memory(pid),
|
35
37
|
:cpu => cpu(pid),
|
36
38
|
:start_time => start_time(pid),
|
@@ -38,49 +40,52 @@ class Eye::SystemResources
|
|
38
40
|
}
|
39
41
|
end
|
40
42
|
|
41
|
-
|
42
|
-
|
43
|
-
@actor ||= PsAxActor.new
|
44
|
-
end
|
45
|
-
|
46
|
-
private
|
47
|
-
|
48
|
-
def reset!
|
49
|
-
setup.terminate
|
50
|
-
@actor = nil
|
51
|
-
end
|
52
|
-
|
53
|
-
def ps_aux
|
54
|
-
setup
|
55
|
-
@actor.get
|
43
|
+
def cache
|
44
|
+
@cache ||= Cache.new
|
56
45
|
end
|
57
|
-
|
58
46
|
end
|
59
47
|
|
60
|
-
class
|
48
|
+
class Cache
|
61
49
|
include Celluloid
|
62
50
|
|
63
|
-
|
51
|
+
attr_reader :expire
|
64
52
|
|
65
53
|
def initialize
|
66
|
-
|
54
|
+
clear
|
55
|
+
setup_expire
|
67
56
|
end
|
68
57
|
|
69
|
-
def
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
end
|
74
|
-
@ps_aux
|
58
|
+
def setup_expire(expire = 5)
|
59
|
+
@expire = expire
|
60
|
+
@timer.cancel if @timer
|
61
|
+
@timer = every(@expire) { clear }
|
75
62
|
end
|
76
63
|
|
77
|
-
|
64
|
+
def clear
|
65
|
+
@memory = {}
|
66
|
+
@cpu = {}
|
67
|
+
@ppids = {}
|
68
|
+
end
|
78
69
|
|
79
|
-
def
|
80
|
-
@
|
81
|
-
|
70
|
+
def proc_mem(pid)
|
71
|
+
@memory[pid] ||= Eye::Sigar.proc_mem(pid) if pid
|
72
|
+
|
73
|
+
rescue ArgumentError # when incorrect PID
|
82
74
|
end
|
83
75
|
|
76
|
+
def proc_cpu(pid)
|
77
|
+
@cpu[pid] ||= Eye::Sigar.proc_cpu(pid) if pid
|
78
|
+
|
79
|
+
rescue ArgumentError # when incorrect PID
|
80
|
+
end
|
81
|
+
|
82
|
+
def childs(pid)
|
83
|
+
if pid
|
84
|
+
@ppids[pid] ||= Eye::Sigar.proc_list("State.Ppid.eq=#{pid}")
|
85
|
+
else
|
86
|
+
[]
|
87
|
+
end
|
88
|
+
end
|
84
89
|
end
|
85
90
|
|
86
91
|
end
|
data/lib/eye/trigger.rb
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
class Eye::Trigger
|
2
|
+
include Eye::Dsl::Validation
|
3
|
+
|
2
4
|
autoload :Flapping, 'eye/trigger/flapping'
|
3
|
-
autoload :
|
5
|
+
autoload :Transition, 'eye/trigger/transition'
|
4
6
|
autoload :StopChilds, 'eye/trigger/stop_childs'
|
5
7
|
|
6
8
|
# ex: { :type => :flapping, :times => 2, :within => 30.seconds}
|
7
9
|
|
8
|
-
TYPES = {:flapping =>
|
10
|
+
TYPES = {:flapping => 'Flapping', :transition => 'Transition', :stop_childs => 'StopChilds'}
|
9
11
|
|
10
12
|
attr_reader :message, :options, :process
|
11
13
|
|
12
|
-
extend Eye::Dsl::Validation
|
13
|
-
|
14
14
|
def self.name_and_class(type)
|
15
15
|
type = type.to_sym
|
16
16
|
return {:name => type, :type => type} if TYPES[type]
|
@@ -24,6 +24,9 @@ class Eye::Trigger
|
|
24
24
|
def self.get_class(type)
|
25
25
|
klass = eval("Eye::Trigger::#{TYPES[type]}") rescue nil
|
26
26
|
raise "Unknown trigger #{type}" unless klass
|
27
|
+
if deps = klass.depends_on
|
28
|
+
Array(deps).each { |d| require d }
|
29
|
+
end
|
27
30
|
klass
|
28
31
|
end
|
29
32
|
|
@@ -59,8 +62,9 @@ class Eye::Trigger
|
|
59
62
|
"trigger(#{@options[:type]})"
|
60
63
|
end
|
61
64
|
|
62
|
-
def notify(transition)
|
65
|
+
def notify(transition, reason)
|
63
66
|
debug "check (:#{transition.event}) :#{transition.from} => :#{transition.to}"
|
67
|
+
@reason = reason
|
64
68
|
@transition = transition
|
65
69
|
|
66
70
|
check(transition) if filter_transition(transition)
|
@@ -82,7 +86,7 @@ class Eye::Trigger
|
|
82
86
|
end
|
83
87
|
|
84
88
|
def check(transition)
|
85
|
-
raise
|
89
|
+
raise 'realize me'
|
86
90
|
end
|
87
91
|
|
88
92
|
def run_in_process_context(p)
|
@@ -94,12 +98,15 @@ class Eye::Trigger
|
|
94
98
|
end
|
95
99
|
|
96
100
|
def self.register(base)
|
97
|
-
name = base.to_s.gsub(
|
101
|
+
name = base.to_s.gsub('Eye::Trigger::', '')
|
98
102
|
type = name.underscore.to_sym
|
99
103
|
Eye::Trigger::TYPES[type] = name
|
100
104
|
Eye::Trigger.const_set(name, base)
|
101
105
|
end
|
102
106
|
|
107
|
+
def self.depends_on
|
108
|
+
end
|
109
|
+
|
103
110
|
class Custom < Eye::Trigger
|
104
111
|
def self.inherited(base)
|
105
112
|
super
|
@@ -120,4 +127,4 @@ private
|
|
120
127
|
end
|
121
128
|
end
|
122
129
|
|
123
|
-
end
|
130
|
+
end
|