god 0.8.0 → 0.9.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 +14 -0
- data/Rakefile +42 -26
- data/ext/god/kqueue_handler.c +6 -4
- data/ext/god/netlink_handler.c +6 -6
- data/god.gemspec +127 -151
- data/lib/god.rb +26 -5
- data/lib/god/cli/command.rb +1 -1
- data/lib/god/cli/run.rb +5 -5
- data/lib/god/compat19.rb +36 -0
- data/lib/god/contacts/prowl.rb +77 -0
- data/lib/god/contacts/scout.rb +64 -0
- data/lib/god/driver.rb +5 -0
- data/lib/god/logger.rb +8 -29
- data/lib/god/process.rb +8 -2
- data/lib/god/simple_logger.rb +7 -1
- data/lib/god/socket.rb +13 -2
- data/lib/god/sys_logger.rb +45 -0
- data/lib/god/watch.rb +2 -1
- data/test/configs/contact/contact.god +7 -1
- data/test/configs/task/logs/.placeholder +0 -0
- data/test/helper.rb +2 -1
- data/test/test_behavior.rb +1 -1
- data/test/test_logger.rb +1 -1
- data/test/test_prowl.rb +15 -0
- metadata +6 -27
- data/.gitignore +0 -8
- data/VERSION.yml +0 -5
- data/ideas/execve/execve.c +0 -29
- data/ideas/execve/extconf.rb +0 -11
- data/ideas/execve/go.rb +0 -8
- data/ideas/future.god +0 -82
- data/init/god +0 -42
- data/init/lsb_compliant_god +0 -109
- data/site/images/banner.jpg +0 -0
- data/site/images/bg.gif +0 -0
- data/site/images/bg_grey.gif +0 -0
- data/site/images/bullet.jpg +0 -0
- data/site/images/corner_green.gif +0 -0
- data/site/images/corner_green.psd +0 -0
- data/site/images/corner_pink.gif +0 -0
- data/site/images/god_logo.png +0 -0
- data/site/images/header_bg.gif +0 -0
- data/site/images/header_bg.jpg +0 -0
- data/site/images/red_dot.gif +0 -0
- data/site/images/top_bg.gif +0 -0
- data/site/index.html +0 -563
- data/site/install.html +0 -2
- data/site/javascripts/code_highlighter.js +0 -188
- data/site/javascripts/ruby.js +0 -18
- data/site/stylesheets/layout.css +0 -174
@@ -0,0 +1,45 @@
|
|
1
|
+
begin
|
2
|
+
require 'syslog'
|
3
|
+
|
4
|
+
# Ensure that Syslog is open
|
5
|
+
begin
|
6
|
+
Syslog.open('god')
|
7
|
+
rescue RuntimeError
|
8
|
+
Syslog.reopen('god')
|
9
|
+
end
|
10
|
+
|
11
|
+
Syslog.info("Syslog enabled.")
|
12
|
+
|
13
|
+
module God
|
14
|
+
|
15
|
+
class SysLogger
|
16
|
+
SYMBOL_EQUIVALENTS = { :fatal => Syslog::LOG_CRIT,
|
17
|
+
:error => Syslog::LOG_ERR,
|
18
|
+
:warn => Syslog::LOG_WARNING,
|
19
|
+
:info => Syslog::LOG_INFO,
|
20
|
+
:debug => Syslog::LOG_DEBUG }
|
21
|
+
|
22
|
+
# Set the log level
|
23
|
+
# +level+ is the Symbol level to set as maximum. One of:
|
24
|
+
# [:fatal | :error | :warn | :info | :debug ]
|
25
|
+
#
|
26
|
+
# Returns Nothing
|
27
|
+
def self.level=(level)
|
28
|
+
Syslog.mask = Syslog::LOG_UPTO(SYMBOL_EQUIVALENTS[level])
|
29
|
+
end
|
30
|
+
|
31
|
+
# Log a message to syslog.
|
32
|
+
# +level+ is the Symbol level of the message. One of:
|
33
|
+
# [:fatal | :error | :warn | :info | :debug ]
|
34
|
+
# +text+ is the String text of the message
|
35
|
+
#
|
36
|
+
# Returns Nothing
|
37
|
+
def self.log(level, text)
|
38
|
+
Syslog.log(SYMBOL_EQUIVALENTS[level], text)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
rescue Object => e
|
44
|
+
puts "Syslog could not be enabled: #{e.message}"
|
45
|
+
end
|
data/lib/god/watch.rb
CHANGED
@@ -13,7 +13,8 @@ module God
|
|
13
13
|
extend Forwardable
|
14
14
|
def_delegators :@process, :name, :uid, :gid, :start, :stop, :restart, :dir,
|
15
15
|
:name=, :uid=, :gid=, :start=, :stop=, :restart=, :dir=,
|
16
|
-
:pid_file, :pid_file=, :log, :log=, :log_cmd, :log_cmd=,
|
16
|
+
:pid_file, :pid_file=, :log, :log=, :log_cmd, :log_cmd=,
|
17
|
+
:err_log, :err_log=, :err_log_cmd, :err_log_cmd=, :alive?, :pid,
|
17
18
|
:unix_socket, :unix_socket=, :chroot, :chroot=, :env, :env=, :signal
|
18
19
|
#
|
19
20
|
def initialize
|
@@ -36,6 +36,12 @@ God.contact(:twitter) do |c|
|
|
36
36
|
c.group = 'developers'
|
37
37
|
end
|
38
38
|
|
39
|
+
God.contact(:prowl) do |c|
|
40
|
+
c.name = 'tom3'
|
41
|
+
c.apikey = 'd31c1f31f7af0f69e263c2f12167263127eab608'
|
42
|
+
c.group = 'developers'
|
43
|
+
end
|
44
|
+
|
39
45
|
God.watch do |w|
|
40
46
|
w.name = "contact"
|
41
47
|
w.interval = 5.seconds
|
@@ -65,7 +71,7 @@ God.watch do |w|
|
|
65
71
|
# start if process is not running
|
66
72
|
w.transition(:up, :start) do |on|
|
67
73
|
on.condition(:process_exits) do |c|
|
68
|
-
c.notify = {:contacts => ['tom2', 'foobar'], :priority => 1, :category => 'product'}
|
74
|
+
c.notify = {:contacts => ['tom2', 'tom3', 'foobar'], :priority => 1, :category => 'product'}
|
69
75
|
end
|
70
76
|
end
|
71
77
|
|
File without changes
|
data/test/helper.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'rubygems'
|
2
|
+
require File.join(File.dirname(__FILE__), *%w[.. lib god sys_logger])
|
2
3
|
require File.join(File.dirname(__FILE__), *%w[.. lib god])
|
3
4
|
God::EventHandler.load
|
4
5
|
|
@@ -122,7 +123,7 @@ end
|
|
122
123
|
class Object
|
123
124
|
class Bypass
|
124
125
|
instance_methods.each do |m|
|
125
|
-
undef_method m unless m =~ /^__/
|
126
|
+
undef_method m unless m =~ /^(__|object_id)/
|
126
127
|
end
|
127
128
|
|
128
129
|
def initialize(ref)
|
data/test/test_behavior.rb
CHANGED
data/test/test_logger.rb
CHANGED
data/test/test_prowl.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require File.dirname(__FILE__) + '/helper'
|
3
|
+
|
4
|
+
class TestProwl < Test::Unit::TestCase
|
5
|
+
def test_live_notify
|
6
|
+
prowl = God::Contacts::Prowl.new
|
7
|
+
prowl.name = "Prowly"
|
8
|
+
prowl.apikey = 'put_your_apikey_here'
|
9
|
+
|
10
|
+
Prowly.expects(:notify).returns(mock(:succeeded? => true))
|
11
|
+
|
12
|
+
prowl.notify("Test", Time.now, "Test", "Test", "")
|
13
|
+
assert_equal "sent prowl notification to #{prowl.name}", prowl.info
|
14
|
+
end
|
15
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: god
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tom Preston-Werner
|
@@ -23,12 +23,10 @@ extensions:
|
|
23
23
|
extra_rdoc_files:
|
24
24
|
- README.txt
|
25
25
|
files:
|
26
|
-
- .gitignore
|
27
26
|
- Announce.txt
|
28
27
|
- History.txt
|
29
28
|
- README.txt
|
30
29
|
- Rakefile
|
31
|
-
- VERSION.yml
|
32
30
|
- bin/god
|
33
31
|
- examples/events.god
|
34
32
|
- examples/gravatar.god
|
@@ -38,13 +36,6 @@ files:
|
|
38
36
|
- ext/god/kqueue_handler.c
|
39
37
|
- ext/god/netlink_handler.c
|
40
38
|
- god.gemspec
|
41
|
-
- ideas/execve/.DS_Store
|
42
|
-
- ideas/execve/execve.c
|
43
|
-
- ideas/execve/extconf.rb
|
44
|
-
- ideas/execve/go.rb
|
45
|
-
- ideas/future.god
|
46
|
-
- init/god
|
47
|
-
- init/lsb_compliant_god
|
48
39
|
- lib/god.rb
|
49
40
|
- lib/god/behavior.rb
|
50
41
|
- lib/god/behaviors/clean_pid_file.rb
|
@@ -53,6 +44,7 @@ files:
|
|
53
44
|
- lib/god/cli/command.rb
|
54
45
|
- lib/god/cli/run.rb
|
55
46
|
- lib/god/cli/version.rb
|
47
|
+
- lib/god/compat19.rb
|
56
48
|
- lib/god/condition.rb
|
57
49
|
- lib/god/conditions/always.rb
|
58
50
|
- lib/god/conditions/complex.rb
|
@@ -72,6 +64,8 @@ files:
|
|
72
64
|
- lib/god/contacts/campfire.rb
|
73
65
|
- lib/god/contacts/email.rb
|
74
66
|
- lib/god/contacts/jabber.rb
|
67
|
+
- lib/god/contacts/prowl.rb
|
68
|
+
- lib/god/contacts/scout.rb
|
75
69
|
- lib/god/contacts/twitter.rb
|
76
70
|
- lib/god/contacts/webhook.rb
|
77
71
|
- lib/god/dependency_graph.rb
|
@@ -89,6 +83,7 @@ files:
|
|
89
83
|
- lib/god/simple_logger.rb
|
90
84
|
- lib/god/socket.rb
|
91
85
|
- lib/god/sugar.rb
|
86
|
+
- lib/god/sys_logger.rb
|
92
87
|
- lib/god/system/portable_poller.rb
|
93
88
|
- lib/god/system/process.rb
|
94
89
|
- lib/god/system/slash_proc_poller.rb
|
@@ -96,23 +91,6 @@ files:
|
|
96
91
|
- lib/god/timeline.rb
|
97
92
|
- lib/god/trigger.rb
|
98
93
|
- lib/god/watch.rb
|
99
|
-
- site/images/banner.jpg
|
100
|
-
- site/images/bg.gif
|
101
|
-
- site/images/bg_grey.gif
|
102
|
-
- site/images/bullet.jpg
|
103
|
-
- site/images/corner_green.gif
|
104
|
-
- site/images/corner_green.psd
|
105
|
-
- site/images/corner_pink.gif
|
106
|
-
- site/images/god_logo.png
|
107
|
-
- site/images/header_bg.gif
|
108
|
-
- site/images/header_bg.jpg
|
109
|
-
- site/images/red_dot.gif
|
110
|
-
- site/images/top_bg.gif
|
111
|
-
- site/index.html
|
112
|
-
- site/install.html
|
113
|
-
- site/javascripts/code_highlighter.js
|
114
|
-
- site/javascripts/ruby.js
|
115
|
-
- site/stylesheets/layout.css
|
116
94
|
- test/configs/child_events/child_events.god
|
117
95
|
- test/configs/child_events/simple_server.rb
|
118
96
|
- test/configs/child_polls/child_polls.god
|
@@ -157,6 +135,7 @@ files:
|
|
157
135
|
- test/test_logger.rb
|
158
136
|
- test/test_metric.rb
|
159
137
|
- test/test_process.rb
|
138
|
+
- test/test_prowl.rb
|
160
139
|
- test/test_registry.rb
|
161
140
|
- test/test_socket.rb
|
162
141
|
- test/test_sugar.rb
|
data/.gitignore
DELETED
data/VERSION.yml
DELETED
data/ideas/execve/execve.c
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
#include "ruby.h"
|
2
|
-
|
3
|
-
static VALUE mKernel;
|
4
|
-
void Init_execve();
|
5
|
-
VALUE method_execve(VALUE self, VALUE cmd, VALUE env);
|
6
|
-
|
7
|
-
void Init_execve() {
|
8
|
-
mKernel = rb_const_get(rb_cObject, rb_intern("Kernel"));
|
9
|
-
rb_define_method(mKernel, "execve", method_execve, 2);
|
10
|
-
}
|
11
|
-
|
12
|
-
VALUE method_execve(VALUE self, VALUE r_cmd, VALUE r_env) {
|
13
|
-
char *shell = (char *)dln_find_exe("sh", 0);
|
14
|
-
char *arg[] = { "sh", "-c", StringValuePtr(r_cmd), (char *)0 };
|
15
|
-
|
16
|
-
struct RArray *env_array;
|
17
|
-
env_array = RARRAY(r_env);
|
18
|
-
char *env[env_array->len + 1];
|
19
|
-
|
20
|
-
int i;
|
21
|
-
for(i = 0; i < env_array->len; i++) {
|
22
|
-
env[i] = StringValuePtr(env_array->ptr[i]);
|
23
|
-
}
|
24
|
-
|
25
|
-
env[env_array->len] = (char *)0;
|
26
|
-
|
27
|
-
execve(shell, arg, env);
|
28
|
-
return Qnil;
|
29
|
-
}
|
data/ideas/execve/extconf.rb
DELETED
data/ideas/execve/go.rb
DELETED
data/ideas/future.god
DELETED
@@ -1,82 +0,0 @@
|
|
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::Contacts::Email.delivery_method = :smtp
|
10
|
-
God::Contacts::Email.server_settings = {}
|
11
|
-
|
12
|
-
God.contact(:email) do |c|
|
13
|
-
c.name = 'tom'
|
14
|
-
c.email = 'tom@powerset.com'
|
15
|
-
c.group = 'developers'
|
16
|
-
c.throttle = 30.minutes
|
17
|
-
end
|
18
|
-
|
19
|
-
God.watch do |w|
|
20
|
-
w.name = "local-3000"
|
21
|
-
w.interval = 5.seconds
|
22
|
-
w.start = "mongrel_rails start -P ./log/mongrel.pid -c #{RAILS_ROOT} -d"
|
23
|
-
w.stop = "mongrel_rails stop -P ./log/mongrel.pid -c #{RAILS_ROOT}"
|
24
|
-
w.pid_file = File.join(RAILS_ROOT, "log/mongrel.pid")
|
25
|
-
|
26
|
-
# clean pid files before start if necessary
|
27
|
-
w.behavior(:clean_pid_file)
|
28
|
-
|
29
|
-
# determine the state on startup
|
30
|
-
w.transition(:init, { true => :up, false => :start }) do |on|
|
31
|
-
on.condition(:process_running) do |c|
|
32
|
-
c.running = true
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
# determine when process has finished starting
|
37
|
-
w.transition([:start, :restart], :up) do |on|
|
38
|
-
on.condition(:process_running) do |c|
|
39
|
-
c.running = true
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
# start if process is not running
|
44
|
-
w.transition(:up, :start) do |on|
|
45
|
-
on.condition(:process_exits)
|
46
|
-
end
|
47
|
-
|
48
|
-
# restart if memory or cpu is too high
|
49
|
-
w.transition(:up, :restart) do |on|
|
50
|
-
on.condition(:memory_usage) do |c|
|
51
|
-
c.interval = 20
|
52
|
-
c.above = 50.megabytes
|
53
|
-
c.times = [3, 5]
|
54
|
-
end
|
55
|
-
|
56
|
-
on.condition(:cpu_usage) do |c|
|
57
|
-
c.interval = 10
|
58
|
-
c.above = 10.percent
|
59
|
-
c.times = [3, 5]
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
# lifecycle
|
64
|
-
w.lifecycle do |on|
|
65
|
-
on.condition(:flapping) do |c|
|
66
|
-
c.to_state = [:start, :restart]
|
67
|
-
c.times = 5
|
68
|
-
c.within = 30.seconds
|
69
|
-
c.transition = nil
|
70
|
-
c.retry = 60.seconds
|
71
|
-
c.giveup_tries = 5
|
72
|
-
c.notify = 'tom'
|
73
|
-
end
|
74
|
-
|
75
|
-
on.condition(:memory_usage) do |c|
|
76
|
-
c.interval = 20
|
77
|
-
c.above = 40.megabytes
|
78
|
-
c.times = [3, 5]
|
79
|
-
c.notify = 'tom'
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
data/init/god
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
#!/bin/bash
|
2
|
-
#
|
3
|
-
# god Startup script for god (http://god.rubyforge.org)
|
4
|
-
#
|
5
|
-
# chkconfig: - 85 15
|
6
|
-
# description: God is an easy to configure, easy to extend monitoring \
|
7
|
-
# framework written in Ruby.
|
8
|
-
#
|
9
|
-
|
10
|
-
CONF_DIR=/etc/god
|
11
|
-
|
12
|
-
RETVAL=0
|
13
|
-
|
14
|
-
# Go no further if config directory is missing.
|
15
|
-
[ -d "$CONF_DIR" ] || exit 0
|
16
|
-
|
17
|
-
case "$1" in
|
18
|
-
start)
|
19
|
-
# Create pid directory
|
20
|
-
ruby /usr/bin/god -c $CONF_DIR/master.conf
|
21
|
-
RETVAL=$?
|
22
|
-
;;
|
23
|
-
stop)
|
24
|
-
ruby /usr/bin/god terminate
|
25
|
-
RETVAL=$?
|
26
|
-
;;
|
27
|
-
restart)
|
28
|
-
ruby /usr/bin/god terminate
|
29
|
-
ruby /usr/bin/god -c $CONF_DIR/master.conf
|
30
|
-
RETVAL=$?
|
31
|
-
;;
|
32
|
-
status)
|
33
|
-
ruby /usr/bin/god status
|
34
|
-
RETVAL=$?
|
35
|
-
;;
|
36
|
-
*)
|
37
|
-
echo "Usage: god {start|stop|restart|status}"
|
38
|
-
exit 1
|
39
|
-
;;
|
40
|
-
esac
|
41
|
-
|
42
|
-
exit $RETVAL
|
data/init/lsb_compliant_god
DELETED
@@ -1,109 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
# see http://refspecs.freestandards.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html
|
4
|
-
|
5
|
-
PATH="/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin"
|
6
|
-
DESC="god daemon"
|
7
|
-
NAME="god"
|
8
|
-
DAEMON="/usr/bin/#{NAME}"
|
9
|
-
CONFIGFILE="/etc/god/god.conf"
|
10
|
-
PIDFILE="/var/run/#{NAME}.pid"
|
11
|
-
SCRIPTNAME="/etc/init.d/#{NAME}"
|
12
|
-
START_FLAGS="--no-syslog -P #{PIDFILE}"
|
13
|
-
|
14
|
-
ENV["PATH"] = PATH
|
15
|
-
|
16
|
-
def read_pid
|
17
|
-
begin
|
18
|
-
@pid = File.read(PIDFILE).to_i
|
19
|
-
@pid = nil if @pid == 0
|
20
|
-
rescue
|
21
|
-
@pid = nil
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def kill(code)
|
26
|
-
Process.kill(code, @pid)
|
27
|
-
true
|
28
|
-
rescue
|
29
|
-
false
|
30
|
-
end
|
31
|
-
|
32
|
-
def running?
|
33
|
-
@pid && kill(0)
|
34
|
-
end
|
35
|
-
|
36
|
-
def dead?
|
37
|
-
@pid && !kill(0)
|
38
|
-
end
|
39
|
-
|
40
|
-
def start
|
41
|
-
if running?
|
42
|
-
puts "already running (#{@pid})"
|
43
|
-
exit
|
44
|
-
end
|
45
|
-
|
46
|
-
if dead?
|
47
|
-
clean_pid
|
48
|
-
end
|
49
|
-
|
50
|
-
puts "starting #{NAME}"
|
51
|
-
system("#{DAEMON} -c #{CONFIGFILE} #{START_FLAGS}")
|
52
|
-
end
|
53
|
-
|
54
|
-
def stop
|
55
|
-
if not running?
|
56
|
-
puts "not running"
|
57
|
-
exit
|
58
|
-
end
|
59
|
-
|
60
|
-
system("god quit")
|
61
|
-
end
|
62
|
-
|
63
|
-
def restart
|
64
|
-
if running?
|
65
|
-
stop
|
66
|
-
read_pid
|
67
|
-
end
|
68
|
-
start
|
69
|
-
end
|
70
|
-
|
71
|
-
def force_reload
|
72
|
-
if running?
|
73
|
-
restart
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
def clean_pid
|
78
|
-
File.delete(PIDFILE)
|
79
|
-
end
|
80
|
-
|
81
|
-
read_pid
|
82
|
-
case ARGV[0]
|
83
|
-
when 'start'
|
84
|
-
start
|
85
|
-
when 'stop'
|
86
|
-
stop
|
87
|
-
when 'restart'
|
88
|
-
if not running?
|
89
|
-
start
|
90
|
-
else
|
91
|
-
restart
|
92
|
-
end
|
93
|
-
when 'force-reload'
|
94
|
-
force_reload
|
95
|
-
when 'status'
|
96
|
-
if running?
|
97
|
-
puts "running (#{@pid})"
|
98
|
-
elsif dead?
|
99
|
-
puts "dead (#{@pid})"
|
100
|
-
exit!(1)
|
101
|
-
else
|
102
|
-
puts "not running"
|
103
|
-
exit!(3)
|
104
|
-
end
|
105
|
-
else
|
106
|
-
puts "Usage: #{SCRIPTNAME} start|stop|restart|force-reload|status"
|
107
|
-
end
|
108
|
-
|
109
|
-
exit
|