godhead 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|