Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Remove all trailing whitespace from the project.

  • Loading branch information...
commit 4530542c239e2a28b4e68a1c8273fe747a772440 1 parent dace5ba
@mojombo authored
Showing with 1,587 additions and 1,587 deletions.
  1. +6 −6 Announce.txt
  2. +2 −2 History.txt
  3. +1 −1  LICENSE
  4. +1 −1  README.md
  5. +20 −20 bin/god
  6. +1 −1  doc/god.asciidoc
  7. +9 −9 examples/events.god
  8. +7 −7 examples/gravatar.god
  9. +8 −8 examples/single.god
  10. +3 −3 ext/god/extconf.rb
  11. +18 −18 ext/god/kqueue_handler.c
  12. +27 −27 ext/god/netlink_handler.c
  13. BIN  ideas/execve/.DS_Store
  14. +5 −5 ideas/execve/execve.c
  15. +1 −1  ideas/execve/extconf.rb
  16. +8 −8 ideas/future.god
  17. +2 −2 init/god
  18. +77 −77 lib/god.rb
  19. +14 −14 lib/god/behavior.rb
  20. +5 −5 lib/god/behaviors/clean_pid_file.rb
  21. +10 −10 lib/god/behaviors/clean_unix_socket.rb
  22. +12 −12 lib/god/behaviors/notify_when_flapping.rb
  23. +38 −38 lib/god/cli/command.rb
  24. +33 −33 lib/god/cli/run.rb
  25. +6 −6 lib/god/cli/version.rb
  26. +1 −1  lib/god/compat19.rb
  27. +21 −21 lib/god/condition.rb
  28. +5 −5 lib/god/conditions/always.rb
  29. +18 −18 lib/god/conditions/complex.rb
  30. +14 −14 lib/god/conditions/cpu_usage.rb
  31. +8 −8 lib/god/conditions/degrading_lambda.rb
  32. +5 −5 lib/god/conditions/disk_usage.rb
  33. +23 −23 lib/god/conditions/flapping.rb
  34. +2 −2 lib/god/conditions/http_response_code.rb
  35. +2 −2 lib/god/conditions/lambda.rb
  36. +13 −13 lib/god/conditions/memory_usage.rb
  37. +12 −12 lib/god/conditions/process_exits.rb
  38. +10 −10 lib/god/conditions/process_running.rb
  39. +10 −10 lib/god/conditions/tries.rb
  40. +10 −10 lib/god/configurable.rb
  41. +20 −20 lib/god/contact.rb
  42. +1 −1  lib/god/contacts/jabber.rb
  43. +11 −11 lib/god/driver.rb
  44. +9 −9 lib/god/errors.rb
  45. +19 −19 lib/god/event_handler.rb
  46. +3 −3 lib/god/event_handlers/dummy_handler.rb
  47. +3 −3 lib/god/event_handlers/kqueue_handler.rb
  48. +2 −2 lib/god/event_handlers/netlink_handler.rb
  49. +13 −13 lib/god/logger.rb
  50. +12 −12 lib/god/metric.rb
  51. +50 −50 lib/god/process.rb
  52. +7 −7 lib/god/registry.rb
  53. +13 −13 lib/god/simple_logger.rb
  54. +11 −11 lib/god/socket.rb
  55. +15 −15 lib/god/sugar.rb
  56. +1 −1  lib/god/sys_logger.rb
  57. +8 −8 lib/god/system/portable_poller.rb
  58. +8 −8 lib/god/system/process.rb
  59. +12 −12 lib/god/system/slash_proc_poller.rb
  60. +91 −91 lib/god/task.rb
  61. +5 −5 lib/god/timeline.rb
  62. +11 −11 lib/god/trigger.rb
  63. +43 −43 lib/god/watch.rb
  64. +60 −60 site/index.html
  65. +1 −1  site/install.html
  66. +188 −188 site/javascripts/code_highlighter.js
  67. +1 −1  site/javascripts/ruby.js
  68. +1 −1  site/stylesheets/layout.css
  69. +5 −5 test/configs/child_events/child_events.god
  70. +1 −1  test/configs/child_events/simple_server.rb
  71. +4 −4 test/configs/child_polls/child_polls.god
  72. +4 −4 test/configs/child_polls/simple_server.rb
  73. +7 −7 test/configs/complex/complex.god
  74. +1 −1  test/configs/complex/simple_server.rb
  75. +1 −1  test/configs/contact/contact.god
  76. +1 −1  test/configs/contact/simple_server.rb
  77. +5 −5 test/configs/daemon_events/daemon_events.god
  78. +1 −1  test/configs/daemon_events/simple_server.rb
  79. +1 −1  test/configs/daemon_events/simple_server_stop.rb
  80. +3 −3 test/configs/daemon_polls/daemon_polls.god
  81. +1 −1  test/configs/daemon_polls/simple_server.rb
  82. +3 −3 test/configs/degrading_lambda/degrading_lambda.god
  83. +1 −1  test/configs/keepalive/keepalive.rb
  84. +2 −2 test/configs/lifecycle/lifecycle.god
  85. +6 −6 test/configs/matias/matias.god
  86. +7 −7 test/configs/real.rb
  87. +2 −2 test/configs/running_load/running_load.god
  88. +1 −1  test/configs/stop_options/simple_server.rb
  89. +1 −1  test/configs/stress/simple_server.rb
  90. +2 −2 test/configs/stress/stress.god
  91. +5 −5 test/configs/task/task.god
  92. +7 −7 test/configs/test.rb
  93. +7 −7 test/helper.rb
  94. +3 −3 test/test_behavior.rb
  95. +1 −1  test/test_campfire.rb
  96. +10 −10 test/test_condition.rb
  97. +12 −12 test/test_conditions_disk_usage.rb
  98. +15 −15 test/test_conditions_http_response_code.rb
  99. +7 −7 test/test_conditions_process_running.rb
  100. +1 −1  test/test_conditions_tries.rb
  101. +19 −19 test/test_contact.rb
  102. +2 −2 test/test_driver.rb
  103. +12 −12 test/test_event_handler.rb
  104. +99 −99 test/test_god.rb
  105. +4 −4 test/test_handlers_kqueue_handler.rb
  106. +1 −1  test/test_jabber.rb
  107. +17 −17 test/test_logger.rb
  108. +16 −16 test/test_metric.rb
  109. +40 −40 test/test_process.rb
  110. +1 −1  test/test_prowl.rb
  111. +2 −2 test/test_registry.rb
  112. +3 −3 test/test_socket.rb
  113. +7 −7 test/test_sugar.rb
  114. +1 −1  test/test_system_portable_poller.rb
  115. +5 −5 test/test_system_process.rb
  116. +55 −55 test/test_task.rb
  117. +8 −8 test/test_timeline.rb
  118. +16 −16 test/test_trigger.rb
  119. +64 −64 test/test_watch.rb
View
12 Announce.txt
@@ -52,7 +52,7 @@ EXAMPLE
The easiest way to understand how god will make your life better is by looking at a sample config file. The following configuration file is what I use at gravatar.com to keep the mongrels running:
# run with: god -c /path/to/gravatar.god
-#
+#
# This is the actual config file used to keep the mongrels of
# gravatar.com running.
@@ -61,7 +61,7 @@ RAILS_ROOT = "/Users/tom/dev/gravatar2"
%w{8200 8201 8202}.each do |port|
God.watch do |w|
w.name = "gravatar2-mongrel-#{port}"
- w.interval = 30.seconds # default
+ w.interval = 30.seconds # default
w.start = "mongrel_rails start -c #{RAILS_ROOT} -p #{port} \
-P #{RAILS_ROOT}/log/mongrel.#{port}.pid -d"
w.stop = "mongrel_rails stop -P #{RAILS_ROOT}/log/mongrel.#{port}.pid"
@@ -69,7 +69,7 @@ RAILS_ROOT = "/Users/tom/dev/gravatar2"
w.start_grace = 10.seconds
w.restart_grace = 10.seconds
w.pid_file = File.join(RAILS_ROOT, "log/mongrel.#{port}.pid")
-
+
w.behavior(:clean_pid_file)
w.start_if do |start|
@@ -78,19 +78,19 @@ RAILS_ROOT = "/Users/tom/dev/gravatar2"
c.running = false
end
end
-
+
w.restart_if do |restart|
restart.condition(:memory_usage) do |c|
c.above = 150.megabytes
c.times = [3, 5] # 3 out of 5 intervals
end
-
+
restart.condition(:cpu_usage) do |c|
c.above = 50.percent
c.times = 5
end
end
-
+
# lifecycle
w.lifecycle do |on|
on.condition(:flapping) do |c|
View
4 History.txt
@@ -135,7 +135,7 @@
* Major Enhancements
* Enable sending of arbitrary signals to a task or group via `god signal`
* Bug Fixes
- * setup logging *after* loading a given config file when daemonized.
+ * setup logging *after* loading a given config file when daemonized.
enables logging to the 'God.log_file' specified in a config file. [github.com/jnewland]
* New Conditions
* FileMtime < PollCondition - trigger on file mtime durations [github.com/jwilkins]
@@ -290,7 +290,7 @@
* Minor Enhancement
* Allow extra args to pass through to config file
-
+
== 0.5.1 / 2007-10-08
* Bug Fixes
View
2  LICENSE
@@ -19,4 +19,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
View
2  README.md
@@ -60,4 +60,4 @@ The best way to get your changes merged back into core is as follows:
License
-------
-See LICENSE file.
+See LICENSE file.
View
40 bin/god
@@ -20,13 +20,13 @@ begin
Usage:
Starting:
god [-c <config file>] [-p <port> | -b] [-P <file>] [-l <file>] [-D]
-
+
Querying:
god <command> <argument> [-p <port>]
god <command> [-p <port>]
god -v
god -V (must be run as root to be accurate on Linux)
-
+
Commands:
start <task or group name> start task or group
restart <task or group name> restart task or group
@@ -41,70 +41,70 @@ begin
quit stop god
terminate stop god and all tasks
check run self diagnostic
-
+
Options:
EOF
-
+
opts.on("-cCONFIG", "--config-file CONFIG", "Configuration file") do |x|
options[:config] = x
end
-
+
opts.on("-pPORT", "--port PORT", "Communications port (default 17165)") do |x|
options[:port] = x
end
-
+
opts.on("-b", "--auto-bind", "Auto-bind to an unused port number") do
options[:port] = "0"
end
-
+
opts.on("-PFILE", "--pid FILE", "Where to write the PID file") do |x|
options[:pid] = x
end
-
+
opts.on("-lFILE", "--log FILE", "Where to write the log file") do |x|
options[:log] = x
end
-
+
opts.on("-D", "--no-daemonize", "Don't daemonize") do
options[:daemonize] = false
end
-
+
opts.on("-v", "--version", "Print the version number and exit") do
options[:version] = true
end
-
+
opts.on("-V", "Print extended version and build information") do
options[:info] = true
end
-
+
opts.on("--log-level LEVEL", "Log level [debug|info|warn|error|fatal]") do |x|
options[:log_level] = x.to_sym
end
-
+
opts.on("--no-syslog", "Disable output to syslog") do
options[:syslog] = false
end
-
+
opts.on("--attach PID", "Quit god when the attached process dies") do |x|
options[:attach] = x
end
-
+
opts.on("--no-events", "Disable the event system") do
options[:events] = false
end
-
+
opts.on("--bleakhouse", "Enable bleakhouse profiling") do
options[:bleakhouse] = true
end
end
-
+
opts.parse!
-
+
# validate
if options[:log_level] && ![:debug, :info, :warn, :error, :fatal].include?(options[:log_level])
abort("Invalid log level '#{options[:log_level]}'")
end
-
+
# dispatch
if !options[:config] && options[:version]
require 'god'
@@ -129,4 +129,4 @@ rescue Exception => e
puts e.message
puts e.backtrace.join("\n")
end
-end
+end
View
2  doc/god.asciidoc
@@ -1395,4 +1395,4 @@ Extend God with your own Conditions
-----------------------------------
God was designed from the start to allow you to easily write your own custom
-conditions, making it simple to add tests that are application specific.
+conditions, making it simple to add tests that are application specific.
View
18 examples/events.god
@@ -14,23 +14,23 @@ RAILS_ROOT = ENV['GOD_TEST_RAILS_ROOT']
w.stop = "mongrel_rails stop -P #{RAILS_ROOT}/log/mongrel.#{port}.pid -c #{RAILS_ROOT}"
w.pid_file = File.join(RAILS_ROOT, "log/mongrel.#{port}.pid")
w.log = File.join(RAILS_ROOT, "log/commands.#{port}.log")
-
+
# clean pid files before start if necessary
w.behavior(:clean_pid_file)
-
+
# determine the state on startup
w.transition(:init, { true => :up, false => :start }) do |on|
on.condition(:process_running) do |c|
c.running = true
end
end
-
+
# determine when process has finished starting
w.transition([:start, :restart], :up) do |on|
on.condition(:process_running) do |c|
c.running = true
end
-
+
# failsafe
on.condition(:tries) do |c|
c.times = 8
@@ -43,7 +43,7 @@ RAILS_ROOT = ENV['GOD_TEST_RAILS_ROOT']
w.transition(:up, :start) do |on|
on.condition(:process_exits)
end
-
+
# restart if memory or cpu is too high
w.transition(:up, :restart) do |on|
on.condition(:memory_usage) do |c|
@@ -51,13 +51,13 @@ RAILS_ROOT = ENV['GOD_TEST_RAILS_ROOT']
c.above = 50.megabytes
c.times = [3, 5]
end
-
+
on.condition(:cpu_usage) do |c|
c.interval = 10
c.above = 10.percent
c.times = 5
end
-
+
on.condition(:http_response_code) do |c|
c.host = 'localhost'
c.port = port
@@ -67,7 +67,7 @@ RAILS_ROOT = ENV['GOD_TEST_RAILS_ROOT']
c.times = [3, 5]
end
end
-
+
# lifecycle
w.lifecycle do |on|
on.condition(:flapping) do |c|
@@ -81,4 +81,4 @@ RAILS_ROOT = ENV['GOD_TEST_RAILS_ROOT']
end
end
end
-end
+end
View
14 examples/gravatar.god
@@ -1,5 +1,5 @@
# run with: god -c /path/to/gravatar.god
-#
+#
# This is the actual config file used to keep the mongrels of
# gravatar.com running.
@@ -8,7 +8,7 @@ RAILS_ROOT = "/Users/tom/dev/gravatar2"
%w{8200 8201 8202}.each do |port|
God.watch do |w|
w.name = "gravatar2-mongrel-#{port}"
- w.interval = 30.seconds # default
+ w.interval = 30.seconds # default
w.start = "mongrel_rails start -c #{RAILS_ROOT} -p #{port} \
-P #{RAILS_ROOT}/log/mongrel.#{port}.pid -d"
w.stop = "mongrel_rails stop -P #{RAILS_ROOT}/log/mongrel.#{port}.pid"
@@ -16,7 +16,7 @@ RAILS_ROOT = "/Users/tom/dev/gravatar2"
w.start_grace = 10.seconds
w.restart_grace = 10.seconds
w.pid_file = File.join(RAILS_ROOT, "log/mongrel.#{port}.pid")
-
+
w.behavior(:clean_pid_file)
w.start_if do |start|
@@ -25,19 +25,19 @@ RAILS_ROOT = "/Users/tom/dev/gravatar2"
c.running = false
end
end
-
+
w.restart_if do |restart|
restart.condition(:memory_usage) do |c|
c.above = 150.megabytes
c.times = [3, 5] # 3 out of 5 intervals
end
-
+
restart.condition(:cpu_usage) do |c|
c.above = 50.percent
c.times = 5
end
end
-
+
# lifecycle
w.lifecycle do |on|
on.condition(:flapping) do |c|
@@ -51,4 +51,4 @@ RAILS_ROOT = "/Users/tom/dev/gravatar2"
end
end
end
-end
+end
View
16 examples/single.god
@@ -7,23 +7,23 @@ God.watch do |w|
w.stop = "mongrel_rails stop -P #{RAILS_ROOT}/log/mongrel.pid"
w.restart = "mongrel_rails restart -P #{RAILS_ROOT}/log/mongrel.pid"
w.pid_file = File.join(RAILS_ROOT, "log/mongrel.pid")
-
+
# clean pid files before start if necessary
w.behavior(:clean_pid_file)
-
+
# determine the state on startup
w.transition(:init, { true => :up, false => :start }) do |on|
on.condition(:process_running) do |c|
c.running = true
end
end
-
+
# determine when process has finished starting
w.transition([:start, :restart], :up) do |on|
on.condition(:process_running) do |c|
c.running = true
end
-
+
# failsafe
on.condition(:tries) do |c|
c.times = 5
@@ -35,7 +35,7 @@ God.watch do |w|
w.transition(:up, :start) do |on|
on.condition(:process_exits)
end
-
+
# restart if memory or cpu is too high
w.transition(:up, :restart) do |on|
on.condition(:memory_usage) do |c|
@@ -43,14 +43,14 @@ God.watch do |w|
c.above = 50.megabytes
c.times = [3, 5]
end
-
+
on.condition(:cpu_usage) do |c|
c.interval = 10
c.above = 10.percent
c.times = [3, 5]
end
end
-
+
# lifecycle
w.lifecycle do |on|
on.condition(:flapping) do |c|
@@ -63,4 +63,4 @@ God.watch do |w|
c.retry_within = 2.hours
end
end
-end
+end
View
6 ext/god/extconf.rb
@@ -16,7 +16,7 @@ def create_dummy_makefile
puts "Missing 'sys/event.h' header"
fail = true
end
-
+
if fail
puts
puts "Events handler could not be compiled (see above error). Your god installation will not support event conditions."
@@ -31,7 +31,7 @@ def create_dummy_makefile
puts "You may need to install a header package for your system"
fail = true
end
-
+
unless have_header('linux/connector.h') && have_header('linux/cn_proc.h')
puts
puts "Missing 'linux/connector.h', or 'linux/cn_proc.h' header(s)"
@@ -39,7 +39,7 @@ def create_dummy_makefile
puts "You may need to install a header package for your system"
fail = true
end
-
+
if fail
puts
puts "Events handler could not be compiled (see above error). Your god installation will not support event conditions."
View
36 ext/god/kqueue_handler.c
@@ -31,11 +31,11 @@ kqh_event_mask(VALUE klass, VALUE sym)
} else {
rb_raise(rb_eNotImpError, "Event `%s` not implemented", rb_id2name(id));
}
-
+
return Qnil;
}
-
+
VALUE
kqh_monitor_process(VALUE klass, VALUE pid, VALUE mask)
{
@@ -43,18 +43,18 @@ kqh_monitor_process(VALUE klass, VALUE pid, VALUE mask)
ID event;
(void)event; //!< Silence warning about unused var, should be removed?
-
+
u_int fflags = NUM2UINT(mask);
-
+
EV_SET(&new_event, FIX2UINT(pid), EVFILT_PROC,
EV_ADD | EV_ENABLE, fflags, 0, 0);
-
+
if (-1 == kevent(kq, &new_event, 1, NULL, 0, NULL)) {
rb_raise(rb_eStandardError, "%s", strerror(errno));
}
-
+
num_events = NUM_EVENTS;
-
+
return Qnil;
}
@@ -64,23 +64,23 @@ kqh_handle_events()
int nevents, i, num_to_fetch;
struct kevent *events;
fd_set read_set;
-
+
FD_ZERO(&read_set);
FD_SET(kq, &read_set);
-
+
// Don't actually run this method until we've got an event
- rb_thread_select(kq + 1, &read_set, NULL, NULL, NULL);
-
+ rb_thread_select(kq + 1, &read_set, NULL, NULL, NULL);
+
// Grabbing num_events once for thread safety
num_to_fetch = num_events;
events = (struct kevent*)malloc(num_to_fetch * sizeof(struct kevent));
-
+
if (NULL == events) {
rb_raise(rb_eStandardError, "%s", strerror(errno));
}
-
+
nevents = kevent(kq, NULL, 0, events, num_to_fetch, NULL);
-
+
if (-1 == nevents) {
free(events);
rb_raise(rb_eStandardError, "%s", strerror(errno));
@@ -93,7 +93,7 @@ kqh_handle_events()
}
}
}
-
+
free(events);
return INT2FIX(nevents);
@@ -103,17 +103,17 @@ void
Init_kqueue_handler_ext()
{
kq = kqueue();
-
+
if (kq == -1) {
rb_raise(rb_eStandardError, "kqueue initilization failed");
}
-
+
proc_exit = rb_intern("proc_exit");
proc_fork = rb_intern("proc_fork");
m_call = rb_intern("call");
m_size = rb_intern("size");
m_deregister = rb_intern("deregister");
-
+
mGod = rb_const_get(rb_cObject, rb_intern("God"));
cEventHandler = rb_const_get(mGod, rb_intern("EventHandler"));
cKQueueHandler = rb_define_class_under(mGod, "KQueueHandler", rb_cObject);
View
54 ext/god/netlink_handler.c
@@ -28,42 +28,42 @@ nlh_handle_events()
char buff[CONNECTOR_MAX_MSG_SIZE];
struct nlmsghdr *hdr;
struct proc_event *event;
-
+
VALUE extra_data;
-
+
fd_set fds;
-
+
FD_ZERO(&fds);
FD_SET(nl_sock, &fds);
-
+
if (0 > rb_thread_select(nl_sock + 1, &fds, NULL, NULL, NULL)) {
rb_raise(rb_eStandardError, "%s", strerror(errno));
}
-
+
/* If there were no events detected, return */
if (! FD_ISSET(nl_sock, &fds)) {
return INT2FIX(0);
}
-
- /* if there are events, make calls */
+
+ /* if there are events, make calls */
if (-1 == recv(nl_sock, buff, sizeof(buff), 0)) {
rb_raise(rb_eStandardError, "%s", strerror(errno));
}
-
+
hdr = (struct nlmsghdr *)buff;
-
+
if (NLMSG_ERROR == hdr->nlmsg_type) {
rb_raise(rb_eStandardError, "%s", strerror(errno));
- } else if (NLMSG_DONE == hdr->nlmsg_type) {
-
+ } else if (NLMSG_DONE == hdr->nlmsg_type) {
+
event = (struct proc_event *)((struct cn_msg *)NLMSG_DATA(hdr))->data;
-
+
switch(event->what) {
case PROC_EVENT_EXIT:
if (Qnil == rb_funcall(cEventHandler, m_watching_pid, 1, INT2FIX(event->event_data.exit.process_pid))) {
return INT2FIX(0);
}
-
+
extra_data = rb_hash_new();
rb_hash_aset(extra_data, ID2SYM(rb_intern("pid")), INT2FIX(event->event_data.exit.process_pid));
rb_hash_aset(extra_data, ID2SYM(rb_intern("exit_code")), INT2FIX(event->event_data.exit.exit_code));
@@ -72,18 +72,18 @@ nlh_handle_events()
rb_funcall(cEventHandler, m_call, 3, INT2FIX(event->event_data.exit.process_pid), ID2SYM(proc_exit), extra_data);
return INT2FIX(1);
-
+
case PROC_EVENT_FORK:
if (Qnil == rb_funcall(cEventHandler, m_watching_pid, 1, INT2FIX(event->event_data.fork.parent_pid))) {
return INT2FIX(0);
}
-
+
extra_data = rb_hash_new();
rb_hash_aset(extra_data, ID2SYM(rb_intern("parent_pid")), INT2FIX(event->event_data.fork.parent_pid));
rb_hash_aset(extra_data, ID2SYM(rb_intern("parent_thread_group_id")), INT2FIX(event->event_data.fork.parent_tgid));
rb_hash_aset(extra_data, ID2SYM(rb_intern("child_pid")), INT2FIX(event->event_data.fork.child_pid));
rb_hash_aset(extra_data, ID2SYM(rb_intern("child_thread_group_id")), INT2FIX(event->event_data.fork.child_tgid));
-
+
rb_funcall(cEventHandler, m_call, 3, INT2FIX(event->event_data.fork.parent_pid), ID2SYM(proc_fork), extra_data);
return INT2FIX(1);
@@ -94,7 +94,7 @@ nlh_handle_events()
break;
}
}
-
+
return Qnil;
}
@@ -109,23 +109,23 @@ connect_to_netlink()
char buff[NL_MESSAGE_SIZE];
struct nlmsghdr *hdr; /* for telling netlink what we want */
struct cn_msg *msg; /* the actual connector message */
-
+
/* connect to netlink socket */
nl_sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
-
+
if (-1 == nl_sock) {
rb_raise(rb_eStandardError, "%s", strerror(errno));
}
-
+
bzero(&sa_nl, sizeof(sa_nl));
sa_nl.nl_family = AF_NETLINK;
sa_nl.nl_groups = CN_IDX_PROC;
sa_nl.nl_pid = getpid();
-
+
if (-1 == bind(nl_sock, (struct sockaddr *)&sa_nl, sizeof(sa_nl))) {
rb_raise(rb_eStandardError, "%s", strerror(errno));
}
-
+
/* Fill header */
hdr = (struct nlmsghdr *)buff;
hdr->nlmsg_len = NL_MESSAGE_SIZE;
@@ -133,7 +133,7 @@ connect_to_netlink()
hdr->nlmsg_flags = 0;
hdr->nlmsg_seq = 0;
hdr->nlmsg_pid = getpid();
-
+
/* Fill message */
msg = (struct cn_msg *)NLMSG_DATA(hdr);
msg->id.idx = CN_IDX_PROC; /* Connecting to process information */
@@ -143,7 +143,7 @@ connect_to_netlink()
msg->flags = 0;
msg->len = sizeof(int);
*(int*)msg->data = PROC_CN_MCAST_LISTEN;
-
+
if (-1 == send(nl_sock, hdr, hdr->nlmsg_len, 0)) {
rb_raise(rb_eStandardError, "%s", strerror(errno));
}
@@ -151,17 +151,17 @@ connect_to_netlink()
void
Init_netlink_handler_ext()
-{
+{
proc_exit = rb_intern("proc_exit");
proc_fork = rb_intern("proc_fork");
m_call = rb_intern("call");
m_watching_pid = rb_intern("watching_pid?");
-
+
mGod = rb_const_get(rb_cObject, rb_intern("God"));
cEventHandler = rb_const_get(mGod, rb_intern("EventHandler"));
cNetlinkHandler = rb_define_class_under(mGod, "NetlinkHandler", rb_cObject);
rb_define_singleton_method(cNetlinkHandler, "handle_events", nlh_handle_events, 0);
-
+
connect_to_netlink();
}
View
BIN  ideas/execve/.DS_Store
Binary file not shown
View
10 ideas/execve/execve.c
@@ -12,18 +12,18 @@ void Init_execve() {
VALUE method_execve(VALUE self, VALUE r_cmd, VALUE r_env) {
char *shell = (char *)dln_find_exe("sh", 0);
char *arg[] = { "sh", "-c", StringValuePtr(r_cmd), (char *)0 };
-
+
struct RArray *env_array;
env_array = RARRAY(r_env);
char *env[env_array->len + 1];
-
+
int i;
for(i = 0; i < env_array->len; i++) {
env[i] = StringValuePtr(env_array->ptr[i]);
}
-
+
env[env_array->len] = (char *)0;
-
+
execve(shell, arg, env);
return Qnil;
-}
+}
View
2  ideas/execve/extconf.rb
@@ -8,4 +8,4 @@
dir_config(extension_name)
# Do the work
-create_makefile(extension_name)
+create_makefile(extension_name)
View
16 ideas/future.god
@@ -22,17 +22,17 @@ God.watch do |w|
w.start = "mongrel_rails start -P ./log/mongrel.pid -c #{RAILS_ROOT} -d"
w.stop = "mongrel_rails stop -P ./log/mongrel.pid -c #{RAILS_ROOT}"
w.pid_file = File.join(RAILS_ROOT, "log/mongrel.pid")
-
+
# clean pid files before start if necessary
w.behavior(:clean_pid_file)
-
+
# determine the state on startup
w.transition(:init, { true => :up, false => :start }) do |on|
on.condition(:process_running) do |c|
c.running = true
end
end
-
+
# determine when process has finished starting
w.transition([:start, :restart], :up) do |on|
on.condition(:process_running) do |c|
@@ -44,7 +44,7 @@ God.watch do |w|
w.transition(:up, :start) do |on|
on.condition(:process_exits)
end
-
+
# restart if memory or cpu is too high
w.transition(:up, :restart) do |on|
on.condition(:memory_usage) do |c|
@@ -52,14 +52,14 @@ God.watch do |w|
c.above = 50.megabytes
c.times = [3, 5]
end
-
+
on.condition(:cpu_usage) do |c|
c.interval = 10
c.above = 10.percent
c.times = [3, 5]
end
end
-
+
# lifecycle
w.lifecycle do |on|
on.condition(:flapping) do |c|
@@ -71,7 +71,7 @@ God.watch do |w|
c.giveup_tries = 5
c.notify = 'tom'
end
-
+
on.condition(:memory_usage) do |c|
c.interval = 20
c.above = 40.megabytes
@@ -79,4 +79,4 @@ God.watch do |w|
c.notify = 'tom'
end
end
-end
+end
View
4 init/god
@@ -5,7 +5,7 @@
# chkconfig: - 85 15
# description: God is an easy to configure, easy to extend monitoring \
# framework written in Ruby.
-#
+#
CONF_DIR=/etc/god
@@ -37,6 +37,6 @@ case "$1" in
echo "Usage: god {start|stop|restart|status}"
exit 1
;;
-esac
+esac
exit $RETVAL
View
154 lib/god.rb
@@ -111,15 +111,15 @@ def root_binding
module Kernel
alias_method :abort_orig, :abort
-
+
def abort(text = nil)
$run = false
applog(nil, :error, text) if text
exit(1)
end
-
+
alias_method :exit_orig, :exit
-
+
def exit(code = 0)
$run = false
exit_orig(code)
@@ -133,15 +133,15 @@ def safe_attr_accessor(*args)
if !self.running && self.inited
abort "God.#{arg} must be set before any Tasks are defined"
end
-
+
if self.running && self.inited
applog(nil, :warn, "God.#{arg} can't be set while god is running")
return
end
-
+
instance_variable_set(('@' + arg.to_s).intern, other)
end
-
+
define_method(arg) do
instance_variable_get(('@' + arg.to_s).intern)
end
@@ -159,7 +159,7 @@ module God
TERMINATE_TIMEOUT_DEFAULT = 10
STOP_TIMEOUT_DEFAULT = 10
STOP_SIGNAL_DEFAULT = 'TERM'
-
+
class << self
# user configurable
safe_attr_accessor :pid,
@@ -175,7 +175,7 @@ class << self
:socket_user,
:socket_group,
:socket_perms
-
+
# internal
attr_accessor :inited,
:running,
@@ -188,7 +188,7 @@ class << self
:contact_groups,
:main
end
-
+
# initialize class instance variables
self.pid = nil
self.host = nil
@@ -201,14 +201,14 @@ class << self
self.socket_user = nil
self.socket_group = nil
self.socket_perms = 0755
-
+
# Initialize internal data.
#
# Returns nothing
def self.internal_init
# only do this once
return if self.inited
-
+
# variable init
self.watches = {}
self.groups = {}
@@ -216,17 +216,17 @@ def self.internal_init
self.pending_watch_states = {}
self.contacts = {}
self.contact_groups = {}
-
+
# set defaults
self.log_buffer_size ||= LOG_BUFFER_SIZE_DEFAULT
self.port ||= DRB_PORT_DEFAULT
self.allow ||= DRB_ALLOW_DEFAULT
self.log_level ||= LOG_LEVEL_DEFAULT
self.terminate_timeout ||= TERMINATE_TIMEOUT_DEFAULT
-
+
# additional setup
self.setup
-
+
# log level
log_level_map = {:debug => Logger::DEBUG,
:info => Logger::INFO,
@@ -234,14 +234,14 @@ def self.internal_init
:error => Logger::ERROR,
:fatal => Logger::FATAL}
LOG.level = log_level_map[self.log_level]
-
+
# init has been executed
self.inited = true
-
+
# not yet running
self.running = false
end
-
+
# Instantiate a new, empty Watch object and pass it to the mandatory
# block. The attributes of the watch will be set by the configuration
# file.
@@ -254,7 +254,7 @@ def self.internal_init
def self.watch(&block)
self.task(Watch, &block)
end
-
+
# Instantiate a new, empty Task object and yield it to the mandatory
# block. The attributes of the task will be set by the configuration
# file.
@@ -266,13 +266,13 @@ def self.watch(&block)
# Returns nothing
def self.task(klass = Task)
self.internal_init
-
+
t = klass.new
yield(t)
-
+
# do the post-configuration
t.prepare
-
+
# if running, completely remove the watch (if necessary) to
# prepare for the reload
existing_watch = self.watches[t.name]
@@ -280,35 +280,35 @@ def self.task(klass = Task)
self.pending_watch_states[existing_watch.name] = existing_watch.state
self.unwatch(existing_watch)
end
-
+
# ensure the new watch has a unique name
if self.watches[t.name] || self.groups[t.name]
abort "Task name '#{t.name}' already used for a Task or Group"
end
-
+
# ensure watch is internally valid
t.valid? || abort("Task '#{t.name}' is not valid (see above)")
-
+
# add to list of watches
self.watches[t.name] = t
-
+
# add to pending watches
self.pending_watches << t
-
+
# add to group if specified
if t.group
# ensure group name hasn't been used for a watch already
if self.watches[t.group]
abort "Group name '#{t.group}' already used for a Task"
end
-
+
self.groups[t.group] ||= []
self.groups[t.group] << t
end
-
+
# register watch
t.register!
-
+
# log
if self.running && existing_watch
applog(t, :info, "#{t.name} Reloaded config")
@@ -316,7 +316,7 @@ def self.task(klass = Task)
applog(t, :info, "#{t.name} Loaded config")
end
end
-
+
# Unmonitor and remove the given watch from god.
# +watch+ is the Watch to remove
#
@@ -324,21 +324,21 @@ def self.task(klass = Task)
def self.unwatch(watch)
# unmonitor
watch.unmonitor unless watch.state == :unmonitored
-
+
# unregister
watch.unregister!
-
+
# remove from watches
self.watches.delete(watch.name)
-
+
# remove from groups
if watch.group
self.groups[watch.group].delete(watch)
end
-
+
applog(watch, :info, "#{watch.name} unwatched")
end
-
+
# Instantiate a new Contact of the given kind and send it to the block.
# Then prepare, validate, and record the Contact.
# +kind+ is the contact class specifier
@@ -351,7 +351,7 @@ def self.unwatch(watch)
# Returns nothing
def self.contact(kind)
self.internal_init
-
+
# verify contact has been loaded
if CONTACT_LOAD_SUCCESS[kind] == false
applog(nil, :error, "A required dependency for the #{kind} contact is unavailable.")
@@ -361,53 +361,53 @@ def self.contact(kind)
end
abort
end
-
+
# create the contact
begin
c = Contact.generate(kind)
rescue NoSuchContactError => e
abort e.message
end
-
+
# send to block so config can set attributes
yield(c) if block_given?
-
+
# call prepare on the contact
c.prepare
-
+
# remove existing contacts of same name
existing_contact = self.contacts[c.name]
if self.running && existing_contact
self.uncontact(existing_contact)
end
-
+
# warn and noop if the contact has been defined before
if self.contacts[c.name] || self.contact_groups[c.name]
applog(nil, :warn, "Contact name '#{c.name}' already used for a Contact or Contact Group")
return
end
-
+
# abort if the Contact is invalid, the Contact will have printed
# out its own error messages by now
unless Contact.valid?(c) && c.valid?
abort "Exiting on invalid contact"
end
-
+
# add to list of contacts
self.contacts[c.name] = c
-
+
# add to contact group if specified
if c.group
# ensure group name hasn't been used for a contact already
if self.contacts[c.group]
abort "Contact Group name '#{c.group}' already used for a Contact"
end
-
+
self.contact_groups[c.group] ||= []
self.contact_groups[c.group] << c
end
end
-
+
# Remove the given contact from god.
# +contact+ is the Contact to remove
#
@@ -418,7 +418,7 @@ def self.uncontact(contact)
self.contact_groups[contact.group].delete(contact)
end
end
-
+
# Control the lifecycle of the given task(s).
# +name+ is the name of a task/group (String)
# +command+ is the command to run (String)
@@ -433,9 +433,9 @@ def self.uncontact(contact)
def self.control(name, command)
# get the list of items
items = Array(self.watches[name] || self.groups[name]).dup
-
+
jobs = []
-
+
# do the command
case command
when "start", "monitor"
@@ -451,12 +451,12 @@ def self.control(name, command)
else
raise InvalidCommandError.new
end
-
+
jobs.each { |j| j.join }
-
+
items.map { |x| x.name }
end
-
+
# Unmonitor and stop all tasks.
#
# Returns true on success
@@ -468,15 +468,15 @@ def self.stop_all
w.action(:stop) if w.alive?
end
end
-
+
terminate_timeout.times do
return true unless self.watches.map { |name, w| w.alive? }.any?
sleep 1
end
-
+
return false
end
-
+
# Force the termination of god.
# * Clean up pid file if one exists
# * Stop DRb service
@@ -488,7 +488,7 @@ def self.terminate
self.server.stop if self.server
exit!(0)
end
-
+
# Gather the status of each task.
#
# Examples
@@ -503,7 +503,7 @@ def self.status
end
info
end
-
+
# Send a signal to each task.
# +name+ is the String name of the task or group
# +signal+ is the signal to send. e.g. HUP, 9
@@ -516,7 +516,7 @@ def self.signal(name, signal)
jobs.each { |j| j.join }
items.map { |x| x.name }
end
-
+
# Log lines for the given task since the specified time.
# +watch_name+ is the name of the task (may be abbreviated)
# +since+ is the Time since which to report log lines
@@ -585,18 +585,18 @@ def self.running_load(code, filename, action = nil)
rescue Exception => e
# don't ever let running_load take down god
errors << LOG.finish_capture
-
+
unless e.instance_of?(SystemExit)
errors << e.message << "\n"
errors << e.backtrace.join("\n")
end
end
-
+
jobs.each { |t| t.join }
[loaded_watches, errors, unloaded_watches]
end
-
+
# Load the given file(s) according to the given glob.
# +glob+ is the glob-enabled path to load
#
@@ -606,7 +606,7 @@ def self.load(glob)
Kernel.load f
end
end
-
+
def self.setup
if self.pid_file_directory
# pid file dir was specified, ensure it is created and writable
@@ -617,7 +617,7 @@ def self.setup
abort "Failed to create pid file directory: #{e.message}"
end
end
-
+
unless File.writable?(self.pid_file_directory)
abort "The pid file directory (#{self.pid_file_directory}) is not writable by #{Etc.getlogin}"
end
@@ -634,42 +634,42 @@ def self.setup
rescue Errno::EACCES => e
end
end
-
+
unless self.pid_file_directory
dirs = PID_FILE_DIRECTORY_DEFAULTS.map { |x| File.expand_path(x) }
abort "No pid file directory exists, could be created, or is writable at any of #{dirs.join(', ')}"
end
end
-
+
if God::Logger.syslog
LOG.info("Syslog enabled.")
else
LOG.info("Syslog disabled.")
end
-
+
applog(nil, :info, "Using pid file directory: #{self.pid_file_directory}")
end
-
+
# Initialize and startup the machinery that makes god work.
#
# Returns nothing
def self.start
self.internal_init
-
+
# instantiate server
self.server = Socket.new(self.port, self.socket_user, self.socket_group, self.socket_perms)
-
+
# start monitoring any watches set to autostart
self.watches.values.each { |w| w.monitor if w.autostart? }
-
+
# clear pending watches
self.pending_watches.clear
-
+
# mark as running
self.running = true
-
+
# don't exit
- self.main =
+ self.main =
Thread.new do
loop do
sleep 60
@@ -684,7 +684,7 @@ def self.join
def self.version
God::VERSION
end
-
+
# To be called on program exit to start god
#
# Returns nothing
@@ -692,9 +692,9 @@ def self.at_exit
self.start
self.join
end
-
+
# private
-
+
# Match a shortened pattern against a list of String candidates.
# The pattern is expanded into a regular expression by
# inserting .* between each character.
@@ -711,7 +711,7 @@ def self.at_exit
# Returns String[]:matched_elements
def self.pattern_match(pattern, list)
regex = pattern.split('').join('.*')
-
+
list.select do |item|
item =~ Regexp.new(regex)
end.sort_by { |x| x.size }
View
28 lib/god/behavior.rb
@@ -1,10 +1,10 @@
module God
-
+
class Behavior
include Configurable
-
+
attr_accessor :watch
-
+
# Generate a Behavior of the given kind. The proper class is found by camel casing the
# kind (which is given as an underscored symbol).
# +kind+ is the underscored symbol representing the class (e.g. foo_bar for God::Behaviors::FooBar)
@@ -16,31 +16,31 @@ def self.generate(kind, watch)
rescue NameError
raise NoSuchBehaviorError.new("No Behavior found with the class name God::Behaviors::#{sym}")
end
-
+
def valid?
true
end
-
+
#######
-
+
def before_start
end
-
+
def after_start
end
-
+
def before_restart
end
-
+
def after_restart
end
-
+
def before_stop
end
-
+
def after_stop
end
-
+
# Construct the friendly name of this Behavior, looks like:
#
# Behavior FooBar on Watch 'baz'
@@ -48,5 +48,5 @@ def friendly_name
"Behavior " + super + " on Watch '#{self.watch.name}'"
end
end
-
-end
+
+end
View
10 lib/god/behaviors/clean_pid_file.rb
@@ -1,21 +1,21 @@
module God
module Behaviors
-
+
class CleanPidFile < Behavior
def valid?
valid = true
valid &= complain("Attribute 'pid_file' must be specified", self) if self.watch.pid_file.nil?
valid
end
-
+
def before_start
File.delete(self.watch.pid_file)
-
+
"deleted pid file"
rescue
"no pid file to delete"
end
end
-
+
end
-end
+end
View
20 lib/god/behaviors/clean_unix_socket.rb
@@ -1,21 +1,21 @@
module God
module Behaviors
-
+
class CleanUnixSocket < Behavior
def valid?
valid = true
valid &= complain("Attribute 'unix_socket' must be specified", self) if self.watch.unix_socket.nil?
valid
- end
-
- def before_start
+ end
+
+ def before_start
File.delete(self.watch.unix_socket)
-
- "deleted unix socket"
- rescue
- "no unix socket to delete"
+
+ "deleted unix socket"
+ rescue
+ "no unix socket to delete"
end
end
-
+
end
-end
+end
View
24 lib/god/behaviors/notify_when_flapping.rb
@@ -1,44 +1,44 @@
module God
module Behaviors
-
+
class NotifyWhenFlapping < Behavior
- attr_accessor :failures # number of failures
+ attr_accessor :failures # number of failures
attr_accessor :seconds # number of seconds
attr_accessor :notifier # class to notify with
-
+
def initialize
super
@startup_times = []
end
-
+
def valid?
valid = true
valid &= complain("Attribute 'failures' must be specified", self) unless self.failures
valid &= complain("Attribute 'seconds' must be specified", self) unless self.seconds
valid &= complain("Attribute 'notifier' must be specified", self) unless self.notifier
-
+
# Must take one arg or variable args
unless self.notifier.respond_to?(:notify) and [1,-1].include?(self.notifier.method(:notify).arity)
valid &= complain("The 'notifier' must have a method 'notify' which takes 1 or variable args", self)
end
-
+
valid
end
-
+
def before_start
now = Time.now.to_i
@startup_times << now
check_for_flapping(now)
end
-
+
def before_restart
now = Time.now.to_i
@startup_times << now
check_for_flapping(now)
end
-
+
private
-
+
def check_for_flapping(now)
@startup_times.select! {|time| time >= now - self.seconds }
if @startup_times.length >= self.failures
@@ -46,6 +46,6 @@ def check_for_flapping(now)
end
end
end
-
+
end
-end
+end
View
76 lib/god/cli/command.rb
@@ -1,20 +1,20 @@
module God
module CLI
-
+
class Command
def initialize(command, options, args)
@command = command
@options = options
@args = args
-
+
dispatch
end
-
+
def setup
# connect to drb unix socket
DRb.start_service("druby://127.0.0.1:0")
@server = DRbObject.new(nil, God::Socket.socket(@options[:port]))
-
+
# ping server to ensure that it is responsive
begin
@server.ping
@@ -23,7 +23,7 @@ def setup
abort
end
end
-
+
def dispatch
if %w{load status signal log quit terminate}.include?(@command)
setup
@@ -71,13 +71,13 @@ def load_command
puts ' ' + w
end
end
-
+
unless errors.empty?
puts errors
exit(1)
end
end
-
+
def status_command
exitcode = 0
statuses = @server.status
@@ -87,13 +87,13 @@ def status_command
groups[g] ||= {}
groups[g][name] = status
end
-
+
if item = @args[1]
if single = statuses[item]
# specified task (0 -> up, 1 -> unmonitored, 2 -> other)
state = single[:state]
puts "#{item}: #{state}"
- exitcode = state == :up ? 0 : (state == :unmonitored ? 1 : 2)
+ exitcode = state == :up ? 0 : (state == :unmonitored ? 1 : 2)
elsif groups[item]
# specified group (0 -> up, N -> other)
puts "#{item}:"
@@ -118,21 +118,21 @@ def status_command
end
end
end
-
+
exit(exitcode)
end
-
+
def signal_command
# get the name of the watch/group
name = @args[1]
signal = @args[2]
-
+
puts "Sending signal '#{signal}' to '#{name}'"
-
+
t = Thread.new { loop { sleep(1); STDOUT.print('.'); STDOUT.flush; sleep(1) } }
-
+
watches = @server.signal(name, signal)
-
+
# output response
t.kill; STDOUT.puts
unless watches.empty?
@@ -144,17 +144,17 @@ def signal_command
puts 'No matching task or group'
end
end
-
+
def log_command
begin
Signal.trap('INT') { exit }
name = @args[1]
-
+
unless name
puts "You must specify a Task or Group name"
exit!
end
-
+
puts "Please wait..."
t = Time.at(0)
loop do
@@ -168,7 +168,7 @@ def log_command
puts "The server went away"
end
end
-
+
def quit_command
begin
@server.terminate
@@ -177,7 +177,7 @@ def quit_command
puts 'Stopped god'
end
end
-
+
def terminate_command
t = Thread.new { loop { STDOUT.print('.'); STDOUT.flush; sleep(1) } }
if @server.stop_all
@@ -187,7 +187,7 @@ def terminate_command
t.kill; STDOUT.puts
puts "Could not stop all watches within #{@server.terminate_timeout} seconds"
end
-
+
begin
@server.terminate
abort 'Could not stop god'
@@ -195,13 +195,13 @@ def terminate_command
puts 'Stopped god'
end
end
-
+
def check_command
Thread.new do
begin
event_system = God::EventHandler.event_system
puts "using event system: #{event_system}"
-
+
if God::EventHandler.loaded?
puts "starting event handler"
God::EventHandler.start
@@ -209,24 +209,24 @@ def check_command
puts "[fail] event system did not load"
exit(1)
end
-
+
puts 'forking off new process'
-
+
pid = fork do
loop { sleep(1) }
end
-
+
puts "forked process with pid = #{pid}"
-
+
God::EventHandler.register(pid, :proc_exit) do
puts "[ok] process exit event received"
exit!(0)
end
-
+
sleep(1)
-
+
puts "killing process"
-
+
::Process.kill('KILL', pid)
::Process.waitpid(pid)
rescue => e
@@ -234,24 +234,24 @@ def check_command
puts e.backtrace.join("\n")
end
end
-
+
sleep(2)
-
+
puts "[fail] never received process exit event"
exit(1)
end
-
+
def lifecycle_command
# get the name of the watch/group
name = @args[1]
-
+
puts "Sending '#{@command}' command"
-
+
t = Thread.new { loop { sleep(1); STDOUT.print('.'); STDOUT.flush; sleep(1) } }
-
+
# send @command
watches = @server.control(name, @command)
-
+
# output response
t.kill; STDOUT.puts
unless watches.empty?
@@ -264,6 +264,6 @@ def lifecycle_command
end
end
end # Command
-
+
end
end
View
66 lib/god/cli/run.rb
@@ -1,21 +1,21 @@
module God
module CLI
-
+
class Run
def initialize(options)
@options = options
-
+
dispatch
end
-
+
def dispatch
# have at_exit start god
$run = true
-
+
if @options[:syslog]
require 'god/sys_logger'
end
-
+
# run
if @options[:daemonize]
run_daemonized
@@ -23,7 +23,7 @@ def dispatch
run_in_front
end
end
-
+
def attach
process = System::Process.new(@options[:attach])
Thread.new do
@@ -36,65 +36,65 @@ def attach
end
end
end
-
+
def default_run
# make sure we have STDIN/STDOUT redirected immediately
setup_logging
-
+
# start attached pid watcher if necessary
if @options[:attach]
self.attach
end
-
+
if @options[:port]
God.port = @options[:port]
end
-
+
if @options[:events]
God::EventHandler.load
end
-
+
# set log level, defaults to WARN
if @options[:log_level]
God.log_level = @options[:log_level]
else
God.log_level = @options[:daemonize] ? :warn : :info
end
-
+
if @options[:config]
if !@options[:config].include?('*') && !File.exist?(@options[:config])
abort "File not found: #{@options[:config]}"
end
-
+
# start the event handler
God::EventHandler.start if God::EventHandler.loaded?
-
+
load_config @options[:config]
end
setup_logging
end
-
+
def run_in_front
require 'god'
-
+
default_run
end
-
+
def run_daemonized
# trap and ignore SIGHUP
Signal.trap('HUP') {}
-
+
pid = fork do
begin
require 'god'
-
+
# set pid if requested
if @options[:pid] # and as deamon
- God.pid = @options[:pid]
+ God.pid = @options[:pid]
end
-
+
default_run
-
+
unless God::EventHandler.loaded?
puts
puts "***********************************************************************"
@@ -105,30 +105,30 @@ def run_daemonized
puts "***********************************************************************"
puts
end
-
+
rescue => e
puts e.message
puts e.backtrace.join("\n")
abort "There was a fatal system error while starting god (see above)"
end
end
-
+
if @options[:pid]
File.open(@options[:pid], 'w') { |f| f.write pid }
end
-
+
::Process.detach pid
-
+
exit
end
-
+
def setup_logging
log_file = God.log_file