eye 0.5.1 → 0.5.2
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/CHANGES.md +6 -0
- data/README.md +37 -35
- data/examples/puma.eye +1 -1
- data/examples/test.eye +32 -30
- data/examples/unicorn.eye +1 -1
- data/lib/eye.rb +1 -1
- data/lib/eye/checker.rb +24 -1
- data/lib/eye/checker/cpu.rb +4 -14
- data/lib/eye/checker/cputime.rb +2 -12
- data/lib/eye/checker/file_ctime.rb +2 -3
- data/lib/eye/checker/file_size.rb +8 -8
- data/lib/eye/checker/http.rb +2 -2
- data/lib/eye/checker/memory.rb +4 -14
- data/lib/eye/checker/runtime.rb +2 -12
- data/lib/eye/checker/socket.rb +1 -1
- data/lib/eye/cli.rb +6 -0
- data/lib/eye/cli/commands.rb +2 -3
- data/lib/eye/cli/render.rb +4 -4
- data/lib/eye/cli/server.rb +4 -4
- data/lib/eye/controller.rb +1 -1
- data/lib/eye/controller/load.rb +14 -13
- data/lib/eye/controller/send_command.rb +4 -4
- data/lib/eye/controller/status.rb +2 -1
- data/lib/eye/dsl.rb +1 -1
- data/lib/eye/dsl/child_process_opts.rb +2 -2
- data/lib/eye/dsl/opts.rb +5 -1
- data/lib/eye/dsl/validation.rb +2 -2
- data/lib/eye/group/chain.rb +2 -2
- data/lib/eye/notify.rb +3 -3
- data/lib/eye/process.rb +7 -7
- data/lib/eye/process/children.rb +60 -0
- data/lib/eye/process/commands.rb +40 -37
- data/lib/eye/process/config.rb +5 -5
- data/lib/eye/process/controller.rb +8 -8
- data/lib/eye/process/data.rb +4 -4
- data/lib/eye/process/monitor.rb +17 -17
- data/lib/eye/process/scheduler.rb +1 -1
- data/lib/eye/process/states.rb +3 -3
- data/lib/eye/process/system.rb +3 -3
- data/lib/eye/process/validate.rb +1 -1
- data/lib/eye/process/watchers.rb +6 -6
- data/lib/eye/server.rb +1 -1
- data/lib/eye/system.rb +4 -4
- data/lib/eye/system_resources.rb +3 -3
- data/lib/eye/trigger.rb +4 -6
- data/lib/eye/trigger/flapping.rb +2 -2
- data/lib/eye/trigger/stop_children.rb +14 -0
- metadata +4 -4
- data/lib/eye/process/child.rb +0 -60
- data/lib/eye/trigger/stop_childs.rb +0 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cafc3688088df4ed7d7e3dc818098b62409f048d
|
4
|
+
data.tar.gz: 956fe8cad209a7eda5eb2fe8ddc9114d37ea32e3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6714b130ff87b60ad3f7ad768d4854e73b78aea6bf5f3c7374db183374cd608122cff1bc604e5f59e6e2482cc44aca303c12b40dc05b82f95ede1c88e89e0d3c
|
7
|
+
data.tar.gz: d64d70d355dc8580d77d575d102eded7fe7dc25d78aff325db363a42a161fc73f55f210071ae30901849bf7ba724e78fa5d12eba56a2eb59532b94bd3c2c737f
|
data/.gitignore
CHANGED
data/CHANGES.md
CHANGED
data/README.md
CHANGED
@@ -18,77 +18,79 @@ Recommended installation on the server (system wide):
|
|
18
18
|
|
19
19
|
### Why?
|
20
20
|
|
21
|
-
We have used god and bluepill in production and always
|
21
|
+
We have used god and bluepill in production and always ran into bugs (segfaults, crashes, lost processes, kill not-related processes, load problems, deploy problems, ...)
|
22
22
|
|
23
|
-
We wanted something more robust and production stable
|
23
|
+
We wanted something more robust and production stable.
|
24
24
|
|
25
|
-
We wanted features
|
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
|
27
|
+
I hope we've success, we're using eye in production and are quite happy.
|
28
28
|
|
29
29
|
### Config example
|
30
30
|
|
31
31
|
examples/test.eye
|
32
32
|
```ruby
|
33
33
|
# load submodules, here just for example
|
34
|
-
Eye.load(
|
34
|
+
Eye.load('./eye/*.rb')
|
35
35
|
|
36
36
|
# Eye self-configuration section
|
37
37
|
Eye.config do
|
38
|
-
logger
|
38
|
+
logger '/tmp/eye.log'
|
39
39
|
end
|
40
40
|
|
41
41
|
# Adding application
|
42
|
-
Eye.application
|
42
|
+
Eye.application 'test' do
|
43
43
|
# All options inherits down to the config leafs.
|
44
44
|
# except `env`, which merging down
|
45
45
|
|
46
46
|
working_dir File.expand_path(File.join(File.dirname(__FILE__), %w[ processes ]))
|
47
|
-
stdall
|
48
|
-
env
|
49
|
-
trigger :flapping, :
|
50
|
-
check :cpu, :below
|
47
|
+
stdall 'trash.log' # stdout,err logs for processes by default
|
48
|
+
env 'APP_ENV' => 'production' # global env for each processes
|
49
|
+
trigger :flapping, times: 10, within: 1.minute, retry_in: 10.minutes
|
50
|
+
check :cpu, every: 10.seconds, below: 100, times: 3 # global check for all processes
|
51
51
|
|
52
|
-
group
|
53
|
-
chain :
|
52
|
+
group 'samples' do
|
53
|
+
chain grace: 5.seconds # chained start-restart with 5s interval, one by one.
|
54
54
|
|
55
55
|
# eye daemonized process
|
56
56
|
process :sample1 do
|
57
|
-
pid_file
|
58
|
-
start_command
|
57
|
+
pid_file '1.pid' # pid_path will be expanded with the working_dir
|
58
|
+
start_command 'ruby ./sample.rb'
|
59
59
|
|
60
60
|
# when no stop_command or stop_signals, default stop is [:TERM, 0.5, :KILL]
|
61
61
|
# default `restart` command is `stop; start`
|
62
62
|
|
63
63
|
daemonize true
|
64
|
-
stdall
|
64
|
+
stdall 'sample1.log'
|
65
65
|
|
66
|
-
|
66
|
+
# ensure the CPU is below 30% at least 3 out of the last 5 times checked
|
67
|
+
check :cpu, below: 30, times: [3, 5]
|
67
68
|
end
|
68
69
|
|
69
70
|
# self daemonized process
|
70
71
|
process :sample2 do
|
71
|
-
pid_file
|
72
|
-
start_command
|
73
|
-
stop_command
|
72
|
+
pid_file '2.pid'
|
73
|
+
start_command 'ruby ./sample.rb -d --pid 2.pid --log sample2.log'
|
74
|
+
stop_command 'kill -9 {PID}'
|
74
75
|
|
75
|
-
|
76
|
+
# ensure the memory is below 300Mb the last 3 times checked
|
77
|
+
check :memory, every: 20.seconds, below: 300.megabytes, times: 3
|
76
78
|
end
|
77
79
|
end
|
78
80
|
|
79
|
-
# daemon with 3
|
81
|
+
# daemon with 3 children
|
80
82
|
process :forking do
|
81
|
-
pid_file
|
82
|
-
start_command
|
83
|
-
stop_command
|
84
|
-
stdall
|
83
|
+
pid_file 'forking.pid'
|
84
|
+
start_command 'ruby ./forking.rb start'
|
85
|
+
stop_command 'ruby forking.rb stop'
|
86
|
+
stdall 'forking.log'
|
85
87
|
|
86
88
|
start_timeout 10.seconds
|
87
89
|
stop_timeout 5.seconds
|
88
90
|
|
89
91
|
monitor_children do
|
90
|
-
restart_command
|
91
|
-
check :memory, :
|
92
|
+
restart_command 'kill -2 {PID}' # for this child process
|
93
|
+
check :memory, below: 300.megabytes, times: 3
|
92
94
|
end
|
93
95
|
end
|
94
96
|
|
@@ -100,18 +102,18 @@ Eye.application "test" do
|
|
100
102
|
daemonize true
|
101
103
|
stop_signals [:QUIT, 2.seconds, :KILL]
|
102
104
|
|
103
|
-
check :socket, :
|
104
|
-
:
|
105
|
+
check :socket, addr: 'tcp://127.0.0.1:33221', every: 10.seconds, times: 2,
|
106
|
+
timeout: 1.second, send_data: 'ping', expect_data: /pong/
|
105
107
|
end
|
106
108
|
|
107
109
|
# thin process, self daemonized
|
108
110
|
process :thin do
|
109
|
-
pid_file
|
110
|
-
start_command
|
111
|
+
pid_file 'thin.pid'
|
112
|
+
start_command 'bundle exec thin start -R thin.ru -p 33233 -d -l thin.log -P thin.pid'
|
111
113
|
stop_signals [:QUIT, 2.seconds, :TERM, 1.seconds, :KILL]
|
112
114
|
|
113
|
-
check :http, :
|
114
|
-
:
|
115
|
+
check :http, url: 'http://127.0.0.1:33233/hello', pattern: /World/,
|
116
|
+
every: 5.seconds, times: [2, 3], timeout: 1.second
|
115
117
|
end
|
116
118
|
|
117
119
|
end
|
@@ -130,7 +132,7 @@ foreground load:
|
|
130
132
|
|
131
133
|
$ eye l CONF -f
|
132
134
|
|
133
|
-
If eye daemon already started and you call `load` command, config will be updated (into eye daemon). New objects(applications, groups, processes) will be added and monitored.
|
135
|
+
If the eye daemon has already started and you call the `load` command, the config will be updated (into eye daemon). New objects(applications, groups, processes) will be added and monitored. Processes removed from the config will be removed (and stopped if the process has `stop_on_delete true`). Other objects will update their configs.
|
134
136
|
|
135
137
|
|
136
138
|
Process statuses:
|
data/examples/puma.eye
CHANGED
@@ -18,7 +18,7 @@ Eye.application :puma do
|
|
18
18
|
|
19
19
|
start_command "#{BUNDLE} exec puma --port 33280 --environment #{RAILS_ENV} thin.ru"
|
20
20
|
stop_signals [:TERM, 5.seconds, :KILL]
|
21
|
-
restart_command "kill -USR2 {
|
21
|
+
restart_command "kill -USR2 {PID}"
|
22
22
|
|
23
23
|
restart_grace 10.seconds # just sleep this until process get up status
|
24
24
|
# (maybe enought to puma soft restart)
|
data/examples/test.eye
CHANGED
@@ -1,62 +1,64 @@
|
|
1
1
|
# load submodules, here just for example
|
2
|
-
Eye.load(
|
2
|
+
Eye.load('./eye/*.rb')
|
3
3
|
|
4
4
|
# Eye self-configuration section
|
5
5
|
Eye.config do
|
6
|
-
logger
|
6
|
+
logger '/tmp/eye.log'
|
7
7
|
end
|
8
8
|
|
9
9
|
# Adding application
|
10
|
-
Eye.application
|
10
|
+
Eye.application 'test' do
|
11
11
|
# All options inherits down to the config leafs.
|
12
12
|
# except `env`, which merging down
|
13
13
|
|
14
14
|
working_dir File.expand_path(File.join(File.dirname(__FILE__), %w[ processes ]))
|
15
|
-
stdall
|
16
|
-
env
|
17
|
-
trigger :flapping, :
|
18
|
-
check :cpu, :below
|
15
|
+
stdall 'trash.log' # stdout,err logs for processes by default
|
16
|
+
env 'APP_ENV' => 'production' # global env for each processes
|
17
|
+
trigger :flapping, times: 10, within: 1.minute, retry_in: 10.minutes
|
18
|
+
check :cpu, every: 10.seconds, below: 100, times: 3 # global check for all processes
|
19
19
|
|
20
|
-
group
|
21
|
-
chain :
|
20
|
+
group 'samples' do
|
21
|
+
chain grace: 5.seconds # chained start-restart with 5s interval, one by one.
|
22
22
|
|
23
23
|
# eye daemonized process
|
24
24
|
process :sample1 do
|
25
|
-
pid_file
|
26
|
-
start_command
|
25
|
+
pid_file '1.pid' # pid_path will be expanded with the working_dir
|
26
|
+
start_command 'ruby ./sample.rb'
|
27
27
|
|
28
28
|
# when no stop_command or stop_signals, default stop is [:TERM, 0.5, :KILL]
|
29
29
|
# default `restart` command is `stop; start`
|
30
30
|
|
31
31
|
daemonize true
|
32
|
-
stdall
|
32
|
+
stdall 'sample1.log'
|
33
33
|
|
34
|
-
|
34
|
+
# ensure the CPU is below 30% at least 3 out of the last 5 times checked
|
35
|
+
check :cpu, below: 30, times: [3, 5]
|
35
36
|
end
|
36
37
|
|
37
38
|
# self daemonized process
|
38
39
|
process :sample2 do
|
39
|
-
pid_file
|
40
|
-
start_command
|
41
|
-
stop_command
|
40
|
+
pid_file '2.pid'
|
41
|
+
start_command 'ruby ./sample.rb -d --pid 2.pid --log sample2.log'
|
42
|
+
stop_command 'kill -9 {PID}'
|
42
43
|
|
43
|
-
|
44
|
+
# ensure the memory is below 300Mb the last 3 times checked
|
45
|
+
check :memory, every: 20.seconds, below: 300.megabytes, times: 3
|
44
46
|
end
|
45
47
|
end
|
46
48
|
|
47
|
-
# daemon with 3
|
49
|
+
# daemon with 3 children
|
48
50
|
process :forking do
|
49
|
-
pid_file
|
50
|
-
start_command
|
51
|
-
stop_command
|
52
|
-
stdall
|
51
|
+
pid_file 'forking.pid'
|
52
|
+
start_command 'ruby ./forking.rb start'
|
53
|
+
stop_command 'ruby forking.rb stop'
|
54
|
+
stdall 'forking.log'
|
53
55
|
|
54
56
|
start_timeout 10.seconds
|
55
57
|
stop_timeout 5.seconds
|
56
58
|
|
57
59
|
monitor_children do
|
58
|
-
restart_command
|
59
|
-
check :memory, :
|
60
|
+
restart_command 'kill -2 {PID}' # for this child process
|
61
|
+
check :memory, below: 300.megabytes, times: 3
|
60
62
|
end
|
61
63
|
end
|
62
64
|
|
@@ -68,18 +70,18 @@ Eye.application "test" do
|
|
68
70
|
daemonize true
|
69
71
|
stop_signals [:QUIT, 2.seconds, :KILL]
|
70
72
|
|
71
|
-
check :socket, :
|
72
|
-
:
|
73
|
+
check :socket, addr: 'tcp://127.0.0.1:33221', every: 10.seconds, times: 2,
|
74
|
+
timeout: 1.second, send_data: 'ping', expect_data: /pong/
|
73
75
|
end
|
74
76
|
|
75
77
|
# thin process, self daemonized
|
76
78
|
process :thin do
|
77
|
-
pid_file
|
78
|
-
start_command
|
79
|
+
pid_file 'thin.pid'
|
80
|
+
start_command 'bundle exec thin start -R thin.ru -p 33233 -d -l thin.log -P thin.pid'
|
79
81
|
stop_signals [:QUIT, 2.seconds, :TERM, 1.seconds, :KILL]
|
80
82
|
|
81
|
-
check :http, :
|
82
|
-
:
|
83
|
+
check :http, url: 'http://127.0.0.1:33233/hello', pattern: /World/,
|
84
|
+
every: 5.seconds, times: [2, 3], timeout: 1.second
|
83
85
|
end
|
84
86
|
|
85
87
|
end
|
data/examples/unicorn.eye
CHANGED
data/lib/eye.rb
CHANGED
data/lib/eye/checker.rb
CHANGED
@@ -131,7 +131,7 @@ class Eye::Checker
|
|
131
131
|
end
|
132
132
|
|
133
133
|
def get_value
|
134
|
-
raise
|
134
|
+
raise NotImplementedError
|
135
135
|
end
|
136
136
|
|
137
137
|
def human_value(value)
|
@@ -220,4 +220,27 @@ class Eye::Checker
|
|
220
220
|
register(base)
|
221
221
|
end
|
222
222
|
end
|
223
|
+
|
224
|
+
class Measure < Eye::Checker
|
225
|
+
param :below, [Fixnum, Float]
|
226
|
+
param :above, [Fixnum, Float]
|
227
|
+
|
228
|
+
def good?(value)
|
229
|
+
return false if below && (value > below)
|
230
|
+
return false if above && (value < above)
|
231
|
+
true
|
232
|
+
end
|
233
|
+
|
234
|
+
def measure_str
|
235
|
+
if below && above
|
236
|
+
">#{human_value(above)}<#{human_value(below)}"
|
237
|
+
elsif below
|
238
|
+
"<#{human_value(below)}"
|
239
|
+
elsif above
|
240
|
+
">#{human_value(above)}"
|
241
|
+
else
|
242
|
+
'-'
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
223
246
|
end
|
data/lib/eye/checker/cpu.rb
CHANGED
@@ -1,11 +1,9 @@
|
|
1
|
-
class Eye::Checker::Cpu < Eye::Checker
|
1
|
+
class Eye::Checker::Cpu < Eye::Checker::Measure
|
2
2
|
|
3
|
-
#
|
4
|
-
|
5
|
-
param :below, [Fixnum, Float], true
|
3
|
+
# check :cpu, :every => 3.seconds, :below => 80, :times => [3,5]
|
6
4
|
|
7
5
|
def check_name
|
8
|
-
@check_name ||= "cpu(#{
|
6
|
+
@check_name ||= "cpu(#{measure_str})"
|
9
7
|
end
|
10
8
|
|
11
9
|
def get_value
|
@@ -16,12 +14,4 @@ class Eye::Checker::Cpu < Eye::Checker
|
|
16
14
|
"#{value}%"
|
17
15
|
end
|
18
16
|
|
19
|
-
|
20
|
-
if below
|
21
|
-
value < below
|
22
|
-
else
|
23
|
-
true
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
end
|
17
|
+
end
|
data/lib/eye/checker/cputime.rb
CHANGED
@@ -1,9 +1,7 @@
|
|
1
|
-
class Eye::Checker::Cputime < Eye::Checker
|
1
|
+
class Eye::Checker::Cputime < Eye::Checker::Measure
|
2
2
|
|
3
3
|
# check :cputime, :every => 1.minute, :below => 120.minutes
|
4
4
|
|
5
|
-
param :below, [Fixnum, Float], true
|
6
|
-
|
7
5
|
def get_value
|
8
6
|
Eye::SystemResources.cputime(@pid).to_f
|
9
7
|
end
|
@@ -12,12 +10,4 @@ class Eye::Checker::Cputime < Eye::Checker
|
|
12
10
|
"#{value / 60}m"
|
13
11
|
end
|
14
12
|
|
15
|
-
|
16
|
-
if below
|
17
|
-
value < below
|
18
|
-
else
|
19
|
-
true
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
end
|
13
|
+
end
|
@@ -1,8 +1,7 @@
|
|
1
1
|
class Eye::Checker::FileCTime < Eye::Checker
|
2
2
|
|
3
3
|
# Check that file changes (log for example)
|
4
|
-
|
5
|
-
# checks :ctime, :every => 5.seconds, :file => "/tmp/1.log", :times => [3,5]
|
4
|
+
# check :ctime, :every => 5.seconds, :file => "/tmp/1.log", :times => [3,5]
|
6
5
|
|
7
6
|
param :file, [String], true
|
8
7
|
|
@@ -22,4 +21,4 @@ class Eye::Checker::FileCTime < Eye::Checker
|
|
22
21
|
value.to_i > previous_value.to_i
|
23
22
|
end
|
24
23
|
|
25
|
-
end
|
24
|
+
end
|
@@ -1,13 +1,14 @@
|
|
1
|
-
class Eye::Checker::FileSize < Eye::Checker
|
1
|
+
class Eye::Checker::FileSize < Eye::Checker::Measure
|
2
2
|
|
3
3
|
# Check that file size changed (log for example)
|
4
|
-
|
5
|
-
# checks :fsize, :every => 5.seconds, :file => "/tmp/1.log", :times => [3,5],
|
4
|
+
# check :fsize, :every => 5.seconds, :file => "/tmp/1.log", :times => [3,5],
|
6
5
|
# :below => 30.kilobytes, :above => 10.kilobytes
|
7
6
|
|
8
7
|
param :file, [String], true
|
9
|
-
|
10
|
-
|
8
|
+
|
9
|
+
def check_name
|
10
|
+
@check_name ||= "fsize(#{measure_str})"
|
11
|
+
end
|
11
12
|
|
12
13
|
def get_value
|
13
14
|
File.size(file) rescue nil
|
@@ -24,11 +25,10 @@ class Eye::Checker::FileSize < Eye::Checker
|
|
24
25
|
|
25
26
|
return true if diff < 0 # case when logger nulled
|
26
27
|
|
27
|
-
return false
|
28
|
-
return false if above && diff < above
|
28
|
+
return false unless super(diff)
|
29
29
|
return false if diff == 0
|
30
30
|
|
31
31
|
true
|
32
32
|
end
|
33
33
|
|
34
|
-
end
|
34
|
+
end
|