godhead 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.textile +50 -0
- data/Rakefile +2 -12
- data/VERSION +1 -1
- data/examples/etc/god.conf +14 -0
- data/examples/etc/god/god_config.yaml +10 -0
- data/examples/etc/god/sample_project.god +31 -0
- data/examples/etc/init.d/god +48 -0
- data/godhead.gemspec +27 -15
- data/lib/godhead/extensions.rb +1 -0
- data/lib/godhead/extensions/string.rb +9 -0
- data/lib/godhead/god_email.rb +45 -0
- data/lib/godhead/god_recipe.rb +20 -13
- data/lib/godhead/notifications.rb +43 -0
- data/lib/godhead/recipes.rb +6 -2
- data/lib/godhead/recipes/beanstalkd_recipe.rb +13 -6
- data/lib/godhead/recipes/delayed_job_recipe.rb +126 -0
- data/lib/godhead/recipes/generic_worker_recipe.rb +14 -5
- data/lib/godhead/recipes/memcached_recipe.rb +1 -1
- data/lib/godhead/recipes/mongrel_recipe.rb +29 -0
- data/lib/godhead/recipes/mysql_recipe.rb +20 -0
- data/lib/godhead/recipes/nginx_recipe.rb +24 -7
- data/lib/godhead/recipes/resque_recipe.rb +63 -0
- data/lib/godhead/recipes/starling_recipe.rb +3 -2
- data/lib/godhead/recipes/thin_recipe.rb +12 -19
- data/lib/godhead/recipes/thinking_sphinx.rb +98 -0
- data/lib/godhead/recipes/tyrant_recipe.rb +11 -0
- data/lib/godhead/recipes/unicorn_recipe.rb +42 -0
- data/lib/godhead/recipes/workling_recipe.rb +23 -0
- metadata +21 -10
- data/README-god.textile +0 -54
- data/lib/godhead/notification.rb +0 -45
- data/lib/godhead/notification/gmail.rb +0 -0
- data/sample.god +0 -36
data/lib/godhead/recipes.rb
CHANGED
@@ -1,9 +1,13 @@
|
|
1
1
|
module Godhead
|
2
2
|
autoload :BeanstalkdRecipe, 'godhead/recipes/beanstalkd_recipe.rb'
|
3
3
|
autoload :GenericWorkerRecipe, 'godhead/recipes/generic_worker_recipe.rb'
|
4
|
+
autoload :MemcachedRecipe, 'godhead/recipes/memcached_recipe.rb'
|
5
|
+
autoload :MongrelRecipe, 'godhead/recipes/mongrel_recipe.rb'
|
4
6
|
autoload :NginxRecipe, 'godhead/recipes/nginx_recipe.rb'
|
7
|
+
autoload :NginxRunnerRecipe, 'godhead/recipes/nginx_recipe.rb'
|
8
|
+
autoload :StarlingRecipe, 'godhead/recipes/starling_recipe.rb'
|
5
9
|
autoload :ThinRecipe, 'godhead/recipes/thin_recipe.rb'
|
6
10
|
autoload :TyrantRecipe, 'godhead/recipes/tyrant_recipe.rb'
|
7
|
-
autoload :
|
8
|
-
autoload :
|
11
|
+
autoload :UnicornRecipe, 'godhead/recipes/unicorn_recipe.rb'
|
12
|
+
autoload :WorklingRecipe, 'godhead/recipes/workling_recipe.rb'
|
9
13
|
end
|
@@ -1,12 +1,13 @@
|
|
1
1
|
module Godhead
|
2
2
|
class BeanstalkdRecipe < GodRecipe
|
3
3
|
DEFAULT_OPTIONS = {
|
4
|
-
:listen_on
|
5
|
-
:port
|
6
|
-
:max_job_size
|
7
|
-
:
|
8
|
-
:
|
9
|
-
:
|
4
|
+
:listen_on => '0.0.0.0',
|
5
|
+
:port => 11300,
|
6
|
+
:max_job_size => '65535',
|
7
|
+
:default_interval => 1.minute,
|
8
|
+
:max_cpu_usage => 20.percent,
|
9
|
+
:max_mem_usage => 500.megabytes,
|
10
|
+
:runner_path => '/usr/local/bin/beanstalkd',
|
10
11
|
}
|
11
12
|
def self.default_options() super.deep_merge(Godhead::BeanstalkdRecipe::DEFAULT_OPTIONS) ; end
|
12
13
|
|
@@ -19,6 +20,12 @@ module Godhead
|
|
19
20
|
"-z #{options[:max_job_size]}",
|
20
21
|
].flatten.compact.join(" ")
|
21
22
|
end
|
23
|
+
|
24
|
+
# don't try to invent a pid_file -- by default god will find and make one
|
25
|
+
# and will handle task killing/restarting/etc.
|
26
|
+
def pid_file()
|
27
|
+
nil
|
28
|
+
end
|
22
29
|
end
|
23
30
|
end
|
24
31
|
|
@@ -0,0 +1,126 @@
|
|
1
|
+
|
2
|
+
# FIXME -- turn this into a godhead recipe
|
3
|
+
|
4
|
+
# ===========================================================================
|
5
|
+
#
|
6
|
+
# From http://github.com/blog/229-dj-god
|
7
|
+
#
|
8
|
+
|
9
|
+
# rails_root = "/data/github/current"
|
10
|
+
# 20.times do |num|
|
11
|
+
# God.watch do |w|
|
12
|
+
# w.name = "dj-#{num}"
|
13
|
+
# w.group = 'dj'
|
14
|
+
# w.interval = 30.seconds
|
15
|
+
# w.start = "rake -f #{rails_root}/Rakefile production jobs:work"
|
16
|
+
#
|
17
|
+
# w.uid = 'git'
|
18
|
+
# w.gid = 'git'
|
19
|
+
#
|
20
|
+
# # retart if memory gets too high
|
21
|
+
# w.transition(:up, :restart) do |on|
|
22
|
+
# on.condition(:memory_usage) do |c|
|
23
|
+
# c.above = 300.megabytes
|
24
|
+
# c.times = 2
|
25
|
+
# end
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# # determine the state on startup
|
29
|
+
# w.transition(:init, { true => :up, false => :start }) do |on|
|
30
|
+
# on.condition(:process_running) do |c|
|
31
|
+
# c.running = true
|
32
|
+
# end
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# # determine when process has finished starting
|
36
|
+
# w.transition([:start, :restart], :up) do |on|
|
37
|
+
# on.condition(:process_running) do |c|
|
38
|
+
# c.running = true
|
39
|
+
# c.interval = 5.seconds
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
# # failsafe
|
43
|
+
# on.condition(:tries) do |c|
|
44
|
+
# c.times = 5
|
45
|
+
# c.transition = :start
|
46
|
+
# c.interval = 5.seconds
|
47
|
+
# end
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
# # start if process is not running
|
51
|
+
# w.transition(:up, :start) do |on|
|
52
|
+
# on.condition(:process_running) do |c|
|
53
|
+
# c.running = false
|
54
|
+
# end
|
55
|
+
# end
|
56
|
+
# end
|
57
|
+
# end
|
58
|
+
|
59
|
+
# ===========================================================================
|
60
|
+
#
|
61
|
+
# from http://livollmers.net/index.php/2008/11/05/asynchronous-mail-with-delayedjob-god-daemons/
|
62
|
+
#
|
63
|
+
|
64
|
+
# God.watch do |w|
|
65
|
+
# w.name = "delayed_job_worker"
|
66
|
+
# w.interval = 10.seconds
|
67
|
+
# w.start = "#{RAILS_ROOT}/script/delayed_job_worker_control start -- production"
|
68
|
+
# w.stop = "#{RAILS_ROOT}/script/delayed_job_worker_control stop"
|
69
|
+
# w.restart = "#{RAILS_ROOT}/script/delayed_job_worker_control restart"
|
70
|
+
# w.start_grace = 10.seconds
|
71
|
+
# w.restart_grace = 10.seconds
|
72
|
+
# w.pid_file = "#{RAILS_ROOT}/tmp/pids/delayed_job_worker.pid"
|
73
|
+
#
|
74
|
+
# w.uid = "deploy"
|
75
|
+
# w.gid = "root"
|
76
|
+
# w.behavior(:clean_pid_file)
|
77
|
+
# # determine the state on startup
|
78
|
+
# w.transition(:init, { true => :up, false => :start }) do |on|
|
79
|
+
# on.condition(:process_running) do |c|
|
80
|
+
# c.running = true
|
81
|
+
# end
|
82
|
+
# end
|
83
|
+
#
|
84
|
+
# # determine when process has finished starting
|
85
|
+
# w.transition([:start, :restart], :up) do |on|
|
86
|
+
# on.condition(:process_running) do |c|
|
87
|
+
# c.running = true
|
88
|
+
# end
|
89
|
+
#
|
90
|
+
# # failsafe
|
91
|
+
# on.condition(:tries) do |c|
|
92
|
+
# c.times = 5
|
93
|
+
# c.transition = :start
|
94
|
+
# end
|
95
|
+
# end
|
96
|
+
#
|
97
|
+
# # start if process is not running
|
98
|
+
# w.transition(:up, :start) do |on|
|
99
|
+
# on.condition(:process_exits)
|
100
|
+
# end
|
101
|
+
#
|
102
|
+
# w.restart_if do |restart|
|
103
|
+
# restart.condition(:memory_usage) do |c|
|
104
|
+
# c.above = 100.megabytes
|
105
|
+
# c.times = [3, 5]
|
106
|
+
# end
|
107
|
+
#
|
108
|
+
# restart.condition(:cpu_usage) do |c|
|
109
|
+
# c.above = 50.percent
|
110
|
+
# c.times = 5
|
111
|
+
# end
|
112
|
+
# end
|
113
|
+
#
|
114
|
+
# w.lifecycle do |on|
|
115
|
+
# on.condition(:flapping) do |c|
|
116
|
+
# c.to_state = [:start, :restart]
|
117
|
+
# c.times = 5
|
118
|
+
# c.within = 5.minute
|
119
|
+
# c.transition = :unmonitored
|
120
|
+
# c.retry_in = 10.minutes
|
121
|
+
# c.retry_times = 5
|
122
|
+
# c.retry_within = 2.hours
|
123
|
+
# end
|
124
|
+
# end
|
125
|
+
# end
|
126
|
+
# end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Godhead
|
2
2
|
#
|
3
|
-
#
|
3
|
+
# Generic worker process monitoring recipe
|
4
4
|
#
|
5
5
|
class GenericWorkerRecipe < GodRecipe
|
6
6
|
DEFAULT_OPTIONS = {
|
@@ -14,6 +14,7 @@ module Godhead
|
|
14
14
|
|
15
15
|
def initialize _options={}
|
16
16
|
super _options
|
17
|
+
p [options, handle, process_log_file]
|
17
18
|
raise "need a runner path" unless options[:runner_path]
|
18
19
|
end
|
19
20
|
|
@@ -23,16 +24,24 @@ module Godhead
|
|
23
24
|
end
|
24
25
|
|
25
26
|
# don't try to invent a pid_file -- by default god will find and make one
|
26
|
-
|
27
|
-
|
27
|
+
# and will handle task killing/restarting/etc.
|
28
|
+
def pid_file()
|
29
|
+
nil
|
30
|
+
end
|
31
|
+
|
32
|
+
def setup_watcher watcher
|
33
|
+
super
|
34
|
+
watcher.log = process_log_file
|
28
35
|
end
|
29
36
|
|
30
37
|
def start_command
|
31
|
-
[
|
38
|
+
cmd = [
|
32
39
|
"sudo",
|
33
40
|
(options[:user] ? "-u #{options[:user]}" : nil),
|
34
|
-
options[:runner_path]
|
41
|
+
options[:runner_path],
|
35
42
|
].flatten.compact.join(" ")
|
43
|
+
p ['worker command', cmd]
|
44
|
+
cmd
|
36
45
|
end
|
37
46
|
|
38
47
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Godhead
|
2
|
+
class MongrelRecipe < GodRecipe
|
3
|
+
DEFAULT_OPTIONS = {
|
4
|
+
:default_interval => 30.seconds,
|
5
|
+
:max_cpu_usage => 50.percent,
|
6
|
+
:max_mem_usage => 150.megabytes,
|
7
|
+
:port => 5000,
|
8
|
+
:runner_path => 'mongrel_rails', # path to mongrel_rails. Override this in the site config file.
|
9
|
+
:runner_conf => nil,
|
10
|
+
:pid_file => nil,
|
11
|
+
}
|
12
|
+
def self.default_options() super.deep_merge(DEFAULT_OPTIONS) ; end
|
13
|
+
|
14
|
+
# Call the thin runner script
|
15
|
+
def tell_runner action
|
16
|
+
[
|
17
|
+
options[:runner_path],
|
18
|
+
action,
|
19
|
+
"--config=#{options[:runner_conf]}",
|
20
|
+
"--port=#{ options[:port]}",
|
21
|
+
"--pid=#{pid_file}",
|
22
|
+
(action == 'stop' ? nil : '-d'),
|
23
|
+
].flatten.compact.join(" ")
|
24
|
+
end
|
25
|
+
def start_command() tell_runner :start end
|
26
|
+
def restart_command() tell_runner :restart end
|
27
|
+
def stop_command() tell_runner :stop end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Godhead
|
2
|
+
#
|
3
|
+
# Mysql monitoring recipe
|
4
|
+
#
|
5
|
+
# Pretty standard, but speed up the flapping window -- starts and restarts
|
6
|
+
# should be fast, and we don't want the server down for long.
|
7
|
+
class MysqlRecipe < GodRecipe
|
8
|
+
DEFAULT_OPTIONS = {
|
9
|
+
:flapping_window => 2.minutes,
|
10
|
+
:flapping_retry_in => 30.minutes,
|
11
|
+
:max_cpu_usage => nil,
|
12
|
+
:max_mem_usage => nil,
|
13
|
+
:pid_file => "/var/run/mysqld/mysqld.pid",
|
14
|
+
:port => 80,
|
15
|
+
}
|
16
|
+
def self.default_options() super.deep_merge(DEFAULT_OPTIONS) ; end
|
17
|
+
# uses 'service mysql start' and so forth for task management
|
18
|
+
include Godhead::RunsAsService
|
19
|
+
end
|
20
|
+
end
|
@@ -2,21 +2,37 @@ module Godhead
|
|
2
2
|
#
|
3
3
|
# Nginx monitoring recipe
|
4
4
|
#
|
5
|
+
# This defines standard options for nginx, and leaves it to subclasses to
|
6
|
+
# define the start_command and conf path and so forth.
|
7
|
+
#
|
8
|
+
# The nginx monitor not only watches the PID but also checks for a correct
|
9
|
+
# http_response_code
|
5
10
|
class GenericNginxRecipe < GodRecipe
|
6
11
|
DEFAULT_OPTIONS = {
|
7
|
-
:max_cpu_usage =>
|
8
|
-
:max_mem_usage =>
|
12
|
+
:max_cpu_usage => nil,
|
13
|
+
:max_mem_usage => nil,
|
9
14
|
:pid_file => "/var/run/nginx/nginx.pid",
|
15
|
+
:port => 80,
|
10
16
|
}
|
11
17
|
def self.default_options() super.deep_merge(DEFAULT_OPTIONS) ; end
|
12
18
|
|
13
|
-
|
14
|
-
|
19
|
+
# restart if can't contact server
|
20
|
+
def setup_restart watcher
|
21
|
+
super watcher
|
22
|
+
watcher.restart_if do |restart|
|
23
|
+
restart.condition(:http_response_code) do |c|
|
24
|
+
c.host = 'localhost'
|
25
|
+
c.port = options[:port]
|
26
|
+
c.path = '/'
|
27
|
+
c.timeout = 3.seconds
|
28
|
+
c.times = [4, 5] # 4 out of 5 times failure
|
29
|
+
c.code_is_not = 200
|
30
|
+
end
|
31
|
+
end
|
15
32
|
end
|
16
33
|
|
17
|
-
def
|
18
|
-
|
19
|
-
super
|
34
|
+
def self.recipe_name
|
35
|
+
'nginx'
|
20
36
|
end
|
21
37
|
end
|
22
38
|
|
@@ -67,3 +83,4 @@ end
|
|
67
83
|
# -p prefix : set prefix path (default: /usr/local/nginx/)
|
68
84
|
# -c filename : set configuration file (default: /slice/etc/nginx/nginx.conf)
|
69
85
|
# -g directives : set global directives out of configuration file
|
86
|
+
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# module Godhead
|
2
|
+
# #
|
3
|
+
# # Resque monitoring recipe
|
4
|
+
# #
|
5
|
+
# # inspired by http://railscasts.com/episodes/130-monitoring-with-god
|
6
|
+
# class ResqueRecipe < GodRecipe
|
7
|
+
# DEFAULT_OPTIONS = {
|
8
|
+
# :max_cpu_usage => 30.percent,
|
9
|
+
# :max_mem_usage => 100.megabytes,
|
10
|
+
# #
|
11
|
+
# :port => 22122,
|
12
|
+
# :runner_dir => ENV['RAILS_ROOT'],
|
13
|
+
# :runner_env => ENV['RAILS_ENV'],
|
14
|
+
# # uid => nil,
|
15
|
+
# # gid => nil,
|
16
|
+
# }
|
17
|
+
# def self.default_options() super.deep_merge(DEFAULT_OPTIONS) ; end
|
18
|
+
#
|
19
|
+
# def start_command
|
20
|
+
# "env QUEUE=critical,high,low /usr/bin/rake -f #{options[:runner_dir]}/Rakefile #{options[:runner_env]} resque:work"
|
21
|
+
# end
|
22
|
+
# end
|
23
|
+
# end
|
24
|
+
|
25
|
+
|
26
|
+
# # restart if memory gets too high
|
27
|
+
# w.transition(:up, :restart) do |on|
|
28
|
+
# on.condition(:memory_usage) do |c|
|
29
|
+
# c.above = 350.megabytes
|
30
|
+
# c.times = 2
|
31
|
+
# end
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
# # determine the state on startup
|
35
|
+
# w.transition(:init, { true => :up, false => :start }) do |on|
|
36
|
+
# on.condition(:process_running) do |c|
|
37
|
+
# c.running = true
|
38
|
+
# end
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# # determine when process has finished starting
|
42
|
+
# w.transition([:start, :restart], :up) do |on|
|
43
|
+
# on.condition(:process_running) do |c|
|
44
|
+
# c.running = true
|
45
|
+
# c.interval = 5.seconds
|
46
|
+
# end
|
47
|
+
#
|
48
|
+
# # failsafe
|
49
|
+
# on.condition(:tries) do |c|
|
50
|
+
# c.times = 5
|
51
|
+
# c.transition = :start
|
52
|
+
# c.interval = 5.seconds
|
53
|
+
# end
|
54
|
+
# end
|
55
|
+
#
|
56
|
+
# # start if process is not running
|
57
|
+
# w.transition(:up, :start) do |on|
|
58
|
+
# on.condition(:process_running) do |c|
|
59
|
+
# c.running = false
|
60
|
+
# end
|
61
|
+
# end
|
62
|
+
# end
|
63
|
+
# end
|
@@ -2,10 +2,11 @@ module Godhead
|
|
2
2
|
#
|
3
3
|
# Starling monitoring recipe
|
4
4
|
#
|
5
|
+
# inspired by http://railscasts.com/episodes/130-monitoring-with-god
|
5
6
|
class StarlingRecipe < GodRecipe
|
6
7
|
DEFAULT_OPTIONS = {
|
7
|
-
:max_cpu_usage =>
|
8
|
-
:max_mem_usage =>
|
8
|
+
:max_cpu_usage => 30.percent,
|
9
|
+
:max_mem_usage => 20.megabytes,
|
9
10
|
#
|
10
11
|
:port => 22122,
|
11
12
|
}
|
@@ -1,36 +1,29 @@
|
|
1
1
|
module Godhead
|
2
2
|
class ThinRecipe < GodRecipe
|
3
3
|
DEFAULT_OPTIONS = {
|
4
|
-
:
|
5
|
-
:
|
6
|
-
:
|
7
|
-
:
|
4
|
+
:default_interval => 180.seconds,
|
5
|
+
:port => 3000,
|
6
|
+
:thin_port_offset => 3000,
|
7
|
+
:runner_path => '/usr/bin/thin', # path to thin. Override this in the site config file.
|
8
|
+
:runner_conf => nil,
|
9
|
+
:pid_file => nil,
|
8
10
|
}
|
9
11
|
def self.default_options() super.deep_merge(DEFAULT_OPTIONS) ; end
|
10
12
|
|
11
|
-
#
|
12
|
-
def
|
13
|
+
# Call the thin runner script
|
14
|
+
def tell_runner action
|
13
15
|
[
|
14
16
|
options[:runner_path],
|
15
17
|
"--config=#{options[:runner_conf]}",
|
16
18
|
"--rackup=#{options[:rackup_file]}",
|
17
19
|
"--port=#{ options[:port]}",
|
18
20
|
"--pid=#{pid_file}",
|
21
|
+
# "--only=#{options[:port].to_i - options[:thin_port_offset].to_i}",
|
19
22
|
action
|
20
23
|
].flatten.compact.join(" ")
|
21
24
|
end
|
22
|
-
|
23
|
-
def
|
24
|
-
|
25
|
-
end
|
26
|
-
|
27
|
-
def restart_command
|
28
|
-
tell_thin :restart
|
29
|
-
end
|
30
|
-
|
31
|
-
def stop_command
|
32
|
-
tell_thin :stop
|
33
|
-
end
|
25
|
+
def start_command() tell_runner :start end
|
26
|
+
def restart_command() tell_runner :restart end
|
27
|
+
def stop_command() tell_runner :stop end
|
34
28
|
end
|
35
|
-
|
36
29
|
end
|