god 0.2.0 → 0.3.0
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/History.txt +26 -2
- data/Manifest.txt +19 -5
- data/Rakefile +7 -2
- data/bin/god +131 -11
- data/examples/events.god +52 -0
- data/examples/gravatar.god +29 -35
- data/ext/god/extconf.rb +49 -2
- data/ext/god/kqueue_handler.c +2 -2
- data/ext/god/netlink_handler.c +17 -4
- data/lib/god.rb +127 -25
- data/lib/god/behavior.rb +8 -3
- data/lib/god/behaviors/clean_pid_file.rb +2 -8
- data/lib/god/condition.rb +6 -5
- data/lib/god/conditions/cpu_usage.rb +4 -4
- data/lib/god/conditions/lambda.rb +19 -0
- data/lib/god/conditions/memory_usage.rb +4 -4
- data/lib/god/conditions/process_exits.rb +5 -7
- data/lib/god/conditions/process_running.rb +4 -4
- data/lib/god/errors.rb +3 -0
- data/lib/god/event_handler.rb +28 -3
- data/lib/god/event_handlers/dummy_handler.rb +13 -0
- data/lib/god/event_handlers/kqueue_handler.rb +2 -0
- data/lib/god/event_handlers/netlink_handler.rb +2 -0
- data/lib/god/hub.rb +40 -23
- data/lib/god/metric.rb +4 -4
- data/lib/god/process.rb +105 -0
- data/lib/god/registry.rb +28 -0
- data/lib/god/server.rb +3 -4
- data/lib/god/sugar.rb +47 -0
- data/lib/god/system/process.rb +1 -2
- data/lib/god/timer.rb +13 -6
- data/lib/god/watch.rb +61 -29
- data/test/configs/child_events/child_events.god +25 -0
- data/test/configs/child_events/simple_server.rb +3 -0
- data/test/configs/child_polls/child_polls.god +15 -0
- data/test/configs/child_polls/simple_server.rb +3 -0
- data/test/configs/daemon_events/daemon_events.god +30 -0
- data/test/configs/daemon_events/simple_server.rb +6 -0
- data/test/configs/real.rb +47 -49
- data/test/configs/test.rb +52 -62
- data/test/helper.rb +44 -14
- data/test/test_behavior.rb +10 -2
- data/test/test_condition.rb +19 -3
- data/test/test_conditions_process_running.rb +42 -0
- data/test/test_event_handler.rb +73 -0
- data/test/test_god.rb +206 -9
- data/test/test_handlers_kqueue_handler.rb +12 -0
- data/test/test_hub.rb +157 -0
- data/test/test_metric.rb +30 -2
- data/test/test_process.rb +84 -0
- data/test/test_registry.rb +14 -0
- data/test/test_server.rb +3 -2
- data/test/test_sugar.rb +42 -0
- data/test/test_system_process.rb +1 -1
- data/test/test_timer.rb +8 -1
- data/test/test_watch.rb +137 -2
- metadata +28 -17
- data/examples/local.god +0 -60
- data/ext/god/Makefile +0 -149
- data/lib/god/base.rb +0 -13
- data/lib/god/meddle.rb +0 -38
- data/test/test_meddle.rb +0 -46
data/History.txt
CHANGED
@@ -1,10 +1,34 @@
|
|
1
|
-
== 0.
|
1
|
+
== 0.3.0 / 2007-08-17
|
2
|
+
|
3
|
+
* Fix netlink header problem on Ubuntu Edgy [Dan Sully]
|
4
|
+
* Add uid/gid setting for processes [kevinclark]
|
5
|
+
* Add autostart flag for watches so they don't necessarily startup with god [kevinclark]
|
6
|
+
* Change command line call options for god binary to accommodate watch start/stop functionality
|
7
|
+
* Add individual start/stop/restart grace periods for finer grained control
|
8
|
+
* Change default DRb port to 17165 ('god'.to_i(32))
|
9
|
+
* Implement command line control to start/restart/stop/monitor/unmonitor watches/groups by name
|
10
|
+
* Watches can now belong to a group that can be controlled as a whole
|
11
|
+
* Allow god to be installed (sans events) on systems that don't support events
|
12
|
+
* Daemonize and handle PID files for non-daemonizing scripts [kevinclark]
|
13
|
+
* Fix simple mode lifecycle gap
|
14
|
+
* Remove necessity to specify pid_file for conditions
|
15
|
+
* Change config file to use God.init and God.watch directly instead of God.meddle block
|
16
|
+
* Move god binary command logic to main library
|
17
|
+
* Enhance god binary with better reporting
|
18
|
+
* Fix synchronization bug in Timer (reported by Srini Panguluri)
|
19
|
+
* Add Lambda condition for easy custom conditions [Mike Mintz]
|
20
|
+
* Add sugar for numerics (seconds, minutes, kilobytes, megabytes, percent, etc)
|
21
|
+
* Add optional PID and log file generation to god binary for daemon mode
|
22
|
+
* Add God.load to do glob enabled loading
|
23
|
+
* Add -V option to god binary for detailed version/build info
|
24
|
+
|
25
|
+
== 0.2.0 / 2007-07-18
|
2
26
|
|
3
27
|
* Rewrote innards to use a state and event based lifecycle
|
4
28
|
* Basic support for events via kqueue (bsd/darwin) and netlink/pec (linux) [kevinclark]
|
5
29
|
* Added advanced syntax (simple syntax calls advanced api underneath)
|
6
30
|
* Condition returns have changed meaning. With simple syntax, a true return activates block
|
7
|
-
* Updated http://god.
|
31
|
+
* Updated http://god.rubyforge.org with updated simple config and new advanced config
|
8
32
|
|
9
33
|
== 0.1.0 / 2007-07-07
|
10
34
|
|
data/Manifest.txt
CHANGED
@@ -3,46 +3,60 @@ Manifest.txt
|
|
3
3
|
README.txt
|
4
4
|
Rakefile
|
5
5
|
bin/god
|
6
|
+
examples/events.god
|
6
7
|
examples/gravatar.god
|
7
|
-
examples/local.god
|
8
|
-
ext/god/Makefile
|
9
8
|
ext/god/extconf.rb
|
10
9
|
ext/god/kqueue_handler.c
|
11
10
|
ext/god/netlink_handler.c
|
12
11
|
lib/god.rb
|
13
|
-
lib/god/base.rb
|
14
12
|
lib/god/behavior.rb
|
15
13
|
lib/god/behaviors/clean_pid_file.rb
|
16
14
|
lib/god/condition.rb
|
17
15
|
lib/god/conditions/always.rb
|
18
16
|
lib/god/conditions/cpu_usage.rb
|
17
|
+
lib/god/conditions/lambda.rb
|
19
18
|
lib/god/conditions/memory_usage.rb
|
20
19
|
lib/god/conditions/process_exits.rb
|
21
20
|
lib/god/conditions/process_running.rb
|
22
21
|
lib/god/conditions/timeline.rb
|
23
22
|
lib/god/errors.rb
|
24
23
|
lib/god/event_handler.rb
|
24
|
+
lib/god/event_handlers/dummy_handler.rb
|
25
25
|
lib/god/event_handlers/kqueue_handler.rb
|
26
26
|
lib/god/event_handlers/netlink_handler.rb
|
27
27
|
lib/god/hub.rb
|
28
|
-
lib/god/meddle.rb
|
29
28
|
lib/god/metric.rb
|
29
|
+
lib/god/process.rb
|
30
|
+
lib/god/registry.rb
|
30
31
|
lib/god/reporter.rb
|
31
32
|
lib/god/server.rb
|
33
|
+
lib/god/sugar.rb
|
32
34
|
lib/god/system/process.rb
|
33
35
|
lib/god/timer.rb
|
34
36
|
lib/god/watch.rb
|
37
|
+
test/configs/child_events/child_events.god
|
38
|
+
test/configs/child_events/simple_server.rb
|
39
|
+
test/configs/child_polls/child_polls.god
|
40
|
+
test/configs/child_polls/simple_server.rb
|
41
|
+
test/configs/daemon_events/daemon_events.god
|
42
|
+
test/configs/daemon_events/simple_server.rb
|
35
43
|
test/configs/real.rb
|
36
44
|
test/configs/test.rb
|
37
45
|
test/helper.rb
|
38
46
|
test/suite.rb
|
39
47
|
test/test_behavior.rb
|
40
48
|
test/test_condition.rb
|
49
|
+
test/test_conditions_process_running.rb
|
50
|
+
test/test_event_handler.rb
|
41
51
|
test/test_god.rb
|
42
|
-
test/
|
52
|
+
test/test_handlers_kqueue_handler.rb
|
53
|
+
test/test_hub.rb
|
43
54
|
test/test_metric.rb
|
55
|
+
test/test_process.rb
|
56
|
+
test/test_registry.rb
|
44
57
|
test/test_reporter.rb
|
45
58
|
test/test_server.rb
|
59
|
+
test/test_sugar.rb
|
46
60
|
test/test_system_process.rb
|
47
61
|
test/test_timeline.rb
|
48
62
|
test/test_timer.rb
|
data/Rakefile
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
require 'rubygems'
|
4
4
|
require 'hoe'
|
5
5
|
|
6
|
-
Hoe.new('god', '0.
|
6
|
+
Hoe.new('god', '0.3.0') do |p|
|
7
7
|
p.rubyforge_name = 'god'
|
8
8
|
p.author = 'Tom Preston-Werner'
|
9
9
|
p.email = 'tom@rubyisawesome.com'
|
@@ -11,7 +11,7 @@ Hoe.new('god', '0.2.0') do |p|
|
|
11
11
|
p.summary = 'Like monit, only awesome'
|
12
12
|
p.description = "God is an easy to configure, easy to extend monitoring framework written in Ruby."
|
13
13
|
p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
|
14
|
-
p.extra_deps << ['daemons', '>=1.0.7']
|
14
|
+
# p.extra_deps << ['daemons', '>=1.0.7']
|
15
15
|
p.spec_extras = {:extensions => ['ext/god/extconf.rb']}
|
16
16
|
end
|
17
17
|
|
@@ -25,4 +25,9 @@ task :site do
|
|
25
25
|
sh "scp -r site/* mojombo@god.rubyforge.org:/var/www/gforge-projects/god"
|
26
26
|
end
|
27
27
|
|
28
|
+
desc "Upload site to Rubyforge"
|
29
|
+
task :site_edge do
|
30
|
+
sh "scp -r site/* mojombo@god.rubyforge.org:/var/www/gforge-projects/god/edge"
|
31
|
+
end
|
32
|
+
|
28
33
|
# vim: syntax=Ruby
|
data/bin/god
CHANGED
@@ -3,24 +3,144 @@
|
|
3
3
|
$:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
|
4
4
|
|
5
5
|
require 'rubygems'
|
6
|
-
require 'daemons'
|
7
6
|
require 'optparse'
|
8
|
-
require '
|
7
|
+
require 'drb'
|
8
|
+
|
9
|
+
options = {:daemonize => true, :port => 17165}
|
9
10
|
|
10
|
-
options = {}
|
11
11
|
OptionParser.new do |opts|
|
12
|
-
opts.banner =
|
12
|
+
opts.banner = <<-EOF
|
13
|
+
Usage: god [command] [options]
|
14
|
+
|
15
|
+
Commands:
|
16
|
+
start <watch or group name>
|
17
|
+
stop <watch or group name>
|
18
|
+
monitor <watch or group name>
|
19
|
+
unmonitor <watch or group name>
|
20
|
+
|
21
|
+
Options:
|
22
|
+
EOF
|
13
23
|
|
14
24
|
opts.on("-cCONFIG", "--config-file CONFIG", "Configuration file") do |x|
|
15
25
|
options[:config] = x
|
16
26
|
end
|
17
|
-
end.parse!
|
18
27
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
28
|
+
opts.on("-pPORT", "--port PORT", "Communications port") do |x|
|
29
|
+
options[:port] = x
|
30
|
+
end
|
31
|
+
|
32
|
+
opts.on("-PFILE", "--pid FILE", "Where to write the PID file") do |x|
|
33
|
+
options[:pid] = x
|
34
|
+
end
|
35
|
+
|
36
|
+
opts.on("-lFILE", "--log FILE", "Where to write the log file") do |x|
|
37
|
+
options[:log] = x
|
38
|
+
end
|
39
|
+
|
40
|
+
opts.on("-D", "--no-daemonize", "Don't daemonize") do
|
41
|
+
options[:daemonize] = false
|
42
|
+
end
|
43
|
+
|
44
|
+
opts.on("-v", "--version", "Print the version number and exit") do
|
45
|
+
options[:version] = true
|
46
|
+
end
|
47
|
+
|
48
|
+
opts.on("-V", "Print extended version and build information") do
|
49
|
+
options[:info] = true
|
50
|
+
end
|
51
|
+
end.parse!
|
23
52
|
|
24
|
-
|
25
|
-
|
53
|
+
if options[:version]
|
54
|
+
require 'god'
|
55
|
+
|
56
|
+
# print version
|
57
|
+
puts "Version #{God::VERSION}"
|
58
|
+
exit!
|
59
|
+
elsif options[:info]
|
60
|
+
require 'god'
|
61
|
+
|
62
|
+
puts "Version: #{God::VERSION}"
|
63
|
+
puts "Polls: enabled"
|
64
|
+
puts "Events: " + God::EventHandler.event_system
|
65
|
+
|
66
|
+
exit!
|
67
|
+
elsif command = ARGV[0]
|
68
|
+
require 'god'
|
69
|
+
|
70
|
+
# a command was specified
|
71
|
+
|
72
|
+
# disable at_exit
|
73
|
+
# module God; def self.at_exit; end; end
|
74
|
+
|
75
|
+
# get the name of the watch/group
|
76
|
+
name = ARGV[1]
|
77
|
+
|
78
|
+
# connect to remote drb
|
79
|
+
DRb.start_service
|
80
|
+
server = DRbObject.new nil, "druby://localhost:#{options[:port]}"
|
81
|
+
|
82
|
+
begin
|
83
|
+
puts "Sending '#{command}' command"
|
84
|
+
|
85
|
+
# send command
|
86
|
+
watches = server.control(name, command)
|
87
|
+
|
88
|
+
# output response
|
89
|
+
puts 'The following watches were affected:'
|
90
|
+
watches.each do |w|
|
91
|
+
puts ' ' + w.name
|
92
|
+
end
|
93
|
+
rescue God::InvalidCommandError
|
94
|
+
abort "Command '#{command}' is not valid. Run 'god --help' for usage"
|
95
|
+
end
|
96
|
+
|
97
|
+
exit!
|
98
|
+
else
|
99
|
+
# start god
|
100
|
+
if !options[:daemonize]
|
101
|
+
require 'god'
|
102
|
+
load File.expand_path(options[:config])
|
103
|
+
else
|
104
|
+
pid = fork do
|
105
|
+
begin
|
106
|
+
require 'god'
|
107
|
+
|
108
|
+
log_file = options[:log] || "/dev/null"
|
109
|
+
|
110
|
+
STDIN.reopen "/dev/null"
|
111
|
+
STDOUT.reopen(log_file, "a")
|
112
|
+
STDERR.reopen STDOUT
|
113
|
+
|
114
|
+
puts "Starting god"
|
115
|
+
|
116
|
+
unless God::EventHandler.loaded?
|
117
|
+
puts
|
118
|
+
puts "***********************************************************************"
|
119
|
+
puts "*"
|
120
|
+
puts "* Event conditions are not available for your installation of god."
|
121
|
+
puts "* You may still use and write custom conditions using the poll system"
|
122
|
+
puts "*"
|
123
|
+
puts "***********************************************************************"
|
124
|
+
puts
|
125
|
+
end
|
126
|
+
|
127
|
+
puts "Resetting file descriptors"
|
128
|
+
|
129
|
+
puts "Loading config"
|
130
|
+
|
131
|
+
load File.expand_path(options[:config])
|
132
|
+
rescue => e
|
133
|
+
File.open('god.log', 'a') { |f| f.puts e.message + "\n" + e.backtrace }
|
134
|
+
abort "!!! ERROR !!!"
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
if options[:pid]
|
139
|
+
File.open(options[:pid], 'w') { |f| f.write pid }
|
140
|
+
end
|
141
|
+
|
142
|
+
::Process.detach pid
|
143
|
+
|
144
|
+
exit!
|
145
|
+
end
|
26
146
|
end
|
data/examples/events.god
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# This example shows how you might keep a local development Rails server up
|
2
|
+
# and running on your Mac.
|
3
|
+
|
4
|
+
# Run with:
|
5
|
+
# god -c /path/to/events.god
|
6
|
+
|
7
|
+
RAILS_ROOT = "/Users/tom/dev/helloworld"
|
8
|
+
|
9
|
+
God.watch do |w|
|
10
|
+
w.name = "local-3000"
|
11
|
+
w.interval = 5 # seconds
|
12
|
+
w.start = "mongrel_rails start -P ./log/mongrel.pid -c #{RAILS_ROOT} -d"
|
13
|
+
w.stop = "mongrel_rails stop -P ./log/mongrel.pid -c #{RAILS_ROOT}"
|
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 = 20
|
42
|
+
c.above = (50 * 1024) # 50mb
|
43
|
+
c.times = [3, 5]
|
44
|
+
end
|
45
|
+
|
46
|
+
on.condition(:cpu_usage) do |c|
|
47
|
+
c.interval = 10
|
48
|
+
c.above = 10 # percent
|
49
|
+
c.times = [3, 5]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/examples/gravatar.god
CHANGED
@@ -1,46 +1,40 @@
|
|
1
|
-
# run with: god
|
1
|
+
# run with: god -c /path/to/gravatar.god
|
2
2
|
#
|
3
3
|
# This is the actual config file used to keep the mongrels of
|
4
4
|
# gravatar.com running.
|
5
5
|
|
6
6
|
RAILS_ROOT = "/var/www/gravatar2/current"
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
w.behavior(:clean_pid_file) do |b|
|
22
|
-
b.pid_file = pid_file
|
23
|
-
end
|
8
|
+
%w{8200 8201 8202}.each do |port|
|
9
|
+
God.watch do |w|
|
10
|
+
w.name = "gravatar2-mongrel-#{port}"
|
11
|
+
w.interval = 30 # seconds
|
12
|
+
w.start = "mongrel_rails cluster::start --only #{port} \
|
13
|
+
-C #{RAILS_ROOT}/config/mongrel_cluster.yml"
|
14
|
+
w.stop = "mongrel_rails cluster::stop --only #{port} \
|
15
|
+
-C #{RAILS_ROOT}/config/mongrel_cluster.yml"
|
16
|
+
w.grace = 10 # seconds
|
17
|
+
|
18
|
+
pid_file = File.join(RAILS_ROOT, "log/mongrel.#{port}.pid")
|
19
|
+
|
20
|
+
w.behavior(:clean_pid_file)
|
24
21
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
22
|
+
w.start_if do |start|
|
23
|
+
start.condition(:process_running) do |c|
|
24
|
+
c.interval = 5 # seconds
|
25
|
+
c.running = false
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
w.restart_if do |restart|
|
30
|
+
restart.condition(:memory_usage) do |c|
|
31
|
+
c.above = (150 * 1024) # 150mb
|
32
|
+
c.times = [3, 5] # 3 out of 5 intervals
|
30
33
|
end
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
c.above = (150 * 1024) # 150mb
|
36
|
-
c.times = [3, 5] # 3 out of 5 intervals
|
37
|
-
end
|
38
|
-
|
39
|
-
restart.condition(:cpu_usage) do |c|
|
40
|
-
c.pid_file = pid_file
|
41
|
-
c.above = 50 # percent
|
42
|
-
c.times = 5
|
43
|
-
end
|
34
|
+
|
35
|
+
restart.condition(:cpu_usage) do |c|
|
36
|
+
c.above = 50 # percent
|
37
|
+
c.times = 5
|
44
38
|
end
|
45
39
|
end
|
46
40
|
end
|
data/ext/god/extconf.rb
CHANGED
@@ -1,8 +1,55 @@
|
|
1
1
|
require 'mkmf'
|
2
2
|
|
3
|
+
fail = false
|
4
|
+
|
5
|
+
def create_dummy_makefile
|
6
|
+
File.open("Makefile", 'w') do |f|
|
7
|
+
f.puts "all:"
|
8
|
+
f.puts "install:"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
3
12
|
case RUBY_PLATFORM
|
4
13
|
when /bsd/i, /darwin/i
|
5
|
-
|
14
|
+
unless have_header('sys/event.h')
|
15
|
+
puts
|
16
|
+
puts "Missing 'sys/event.h' header"
|
17
|
+
fail = true
|
18
|
+
end
|
19
|
+
|
20
|
+
if fail
|
21
|
+
puts
|
22
|
+
puts "Events handler could not be compiled (see above error). Your god installation will not support event conditions."
|
23
|
+
create_dummy_makefile
|
24
|
+
else
|
25
|
+
create_makefile 'kqueue_handler_ext'
|
26
|
+
end
|
6
27
|
when /linux/i
|
7
|
-
|
28
|
+
unless have_header('linux/netlink.h')
|
29
|
+
puts
|
30
|
+
puts "Missing 'linux/netlink.h' header(s)"
|
31
|
+
puts "You may need to install a header package for your system"
|
32
|
+
fail = true
|
33
|
+
end
|
34
|
+
|
35
|
+
unless have_header('linux/connector.h') && have_header('linux/cn_proc.h')
|
36
|
+
puts
|
37
|
+
puts "Missing 'linux/connector.h', or 'linux/cn_proc.h' header(s)"
|
38
|
+
puts "These are only available in Linux kernel 2.6.15 and later (run `uname -a` to find yours)"
|
39
|
+
puts "You may need to install a header package for your system"
|
40
|
+
fail = true
|
41
|
+
end
|
42
|
+
|
43
|
+
if fail
|
44
|
+
puts
|
45
|
+
puts "Events handler could not be compiled (see above error). Your god installation will not support event conditions."
|
46
|
+
create_dummy_makefile
|
47
|
+
else
|
48
|
+
create_makefile 'netlink_handler_ext'
|
49
|
+
end
|
50
|
+
else
|
51
|
+
puts
|
52
|
+
puts "Unsupported platform '#{RUBY_PLATFORM}'. Supported platforms are BSD, DARWIN, and LINUX."
|
53
|
+
puts "Your god installation will not support event conditions."
|
54
|
+
create_dummy_makefile
|
8
55
|
end
|