firenxis-god 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. data/Announce.txt +135 -0
  2. data/History.txt +393 -0
  3. data/README.txt +59 -0
  4. data/Rakefile +142 -0
  5. data/bin/god +132 -0
  6. data/ext/god/.gitignore +5 -0
  7. data/ext/god/extconf.rb +55 -0
  8. data/ext/god/kqueue_handler.c +125 -0
  9. data/ext/god/netlink_handler.c +168 -0
  10. data/god.gemspec +164 -0
  11. data/lib/god.rb +701 -0
  12. data/lib/god/behavior.rb +52 -0
  13. data/lib/god/behaviors/clean_pid_file.rb +21 -0
  14. data/lib/god/behaviors/clean_unix_socket.rb +21 -0
  15. data/lib/god/behaviors/notify_when_flapping.rb +51 -0
  16. data/lib/god/cli/command.rb +256 -0
  17. data/lib/god/cli/run.rb +172 -0
  18. data/lib/god/cli/version.rb +23 -0
  19. data/lib/god/compat19.rb +36 -0
  20. data/lib/god/condition.rb +96 -0
  21. data/lib/god/conditions/always.rb +23 -0
  22. data/lib/god/conditions/complex.rb +86 -0
  23. data/lib/god/conditions/cpu_usage.rb +80 -0
  24. data/lib/god/conditions/degrading_lambda.rb +52 -0
  25. data/lib/god/conditions/disk_usage.rb +32 -0
  26. data/lib/god/conditions/file_mtime.rb +28 -0
  27. data/lib/god/conditions/flapping.rb +128 -0
  28. data/lib/god/conditions/http_response_code.rb +168 -0
  29. data/lib/god/conditions/lambda.rb +25 -0
  30. data/lib/god/conditions/memory_usage.rb +82 -0
  31. data/lib/god/conditions/process_exits.rb +72 -0
  32. data/lib/god/conditions/process_running.rb +74 -0
  33. data/lib/god/conditions/tries.rb +44 -0
  34. data/lib/god/configurable.rb +57 -0
  35. data/lib/god/contact.rb +114 -0
  36. data/lib/god/contacts/campfire.rb +121 -0
  37. data/lib/god/contacts/email.rb +136 -0
  38. data/lib/god/contacts/jabber.rb +75 -0
  39. data/lib/god/contacts/prowl.rb +57 -0
  40. data/lib/god/contacts/scout.rb +55 -0
  41. data/lib/god/contacts/twitter.rb +51 -0
  42. data/lib/god/contacts/webhook.rb +73 -0
  43. data/lib/god/dependency_graph.rb +41 -0
  44. data/lib/god/diagnostics.rb +37 -0
  45. data/lib/god/driver.rb +206 -0
  46. data/lib/god/errors.rb +24 -0
  47. data/lib/god/event_handler.rb +108 -0
  48. data/lib/god/event_handlers/dummy_handler.rb +13 -0
  49. data/lib/god/event_handlers/kqueue_handler.rb +17 -0
  50. data/lib/god/event_handlers/netlink_handler.rb +13 -0
  51. data/lib/god/logger.rb +109 -0
  52. data/lib/god/metric.rb +59 -0
  53. data/lib/god/process.rb +363 -0
  54. data/lib/god/registry.rb +32 -0
  55. data/lib/god/simple_logger.rb +59 -0
  56. data/lib/god/socket.rb +107 -0
  57. data/lib/god/sugar.rb +47 -0
  58. data/lib/god/sys_logger.rb +45 -0
  59. data/lib/god/system/portable_poller.rb +42 -0
  60. data/lib/god/system/process.rb +50 -0
  61. data/lib/god/system/slash_proc_poller.rb +92 -0
  62. data/lib/god/task.rb +503 -0
  63. data/lib/god/timeline.rb +25 -0
  64. data/lib/god/trigger.rb +43 -0
  65. data/lib/god/watch.rb +188 -0
  66. data/test/configs/child_events/child_events.god +44 -0
  67. data/test/configs/child_events/simple_server.rb +3 -0
  68. data/test/configs/child_polls/child_polls.god +37 -0
  69. data/test/configs/child_polls/simple_server.rb +12 -0
  70. data/test/configs/complex/complex.god +59 -0
  71. data/test/configs/complex/simple_server.rb +3 -0
  72. data/test/configs/contact/contact.god +108 -0
  73. data/test/configs/contact/simple_server.rb +3 -0
  74. data/test/configs/daemon_events/daemon_events.god +37 -0
  75. data/test/configs/daemon_events/simple_server.rb +8 -0
  76. data/test/configs/daemon_events/simple_server_stop.rb +11 -0
  77. data/test/configs/daemon_polls/daemon_polls.god +17 -0
  78. data/test/configs/daemon_polls/simple_server.rb +6 -0
  79. data/test/configs/degrading_lambda/degrading_lambda.god +31 -0
  80. data/test/configs/degrading_lambda/tcp_server.rb +15 -0
  81. data/test/configs/lifecycle/lifecycle.god +25 -0
  82. data/test/configs/matias/matias.god +50 -0
  83. data/test/configs/real.rb +59 -0
  84. data/test/configs/running_load/running_load.god +16 -0
  85. data/test/configs/stop_options/simple_server.rb +12 -0
  86. data/test/configs/stop_options/stop_options.god +39 -0
  87. data/test/configs/stress/simple_server.rb +3 -0
  88. data/test/configs/stress/stress.god +15 -0
  89. data/test/configs/task/logs/.placeholder +0 -0
  90. data/test/configs/task/task.god +26 -0
  91. data/test/configs/test.rb +61 -0
  92. data/test/helper.rb +141 -0
  93. data/test/suite.rb +6 -0
  94. data/test/test_behavior.rb +18 -0
  95. data/test/test_campfire.rb +23 -0
  96. data/test/test_condition.rb +50 -0
  97. data/test/test_conditions_disk_usage.rb +50 -0
  98. data/test/test_conditions_http_response_code.rb +109 -0
  99. data/test/test_conditions_process_running.rb +40 -0
  100. data/test/test_conditions_tries.rb +67 -0
  101. data/test/test_contact.rb +109 -0
  102. data/test/test_dependency_graph.rb +62 -0
  103. data/test/test_driver.rb +11 -0
  104. data/test/test_email.rb +34 -0
  105. data/test/test_event_handler.rb +80 -0
  106. data/test/test_god.rb +570 -0
  107. data/test/test_handlers_kqueue_handler.rb +16 -0
  108. data/test/test_jabber.rb +29 -0
  109. data/test/test_logger.rb +55 -0
  110. data/test/test_metric.rb +72 -0
  111. data/test/test_process.rb +247 -0
  112. data/test/test_prowl.rb +15 -0
  113. data/test/test_registry.rb +15 -0
  114. data/test/test_socket.rb +34 -0
  115. data/test/test_sugar.rb +42 -0
  116. data/test/test_system_portable_poller.rb +17 -0
  117. data/test/test_system_process.rb +30 -0
  118. data/test/test_task.rb +246 -0
  119. data/test/test_timeline.rb +37 -0
  120. data/test/test_trigger.rb +59 -0
  121. data/test/test_watch.rb +279 -0
  122. data/test/test_webhook.rb +15 -0
  123. metadata +362 -0
@@ -0,0 +1,3 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ loop { puts 'server'; sleep 1 }
@@ -0,0 +1,37 @@
1
+ God.watch do |w|
2
+ w.name = "daemon-events"
3
+ w.interval = 5.seconds
4
+ w.start = 'ruby ' + File.join(File.dirname(__FILE__), *%w[simple_server.rb]) + ' start'
5
+ w.stop = 'ruby ' + File.join(File.dirname(__FILE__), *%w[simple_server_stop.rb])
6
+ w.pid_file = '/var/run/daemon-events.pid'
7
+ w.log = File.join(File.dirname(__FILE__), 'daemon_events.log')
8
+ w.uid = 'tom'
9
+ w.gid = 'tom'
10
+
11
+ w.behavior(:clean_pid_file)
12
+
13
+ # determine the state on startup
14
+ w.transition(:init, { true => :up, false => :start }) do |on|
15
+ on.condition(:process_running) do |c|
16
+ c.running = true
17
+ end
18
+ end
19
+
20
+ # determine when process has finished starting
21
+ w.transition([:start, :restart], :up) do |on|
22
+ on.condition(:process_running) do |c|
23
+ c.running = true
24
+ end
25
+
26
+ # failsafe
27
+ on.condition(:tries) do |c|
28
+ c.times = 2
29
+ c.transition = :start
30
+ end
31
+ end
32
+
33
+ # start if process is not running
34
+ w.transition(:up, :start) do |on|
35
+ on.condition(:process_exits)
36
+ end
37
+ end
@@ -0,0 +1,8 @@
1
+ require 'rubygems'
2
+ require 'daemons'
3
+
4
+ puts 'simple server ahoy!'
5
+
6
+ Daemons.run_proc('daemon-events', {:dir_mode => :system}) do
7
+ loop { puts 'server'; sleep 1 }
8
+ end
@@ -0,0 +1,11 @@
1
+ # exit!(2)
2
+
3
+ 3.times do
4
+ puts 'waiting'
5
+ sleep 1
6
+ end
7
+
8
+ p ENV
9
+
10
+ command = '/usr/local/bin/ruby ' + File.join(File.dirname(__FILE__), *%w[simple_server.rb]) + ' stop'
11
+ system(command)
@@ -0,0 +1,17 @@
1
+ God.watch do |w|
2
+ w.name = "daemon-polls"
3
+ w.interval = 5.seconds
4
+ w.start = 'ruby ' + File.join(File.dirname(__FILE__), *%w[simple_server.rb]) + ' start'
5
+ w.stop = 'ruby ' + File.join(File.dirname(__FILE__), *%w[simple_server.rb]) + ' stop'
6
+ w.pid_file = '/var/run/daemon-polls.pid'
7
+ w.start_grace = 2.seconds
8
+ w.log = File.join(File.dirname(__FILE__), *%w[out.log])
9
+
10
+ w.behavior(:clean_pid_file)
11
+
12
+ w.start_if do |start|
13
+ start.condition(:process_running) do |c|
14
+ c.running = false
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,6 @@
1
+ require 'rubygems'
2
+ require 'daemons'
3
+
4
+ Daemons.run_proc('daemon-polls', {:dir_mode => :system}) do
5
+ loop { STDOUT.puts('server'); STDOUT.flush; sleep 1 }
6
+ end
@@ -0,0 +1,31 @@
1
+ God.watch do |w|
2
+ w.name = 'degrading-lambda'
3
+ w.start = 'ruby ' + File.join(File.dirname(__FILE__), *%w[tcp_server.rb])
4
+ w.interval = 5
5
+ w.grace = 2
6
+ w.group = 'test'
7
+
8
+ w.start_if do |start|
9
+ start.condition(:process_running) do |c|
10
+ c.running = false
11
+ end
12
+ end
13
+
14
+ w.restart_if do |restart|
15
+ restart.condition(:degrading_lambda) do |c|
16
+ require 'socket'
17
+ c.lambda = lambda {
18
+ begin
19
+ sock = TCPSocket.open('127.0.0.1', 9090)
20
+ sock.send "2\n", 0
21
+ retval = sock.gets
22
+ puts "Retval is #{retval}"
23
+ sock.close
24
+ retval
25
+ rescue
26
+ false
27
+ end
28
+ }
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,15 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ require 'socket'
4
+ server = TCPServer.new('127.0.0.1', 9090)
5
+ while (session = server.accept)
6
+ puts "Found a session"
7
+ request = session.gets
8
+ puts "Request: #{request}"
9
+ time = request.to_i
10
+ puts "Sleeping for #{time}"
11
+ sleep time
12
+ session.print "Slept for #{time} seconds"
13
+ session.close
14
+ puts "Session closed"
15
+ end
@@ -0,0 +1,25 @@
1
+ God::Contacts::Twitter.settings = {
2
+ # this is for my 'mojombo2' twitter test account
3
+ # feel free to use it for testing your conditions
4
+ :username => 'mojombo@gmail.com',
5
+ :password => 'gok9we3ot1av2e'
6
+ }
7
+
8
+ God.contact(:twitter) do |c|
9
+ c.name = 'tom2'
10
+ c.group = 'developers'
11
+ end
12
+
13
+ God.watch do |w|
14
+ w.name = "lifecycle"
15
+ w.interval = 5.seconds
16
+ w.start = "/dev/null"
17
+
18
+ # lifecycle
19
+ w.lifecycle do |on|
20
+ on.condition(:always) do |c|
21
+ c.what = true
22
+ c.notify = "tom2"
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,50 @@
1
+ $pid_file = "/tmp/matias.pid"
2
+
3
+ God.task do |w|
4
+ w.name = "watcher"
5
+ w.interval = 5.seconds
6
+ w.valid_states = [:init, :up, :down]
7
+ w.initial_state = :init
8
+
9
+ # determine the state on startup
10
+ w.transition(:init, { true => :up, false => :down }) do |on|
11
+ on.condition(:process_running) do |c|
12
+ c.running = true
13
+ c.pid_file = $pid_file
14
+ end
15
+ end
16
+
17
+ # when process is up
18
+ w.transition(:up, :down) do |on|
19
+ # transition to 'start' if process goes down
20
+ on.condition(:process_running) do |c|
21
+ c.running = false
22
+ c.pid_file = $pid_file
23
+ end
24
+
25
+ # send up info
26
+ on.condition(:lambda) do |c|
27
+ c.lambda = lambda do
28
+ puts 'yay I am up'
29
+ false
30
+ end
31
+ end
32
+ end
33
+
34
+ # when process is down
35
+ w.transition(:down, :up) do |on|
36
+ # transition to 'up' if process comes up
37
+ on.condition(:process_running) do |c|
38
+ c.running = true
39
+ c.pid_file = $pid_file
40
+ end
41
+
42
+ # send down info
43
+ on.condition(:lambda) do |c|
44
+ c.lambda = lambda do
45
+ puts 'boo I am down'
46
+ false
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,59 @@
1
+ if $0 == __FILE__
2
+ require File.join(File.dirname(__FILE__), *%w[.. .. lib god])
3
+ end
4
+
5
+ RAILS_ROOT = "/Users/tom/dev/git/helloworld"
6
+
7
+ God.watch do |w|
8
+ w.name = "local-3000"
9
+ w.interval = 5 # seconds
10
+ w.start = "mongrel_rails start -P ./log/mongrel.pid -c #{RAILS_ROOT} -d"
11
+ w.stop = "mongrel_rails stop -P ./log/mongrel.pid -c #{RAILS_ROOT}"
12
+ w.grace = 5
13
+
14
+ pid_file = File.join(RAILS_ROOT, "log/mongrel.pid")
15
+
16
+ # clean pid files before start if necessary
17
+ w.behavior(:clean_pid_file) do |b|
18
+ b.pid_file = pid_file
19
+ end
20
+
21
+ # start if process is not running
22
+ w.start_if do |start|
23
+ start.condition(:process_running) do |c|
24
+ c.running = false
25
+ c.pid_file = pid_file
26
+ end
27
+ end
28
+
29
+ # restart if memory or cpu is too high
30
+ w.restart_if do |restart|
31
+ restart.condition(:memory_usage) do |c|
32
+ c.interval = 20
33
+ c.pid_file = pid_file
34
+ c.above = (50 * 1024) # 50mb
35
+ c.times = [3, 5]
36
+ end
37
+
38
+ restart.condition(:cpu_usage) do |c|
39
+ c.interval = 10
40
+ c.pid_file = pid_file
41
+ c.above = 10 # percent
42
+ c.times = [3, 5]
43
+ end
44
+ end
45
+ end
46
+
47
+ # clear old session files
48
+ # god.watch do |w|
49
+ # w.name = "local-session-cleanup"
50
+ # w.start = lambda do
51
+ # Dir["#{RAILS_ROOT}/tmp/sessions/ruby_sess.*"].select do |f|
52
+ # File.mtime(f) < Time.now - (7 * 24 * 60 * 60)
53
+ # end.each { |f| File.delete(f) }
54
+ # end
55
+ #
56
+ # w.start_if do |start|
57
+ # start.condition(:always)
58
+ # end
59
+ # end
@@ -0,0 +1,16 @@
1
+ God.watch do |w|
2
+ w.name = 'running-load'
3
+ w.start = '/Users/tom/dev/god/test/configs/child_polls/simple_server.rb'
4
+ w.stop = ''
5
+ w.interval = 5
6
+ w.grace = 2
7
+ w.uid = 'tom'
8
+ w.gid = 'tom'
9
+ w.group = 'test'
10
+
11
+ w.start_if do |start|
12
+ start.condition(:process_running) do |c|
13
+ c.running = false
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,12 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ trap :USR1 do
4
+
5
+ end
6
+
7
+ loop do
8
+ STDOUT.puts('server');
9
+ STDOUT.flush;
10
+
11
+ sleep 10
12
+ end
@@ -0,0 +1,39 @@
1
+ God.watch do |w|
2
+ w.name = 'stop-options'
3
+ w.start = File.join(GOD_ROOT, *%w[test configs stop_options simple_server.rb])
4
+ w.stop_signal = 'USR1'
5
+ w.stop_timeout = 5
6
+ w.interval = 5
7
+ w.grace = 2
8
+
9
+ w.start_if do |start|
10
+ start.condition(:process_running) do |c|
11
+ c.running = false
12
+ end
13
+ end
14
+
15
+ w.restart_if do |restart|
16
+ restart.condition(:cpu_usage) do |c|
17
+ c.above = 30.percent
18
+ c.times = [3, 5]
19
+ end
20
+
21
+ restart.condition(:memory_usage) do |c|
22
+ c.above = 10.megabytes
23
+ c.times = [3, 5]
24
+ end
25
+ end
26
+
27
+ # lifecycle
28
+ w.lifecycle do |on|
29
+ on.condition(:flapping) do |c|
30
+ c.to_state = [:start, :restart]
31
+ c.times = 3
32
+ c.within = 60.seconds
33
+ c.transition = :unmonitored
34
+ c.retry_in = 10.seconds
35
+ c.retry_times = 2
36
+ c.retry_within = 5.minutes
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,3 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ loop { puts 'server'; sleep 1 }
@@ -0,0 +1,15 @@
1
+ ('01'..'08').each do |i|
2
+ God.watch do |w|
3
+ w.name = "stress-#{i}"
4
+ w.start = "ruby " + File.join(File.dirname(__FILE__), *%w[simple_server.rb])
5
+ w.interval = 0
6
+ w.grace = 2
7
+ w.group = 'test'
8
+
9
+ w.start_if do |start|
10
+ start.condition(:process_running) do |c|
11
+ c.running = false
12
+ end
13
+ end
14
+ end
15
+ end
File without changes
@@ -0,0 +1,26 @@
1
+ LOG_DIR = File.join(File.dirname(__FILE__), *%w[logs])
2
+
3
+ God.task do |t|
4
+ t.name = 'task'
5
+ t.valid_states = [:ok, :clean]
6
+ t.initial_state = :ok
7
+ t.interval = 5
8
+
9
+ # t.clean = lambda do
10
+ # Dir[File.join(LOG_DIR, '*.log')].each do |f|
11
+ # File.delete(f)
12
+ # end
13
+ # end
14
+
15
+ t.clean = "rm #{File.join(LOG_DIR, '*.log')}"
16
+
17
+ t.transition(:clean, :ok)
18
+
19
+ t.transition(:ok, :clean) do |on|
20
+ on.condition(:lambda) do |c|
21
+ c.lambda = lambda do
22
+ Dir[File.join(LOG_DIR, '*.log')].size > 1
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,61 @@
1
+ ENV['GOD_TEST_RAILS_ROOT'] || abort("Set a rails root for testing in an environment variable called GOD_TEST_RAILS_ROOT")
2
+
3
+ RAILS_ROOT = ENV['GOD_TEST_RAILS_ROOT']
4
+
5
+ port = 5000
6
+
7
+ God.watch do |w|
8
+ w.name = "local-#{port}"
9
+ w.interval = 5.seconds
10
+ w.start = "mongrel_rails start -P ./log/mongrel.pid -c #{RAILS_ROOT} -p #{port} -d"
11
+ w.restart = "mongrel_rails restart -P ./log/mongrel.pid -c #{RAILS_ROOT}"
12
+ w.stop = "mongrel_rails stop -P ./log/mongrel.pid -c #{RAILS_ROOT}"
13
+ w.group = 'mongrels'
14
+ w.pid_file = File.join(RAILS_ROOT, "log/mongrel.pid")
15
+
16
+ # clean pid files before start if necessary
17
+ w.behavior(:clean_pid_file)
18
+
19
+ # determine the state on startup
20
+ w.transition(:init, { true => :up, false => :start }) do |on|
21
+ on.condition(:process_running) do |c|
22
+ c.running = true
23
+ end
24
+ end
25
+
26
+ # determine when process has finished starting
27
+ w.transition([:start, :restart], :up) do |on|
28
+ on.condition(:process_running) do |c|
29
+ c.running = true
30
+ end
31
+ end
32
+
33
+ # start if process is not running
34
+ w.transition(:up, :start) do |on|
35
+ on.condition(:process_exits)
36
+ end
37
+
38
+ # restart if memory or cpu is too high
39
+ w.transition(:up, :restart) do |on|
40
+ on.condition(:memory_usage) do |c|
41
+ c.interval = 1
42
+ c.above = 50.megabytes
43
+ c.times = [3, 5]
44
+ end
45
+
46
+ on.condition(:cpu_usage) do |c|
47
+ c.interval = 1
48
+ c.above = 10.percent
49
+ c.times = [3, 5]
50
+ end
51
+
52
+ on.condition(:http_response_code) do |c|
53
+ c.host = 'localhost'
54
+ c.port = port
55
+ c.path = '/'
56
+ c.code_is_not = 200
57
+ c.timeout = 10.seconds
58
+ c.times = [3, 5]
59
+ end
60
+ end
61
+ end