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.
Files changed (50) hide show
  1. data/History.txt +14 -0
  2. data/Rakefile +42 -26
  3. data/ext/god/kqueue_handler.c +6 -4
  4. data/ext/god/netlink_handler.c +6 -6
  5. data/god.gemspec +127 -151
  6. data/lib/god.rb +26 -5
  7. data/lib/god/cli/command.rb +1 -1
  8. data/lib/god/cli/run.rb +5 -5
  9. data/lib/god/compat19.rb +36 -0
  10. data/lib/god/contacts/prowl.rb +77 -0
  11. data/lib/god/contacts/scout.rb +64 -0
  12. data/lib/god/driver.rb +5 -0
  13. data/lib/god/logger.rb +8 -29
  14. data/lib/god/process.rb +8 -2
  15. data/lib/god/simple_logger.rb +7 -1
  16. data/lib/god/socket.rb +13 -2
  17. data/lib/god/sys_logger.rb +45 -0
  18. data/lib/god/watch.rb +2 -1
  19. data/test/configs/contact/contact.god +7 -1
  20. data/test/configs/task/logs/.placeholder +0 -0
  21. data/test/helper.rb +2 -1
  22. data/test/test_behavior.rb +1 -1
  23. data/test/test_logger.rb +1 -1
  24. data/test/test_prowl.rb +15 -0
  25. metadata +6 -27
  26. data/.gitignore +0 -8
  27. data/VERSION.yml +0 -5
  28. data/ideas/execve/execve.c +0 -29
  29. data/ideas/execve/extconf.rb +0 -11
  30. data/ideas/execve/go.rb +0 -8
  31. data/ideas/future.god +0 -82
  32. data/init/god +0 -42
  33. data/init/lsb_compliant_god +0 -109
  34. data/site/images/banner.jpg +0 -0
  35. data/site/images/bg.gif +0 -0
  36. data/site/images/bg_grey.gif +0 -0
  37. data/site/images/bullet.jpg +0 -0
  38. data/site/images/corner_green.gif +0 -0
  39. data/site/images/corner_green.psd +0 -0
  40. data/site/images/corner_pink.gif +0 -0
  41. data/site/images/god_logo.png +0 -0
  42. data/site/images/header_bg.gif +0 -0
  43. data/site/images/header_bg.jpg +0 -0
  44. data/site/images/red_dot.gif +0 -0
  45. data/site/images/top_bg.gif +0 -0
  46. data/site/index.html +0 -563
  47. data/site/install.html +0 -2
  48. data/site/javascripts/code_highlighter.js +0 -188
  49. data/site/javascripts/ruby.js +0 -18
  50. 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
@@ -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=, :alive?, :pid,
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
@@ -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)
@@ -12,7 +12,7 @@ class TestBehavior < Test::Unit::TestCase
12
12
  end
13
13
 
14
14
  def test_complain
15
- Syslog.expects(:err).with('foo')
15
+ SysLogger.expects(:log).with(:error, 'foo')
16
16
  assert !Behavior.allocate.bypass.complain('foo')
17
17
  end
18
18
  end
@@ -19,7 +19,7 @@ class TestLogger < Test::Unit::TestCase
19
19
  end
20
20
 
21
21
  def test_log_should_send_to_syslog
22
- Syslog.expects(:crit).with('foo')
22
+ SysLogger.expects(:log).with(:fatal, 'foo')
23
23
  @log.log(stub(:name => 'foo'), :fatal, "foo")
24
24
  end
25
25
 
@@ -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.8.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
@@ -1,8 +0,0 @@
1
- coverage
2
- pkg
3
- *.log
4
- logs
5
- *.rbc
6
- *~
7
- .*.sw?
8
- .DS_Store
@@ -1,5 +0,0 @@
1
- ---
2
- :major: 0
3
- :minor: 8
4
- :build:
5
- :patch: 0
@@ -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
- }
@@ -1,11 +0,0 @@
1
- # Loads mkmf which is used to make makefiles for Ruby extensions
2
- require 'mkmf'
3
-
4
- # Give it a name
5
- extension_name = 'execve'
6
-
7
- # The destination
8
- dir_config(extension_name)
9
-
10
- # Do the work
11
- create_makefile(extension_name)
@@ -1,8 +0,0 @@
1
- require 'execve'
2
-
3
- my_env = ENV.to_hash.merge('HOME' => '/foo')
4
- # my_env = ENV.to_hash
5
-
6
- env = my_env.keys.inject([]) { |acc, k| acc << "#{k}=#{my_env[k]}"; acc }
7
-
8
- execve(%Q{ruby -e "puts ENV['HOME']"}, env)
@@ -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
@@ -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