god 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
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