reel-eye 0.5.1 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/CHANGES.md +6 -0
  4. data/README.md +44 -32
  5. data/examples/puma.eye +1 -1
  6. data/examples/test.eye +32 -30
  7. data/examples/unicorn.eye +1 -1
  8. data/lib/eye.rb +1 -1
  9. data/lib/eye/checker.rb +24 -1
  10. data/lib/eye/checker/cpu.rb +4 -14
  11. data/lib/eye/checker/cputime.rb +2 -12
  12. data/lib/eye/checker/file_ctime.rb +2 -3
  13. data/lib/eye/checker/file_size.rb +8 -8
  14. data/lib/eye/checker/http.rb +2 -2
  15. data/lib/eye/checker/memory.rb +4 -14
  16. data/lib/eye/checker/runtime.rb +2 -12
  17. data/lib/eye/checker/socket.rb +1 -1
  18. data/lib/eye/cli.rb +6 -0
  19. data/lib/eye/cli/commands.rb +2 -3
  20. data/lib/eye/cli/render.rb +4 -4
  21. data/lib/eye/cli/server.rb +4 -4
  22. data/lib/eye/controller.rb +1 -1
  23. data/lib/eye/controller/load.rb +14 -13
  24. data/lib/eye/controller/send_command.rb +4 -4
  25. data/lib/eye/controller/status.rb +2 -1
  26. data/lib/eye/dsl.rb +1 -1
  27. data/lib/eye/dsl/child_process_opts.rb +2 -2
  28. data/lib/eye/dsl/opts.rb +5 -1
  29. data/lib/eye/dsl/validation.rb +2 -2
  30. data/lib/eye/group/chain.rb +2 -2
  31. data/lib/eye/notify.rb +3 -3
  32. data/lib/eye/process.rb +7 -7
  33. data/lib/eye/process/children.rb +60 -0
  34. data/lib/eye/process/commands.rb +40 -37
  35. data/lib/eye/process/config.rb +5 -5
  36. data/lib/eye/process/controller.rb +8 -8
  37. data/lib/eye/process/data.rb +4 -4
  38. data/lib/eye/process/monitor.rb +17 -17
  39. data/lib/eye/process/scheduler.rb +1 -1
  40. data/lib/eye/process/states.rb +3 -3
  41. data/lib/eye/process/system.rb +3 -3
  42. data/lib/eye/process/validate.rb +1 -1
  43. data/lib/eye/process/watchers.rb +6 -6
  44. data/lib/eye/server.rb +1 -1
  45. data/lib/eye/system.rb +4 -4
  46. data/lib/eye/system_resources.rb +3 -3
  47. data/lib/eye/trigger.rb +4 -6
  48. data/lib/eye/trigger/flapping.rb +2 -2
  49. data/lib/eye/trigger/stop_children.rb +14 -0
  50. metadata +4 -4
  51. data/lib/eye/process/child.rb +0 -60
  52. data/lib/eye/trigger/stop_childs.rb +0 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a4e0a9547f32b0eae31d793656a43b559eaa2df7
4
- data.tar.gz: a2a6fa219d1b8d4f904075013ba61466cc32a881
3
+ metadata.gz: a8d7151c4d07968c95923d5e03e98479d9c5e2d2
4
+ data.tar.gz: 107ec65c2f5698d6402335517c5959d7a7599c36
5
5
  SHA512:
6
- metadata.gz: 8b252fa537587c2678c9b3f85af63bbb2796ac1bac895c6ff8a1954847612f4c2cf4968fb72664439a584bcbef6701f1a7f8ed26b4cc631c2f4b48da44ca74aa
7
- data.tar.gz: 737744391f0de8816aef5728d52f05649b48bb377c8b5c89808d98b3a2dc06f52cbf3296efdd2834a508f572efc8e247de8ac639ed74adb4812d1f82b7b43610
6
+ metadata.gz: a76c23dca14051ce14bf3f2d20c101cfdd0a8490b0afe81e8c83f2f54fc2bd06604be27de462b07de5f6ef7bbe8ce2b54e024a1f3eeca3e5719594997c753ba8
7
+ data.tar.gz: 331eccf87ef153b6c0241f9b5963a597bc1f28c5584e873633c80a2721b79c29dd01cfd6097eca2f73e6121b690a023ea6b1d828242ec0f0e5178d3e0c41ba15
data/.gitignore CHANGED
@@ -2,6 +2,8 @@
2
2
  *.rbc
3
3
  .bundle
4
4
  .config
5
+ .ruby-version
6
+ .ruby-gemset
5
7
  .yardoc
6
8
  Gemfile.lock
7
9
  InstalledFiles
data/CHANGES.md CHANGED
@@ -1,3 +1,9 @@
1
+ 0.5.2
2
+ -----
3
+ * rename dsl :childs_update_period to :children_update_period
4
+ * grammar fixes
5
+ * add checker option `above`
6
+
1
7
  0.5.1
2
8
  -----
3
9
  * fix ordering in info (#27)
data/README.md CHANGED
@@ -16,69 +16,81 @@ Recommended installation on the server (system wide):
16
16
  $ sudo ln -sf /usr/local/ruby/1.9.3/bin/eye /usr/local/bin/eye
17
17
 
18
18
 
19
- Config example, shows some typical processes and most of the options (see in exampes/ folder):
19
+ ### Why?
20
+
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
+
23
+ We wanted something more robust and production stable.
24
+
25
+ We wanted the features of bluepill and god, with a few extras like chains, nested configuring, mask matching, easy debug configs
26
+
27
+ I hope we've success, we're using eye in production and are quite happy.
28
+
29
+ ### Config example
20
30
 
21
31
  examples/test.eye
22
32
  ```ruby
23
33
  # load submodules, here just for example
24
- Eye.load("./eye/*.rb")
34
+ Eye.load('./eye/*.rb')
25
35
 
26
36
  # Eye self-configuration section
27
37
  Eye.config do
28
- logger "/tmp/eye.log"
38
+ logger '/tmp/eye.log'
29
39
  end
30
40
 
31
41
  # Adding application
32
- Eye.application "test" do
42
+ Eye.application 'test' do
33
43
  # All options inherits down to the config leafs.
34
44
  # except `env`, which merging down
35
45
 
36
46
  working_dir File.expand_path(File.join(File.dirname(__FILE__), %w[ processes ]))
37
- stdall "trash.log" # stdout,err logs for processes by default
38
- env "APP_ENV" => "production" # global env for each processes
39
- trigger :flapping, :times => 10, :within => 1.minute, :retry_in => 10.minutes
40
- check :cpu, :below => 100, :times => 3 # global check for all processes
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
41
51
 
42
- group "samples" do
43
- chain :grace => 5.seconds # chained start-restart with 5s interval, one by one.
52
+ group 'samples' do
53
+ chain grace: 5.seconds # chained start-restart with 5s interval, one by one.
44
54
 
45
55
  # eye daemonized process
46
56
  process :sample1 do
47
- pid_file "1.pid" # pid_path will be expanded with the working_dir
48
- start_command "ruby ./sample.rb"
57
+ pid_file '1.pid' # pid_path will be expanded with the working_dir
58
+ start_command 'ruby ./sample.rb'
49
59
 
50
60
  # when no stop_command or stop_signals, default stop is [:TERM, 0.5, :KILL]
51
61
  # default `restart` command is `stop; start`
52
62
 
53
63
  daemonize true
54
- stdall "sample1.log"
64
+ stdall 'sample1.log'
55
65
 
56
- check :cpu, :below => 30, :times => [3, 5]
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]
57
68
  end
58
69
 
59
70
  # self daemonized process
60
71
  process :sample2 do
61
- pid_file "2.pid"
62
- start_command "ruby ./sample.rb -d --pid 2.pid --log sample2.log"
63
- stop_command "kill -9 {PID}"
72
+ pid_file '2.pid'
73
+ start_command 'ruby ./sample.rb -d --pid 2.pid --log sample2.log'
74
+ stop_command 'kill -9 {PID}'
64
75
 
65
- check :memory, :below => 300.megabytes, :times => 3
76
+ # ensure the memory is below 300Mb the last 3 times checked
77
+ check :memory, every: 20.seconds, below: 300.megabytes, times: 3
66
78
  end
67
79
  end
68
80
 
69
- # daemon with 3 childs
81
+ # daemon with 3 children
70
82
  process :forking do
71
- pid_file "forking.pid"
72
- start_command "ruby ./forking.rb start"
73
- stop_command "ruby forking.rb stop"
74
- stdall "forking.log"
83
+ pid_file 'forking.pid'
84
+ start_command 'ruby ./forking.rb start'
85
+ stop_command 'ruby forking.rb stop'
86
+ stdall 'forking.log'
75
87
 
76
88
  start_timeout 10.seconds
77
89
  stop_timeout 5.seconds
78
90
 
79
91
  monitor_children do
80
- restart_command "kill -2 {PID}" # for this child process
81
- check :memory, :below => 300.megabytes, :times => 3
92
+ restart_command 'kill -2 {PID}' # for this child process
93
+ check :memory, below: 300.megabytes, times: 3
82
94
  end
83
95
  end
84
96
 
@@ -90,18 +102,18 @@ Eye.application "test" do
90
102
  daemonize true
91
103
  stop_signals [:QUIT, 2.seconds, :KILL]
92
104
 
93
- check :socket, :addr => "tcp://127.0.0.1:33221", :every => 10.seconds, :times => 2,
94
- :timeout => 1.second, :send_data => "ping", :expect_data => /pong/
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/
95
107
  end
96
108
 
97
109
  # thin process, self daemonized
98
110
  process :thin do
99
- pid_file "thin.pid"
100
- start_command "bundle exec thin start -R thin.ru -p 33233 -d -l thin.log -P thin.pid"
111
+ pid_file 'thin.pid'
112
+ start_command 'bundle exec thin start -R thin.ru -p 33233 -d -l thin.log -P thin.pid'
101
113
  stop_signals [:QUIT, 2.seconds, :TERM, 1.seconds, :KILL]
102
114
 
103
- check :http, :url => "http://127.0.0.1:33233/hello", :pattern => /World/,
104
- :every => 5.seconds, :times => [2, 3], :timeout => 1.second
115
+ check :http, url: 'http://127.0.0.1:33233/hello', pattern: /World/,
116
+ every: 5.seconds, times: [2, 3], timeout: 1.second
105
117
  end
106
118
 
107
119
  end
@@ -120,7 +132,7 @@ foreground load:
120
132
 
121
133
  $ eye l CONF -f
122
134
 
123
- 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. Removed from config processes will be removed (and stopped if process has `stop_on_delete true`). Other objects update their configs.
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.
124
136
 
125
137
 
126
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 {{PID}}"
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("./eye/*.rb")
2
+ Eye.load('./eye/*.rb')
3
3
 
4
4
  # Eye self-configuration section
5
5
  Eye.config do
6
- logger "/tmp/eye.log"
6
+ logger '/tmp/eye.log'
7
7
  end
8
8
 
9
9
  # Adding application
10
- Eye.application "test" do
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 "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, :below => 100, :times => 3 # global check for all processes
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 "samples" do
21
- chain :grace => 5.seconds # chained start-restart with 5s interval, one by one.
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 "1.pid" # pid_path will be expanded with the working_dir
26
- start_command "ruby ./sample.rb"
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 "sample1.log"
32
+ stdall 'sample1.log'
33
33
 
34
- check :cpu, :below => 30, :times => [3, 5]
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 "2.pid"
40
- start_command "ruby ./sample.rb -d --pid 2.pid --log sample2.log"
41
- stop_command "kill -9 {PID}"
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
- check :memory, :below => 300.megabytes, :times => 3
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 childs
49
+ # daemon with 3 children
48
50
  process :forking do
49
- pid_file "forking.pid"
50
- start_command "ruby ./forking.rb start"
51
- stop_command "ruby forking.rb stop"
52
- stdall "forking.log"
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 "kill -2 {PID}" # for this child process
59
- check :memory, :below => 300.megabytes, :times => 3
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, :addr => "tcp://127.0.0.1:33221", :every => 10.seconds, :times => 2,
72
- :timeout => 1.second, :send_data => "ping", :expect_data => /pong/
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 "thin.pid"
78
- start_command "bundle exec thin start -R thin.ru -p 33233 -d -l thin.log -P thin.pid"
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, :url => "http://127.0.0.1:33233/hello", :pattern => /World/,
82
- :every => 5.seconds, :times => [2, 3], :timeout => 1.second
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
@@ -1,4 +1,4 @@
1
- # Example: now to run unicorn, and monitor its childs processes
1
+ # Example: now to run unicorn, and monitor its child processes
2
2
 
3
3
  RUBY = '/usr/local/ruby/1.9.3/bin/ruby' # ruby on the server
4
4
  RAILS_ENV = 'production'
data/lib/eye.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Eye
2
- VERSION = "0.5.1"
2
+ VERSION = "0.5.2"
3
3
  ABOUT = "ReelEye v#{VERSION} (c) 2012-2014 @kostya"
4
4
  PROCLINE = "reel-eye monitoring v#{VERSION}"
5
5
 
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 'Realize me'
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
@@ -1,11 +1,9 @@
1
- class Eye::Checker::Cpu < Eye::Checker
1
+ class Eye::Checker::Cpu < Eye::Checker::Measure
2
2
 
3
- # checks :cpu, :every => 3.seconds, :below => 80, :times => [3,5]
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(#{human_value(below)})"
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
- def good?(value)
20
- if below
21
- value < below
22
- else
23
- true
24
- end
25
- end
26
-
27
- end
17
+ end
@@ -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
- def good?(value)
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
- param :below, [Fixnum, Float]
10
- param :above, [Fixnum, Float]
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 if below && diff > below
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