god 0.4.3 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. data/History.txt +43 -7
  2. data/Manifest.txt +20 -4
  3. data/Rakefile +1 -1
  4. data/bin/god +263 -195
  5. data/examples/events.god +66 -34
  6. data/examples/gravatar.god +25 -12
  7. data/init/god +42 -0
  8. data/lib/god/behavior.rb +9 -29
  9. data/lib/god/behaviors/clean_pid_file.rb +6 -2
  10. data/lib/god/behaviors/notify_when_flapping.rb +4 -4
  11. data/lib/god/condition.rb +48 -6
  12. data/lib/god/conditions/always.rb +5 -1
  13. data/lib/god/conditions/cpu_usage.rb +13 -5
  14. data/lib/god/conditions/degrading_lambda.rb +8 -3
  15. data/lib/god/conditions/flapping.rb +97 -0
  16. data/lib/god/conditions/http_response_code.rb +97 -0
  17. data/lib/god/conditions/lambda.rb +8 -2
  18. data/lib/god/conditions/memory_usage.rb +13 -5
  19. data/lib/god/conditions/process_exits.rb +11 -3
  20. data/lib/god/conditions/process_running.rb +22 -4
  21. data/lib/god/conditions/tries.rb +16 -5
  22. data/lib/god/configurable.rb +54 -0
  23. data/lib/god/contact.rb +106 -0
  24. data/lib/god/contacts/email.rb +73 -0
  25. data/lib/god/errors.rb +3 -0
  26. data/lib/god/hub.rb +138 -33
  27. data/lib/god/logger.rb +21 -4
  28. data/lib/god/metric.rb +3 -4
  29. data/lib/god/process.rb +93 -49
  30. data/lib/god/socket.rb +60 -0
  31. data/lib/god/task.rb +233 -0
  32. data/lib/god/trigger.rb +43 -0
  33. data/lib/god/watch.rb +48 -114
  34. data/lib/god.rb +216 -63
  35. data/test/configs/child_events/child_events.god +20 -1
  36. data/test/configs/child_polls/child_polls.god +26 -6
  37. data/test/configs/child_polls/simple_server.rb +10 -1
  38. data/test/configs/contact/contact.god +74 -0
  39. data/test/configs/contact/simple_server.rb +3 -0
  40. data/test/configs/daemon_events/daemon_events.god +5 -2
  41. data/test/configs/daemon_events/simple_server.rb +2 -0
  42. data/test/configs/daemon_events/simple_server_stop.rb +9 -0
  43. data/test/configs/degrading_lambda/degrading_lambda.god +1 -3
  44. data/test/configs/task/logs/.placeholder +0 -0
  45. data/test/configs/task/task.god +26 -0
  46. data/test/helper.rb +19 -11
  47. data/test/test_conditions_http_response_code.rb +115 -0
  48. data/test/test_conditions_process_running.rb +2 -2
  49. data/test/test_conditions_tries.rb +21 -0
  50. data/test/test_contact.rb +109 -0
  51. data/test/test_god.rb +101 -17
  52. data/test/test_hub.rb +64 -1
  53. data/test/test_process.rb +43 -56
  54. data/test/{test_server.rb → test_socket.rb} +6 -20
  55. data/test/test_task.rb +86 -0
  56. data/test/test_trigger.rb +59 -0
  57. data/test/test_watch.rb +32 -7
  58. metadata +27 -8
  59. data/lib/god/reporter.rb +0 -25
  60. data/lib/god/server.rb +0 -37
  61. data/test/test_reporter.rb +0 -18
data/History.txt CHANGED
@@ -1,16 +1,52 @@
1
- == 0.4.3
1
+ == 0.5.0 / 2007-10-05
2
+
3
+ * Major Enhancements
4
+ * Implement lifecycle scoped metric to allow for cross-state conditions
5
+ * Add TriggerCondition for conditions that need info about state changes
6
+ * Implement notification system
7
+ * Add Tasks (a generalization of Watches) to do non-process related tasks
8
+ * Add example init.d file in GOD_INSTALL_DIR/init/god [scott becker]
9
+ * Add human readable info to conditions (and make low level log lines debug)
10
+ * Switch DRb to use a unix domain socket for security reasons
11
+ * Minor Enchancements
12
+ * Allow EventConditions to do transition overloading
13
+ * Report errors during god startup instead of failing silently
14
+ * Make transition block optional (default to Always condition returning true)
15
+ * Better usage info for `god --help`
16
+ * Explain what's going on when attempting to rebind to an in-use port
17
+ * Add -b option to god binary to auto-bind to an unused port
18
+ * Add `god quit` to stop god without stopping any tasks
19
+ * Make self-daemonized Watch commands synchronous (as they should be)
20
+ * Allow self-daemonized Watches to specify a log (could be useful)
21
+ * Check for existence of config file if specified
22
+ * Robustify `god load` and report errors back to the command issuer
23
+ * Warn when `god load` tries to set global options
24
+ * Add Configurable.clear method and make built-in conditions clear on entry
25
+ * New Conditions
26
+ * Flapping < TriggerCondition - trigger on state change
27
+ * HttpResponseCode < PollCondition - trigger on http response code or timeout (thx scott becker)
28
+ * New Contacts
29
+ * Email < Contact - notify via email (smtp)
30
+ * Bug Fixes
31
+ * Fix abort not aborting problem
32
+ * Fix -p option not working for god binary
33
+ * Fix God.init not accepting block (thx _eric)
34
+ * Fix SIGHUP ignore (thx _eric)
35
+ * Fix error reporting on `god --help` (don't error report a normal SystemExit)
36
+
37
+ == 0.4.3 / 2007-09-10
2
38
  * Bug Fixes
3
- * fix Process#alive? to not raise on no such file
39
+ * fix Process#alive? to not raise on no such file (affects `god terminate`)
4
40
 
5
- == 0.4.2
41
+ == 0.4.2 / 2007-09-10
6
42
  * Bug Fixes
7
- * fix netlink events [dkresge]
43
+ * fix netlink buffer issue that prevented events on Linux from working consistently [dkresge]
8
44
 
9
- == 0.4.1
45
+ == 0.4.1 / 2007-09-10
10
46
  * Bug Fixes
11
47
  * require 'stringio' for ruby 1.8.5
12
48
 
13
- == 0.4.0
49
+ == 0.4.0 / 2007-09-10
14
50
 
15
51
  * Major Enhancements
16
52
  * Add the ability for conditions to override transition state (for exceptional cases)
@@ -34,7 +70,7 @@
34
70
  * Bug Fixes
35
71
  * Use exit!(0) instead of exit! in god binary to exit with code 0 (instead of default -1)
36
72
  * Command line group control fixed
37
- * Fix cross-thread return problem (use exit instead)
73
+ * Fix cross-thread return problem
38
74
 
39
75
  == 0.3.0 / 2007-08-17
40
76
 
data/Manifest.txt CHANGED
@@ -8,6 +8,7 @@ examples/gravatar.god
8
8
  ext/god/extconf.rb
9
9
  ext/god/kqueue_handler.c
10
10
  ext/god/netlink_handler.c
11
+ init/god
11
12
  lib/god.rb
12
13
  lib/god/behavior.rb
13
14
  lib/god/behaviors/clean_pid_file.rb
@@ -16,11 +17,16 @@ lib/god/condition.rb
16
17
  lib/god/conditions/always.rb
17
18
  lib/god/conditions/cpu_usage.rb
18
19
  lib/god/conditions/degrading_lambda.rb
20
+ lib/god/conditions/flapping.rb
21
+ lib/god/conditions/http_response_code.rb
19
22
  lib/god/conditions/lambda.rb
20
23
  lib/god/conditions/memory_usage.rb
21
24
  lib/god/conditions/process_exits.rb
22
25
  lib/god/conditions/process_running.rb
23
26
  lib/god/conditions/tries.rb
27
+ lib/god/configurable.rb
28
+ lib/god/contact.rb
29
+ lib/god/contacts/email.rb
24
30
  lib/god/dependency_graph.rb
25
31
  lib/god/errors.rb
26
32
  lib/god/event_handler.rb
@@ -32,19 +38,23 @@ lib/god/logger.rb
32
38
  lib/god/metric.rb
33
39
  lib/god/process.rb
34
40
  lib/god/registry.rb
35
- lib/god/reporter.rb
36
- lib/god/server.rb
41
+ lib/god/socket.rb
37
42
  lib/god/sugar.rb
38
43
  lib/god/system/process.rb
44
+ lib/god/task.rb
39
45
  lib/god/timeline.rb
40
46
  lib/god/timer.rb
47
+ lib/god/trigger.rb
41
48
  lib/god/watch.rb
42
49
  test/configs/child_events/child_events.god
43
50
  test/configs/child_events/simple_server.rb
44
51
  test/configs/child_polls/child_polls.god
45
52
  test/configs/child_polls/simple_server.rb
53
+ test/configs/contact/contact.god
54
+ test/configs/contact/simple_server.rb
46
55
  test/configs/daemon_events/daemon_events.god
47
56
  test/configs/daemon_events/simple_server.rb
57
+ test/configs/daemon_events/simple_server_stop.rb
48
58
  test/configs/daemon_polls/daemon_polls.god
49
59
  test/configs/daemon_polls/simple_server.rb
50
60
  test/configs/degrading_lambda/degrading_lambda.god
@@ -53,12 +63,17 @@ test/configs/real.rb
53
63
  test/configs/running_load/running_load.god
54
64
  test/configs/stress/simple_server.rb
55
65
  test/configs/stress/stress.god
66
+ test/configs/task/logs/.placeholder
67
+ test/configs/task/task.god
56
68
  test/configs/test.rb
57
69
  test/helper.rb
58
70
  test/suite.rb
59
71
  test/test_behavior.rb
60
72
  test/test_condition.rb
73
+ test/test_conditions_http_response_code.rb
61
74
  test/test_conditions_process_running.rb
75
+ test/test_conditions_tries.rb
76
+ test/test_contact.rb
62
77
  test/test_dependency_graph.rb
63
78
  test/test_event_handler.rb
64
79
  test/test_god.rb
@@ -68,10 +83,11 @@ test/test_logger.rb
68
83
  test/test_metric.rb
69
84
  test/test_process.rb
70
85
  test/test_registry.rb
71
- test/test_reporter.rb
72
- test/test_server.rb
86
+ test/test_socket.rb
73
87
  test/test_sugar.rb
74
88
  test/test_system_process.rb
89
+ test/test_task.rb
75
90
  test/test_timeline.rb
76
91
  test/test_timer.rb
92
+ test/test_trigger.rb
77
93
  test/test_watch.rb
data/Rakefile CHANGED
@@ -1,7 +1,7 @@
1
1
  require 'rubygems'
2
2
  require 'hoe'
3
3
 
4
- Hoe.new('god', '0.4.3') do |p|
4
+ Hoe.new('god', '0.5.0') do |p|
5
5
  p.rubyforge_name = 'god'
6
6
  p.author = 'Tom Preston-Werner'
7
7
  p.email = 'tom@rubyisawesome.com'
data/bin/god CHANGED
@@ -1,234 +1,302 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
+ STDOUT.sync = true
4
+
3
5
  $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
4
6
 
5
7
  require 'rubygems'
6
8
  require 'optparse'
7
9
  require 'drb'
8
10
 
9
- options = {:daemonize => true, :port => 17165}
10
-
11
- OptionParser.new do |opts|
12
- opts.banner = <<-EOF
13
- Usage: god [command] [options]
14
-
15
- Commands:
16
- start <watch or group name>
17
- restart <watch or group name>
18
- stop <watch or group name>
19
- monitor <watch or group name>
20
- unmonitor <watch or group name>
21
- load <file>
22
- log <watch name>
23
- status
24
- terminate
25
-
26
- Options:
27
- EOF
28
-
29
- opts.on("-cCONFIG", "--config-file CONFIG", "Configuration file") do |x|
30
- options[:config] = x
31
- end
32
-
33
- opts.on("-pPORT", "--port PORT", "Communications port") do |x|
34
- options[:port] = x
35
- end
36
-
37
- opts.on("-PFILE", "--pid FILE", "Where to write the PID file") do |x|
38
- options[:pid] = x
39
- end
40
-
41
- opts.on("-lFILE", "--log FILE", "Where to write the log file") do |x|
42
- options[:log] = x
43
- end
44
-
45
- opts.on("-D", "--no-daemonize", "Don't daemonize") do
46
- options[:daemonize] = false
47
- end
48
-
49
- opts.on("-v", "--version", "Print the version number and exit") do
50
- options[:version] = true
51
- end
52
-
53
- opts.on("-V", "Print extended version and build information") do
54
- options[:info] = true
55
- end
56
- end.parse!
11
+ begin
12
+ options = {:daemonize => true, :port => 17165}
57
13
 
58
- if options[:version]
59
- require 'god'
60
-
61
- # print version
62
- puts "Version #{God::VERSION}"
63
- exit!(0)
64
- elsif options[:info]
65
- require 'god'
66
-
67
- puts "Version: #{God::VERSION}"
68
- puts "Polls: enabled"
69
- puts "Events: " + God::EventHandler.event_system
70
-
71
- exit!(0)
72
- elsif command = ARGV[0]
73
- require 'god'
74
-
75
- # a command was specified
76
-
77
- # connect to remote drb
78
- DRb.start_service
79
- server = DRbObject.new nil, "druby://127.0.0.1:#{options[:port]}"
80
-
81
- begin
82
- server.ping
83
- rescue DRb::DRbConnError
84
- puts "The server is not available (or you do not have permissions to access it)"
85
- exit!
86
- rescue => e
87
- puts e.message
88
- puts e.backtrace.join("\n")
89
- exit!
90
- end
14
+ opts = OptionParser.new do |opts|
15
+ opts.banner = <<-EOF
16
+ Usage:
17
+ Starting:
18
+ god -c <config file> [-p <port> | -b] [-P <file>] [-l <file>] [-D]
19
+
20
+ Querying:
21
+ god <command> <argument> [-p <port>]
22
+ god <command> [-p <port>]
23
+ god -v
24
+ god -V (must be run as root to be accurate on Linux)
25
+
26
+ Commands:
27
+ start <task or group name> start task or group
28
+ restart <task or group name> restart task or group
29
+ stop <task or group name> stop task or group
30
+ monitor <task or group name> monitor task or group
31
+ unmonitor <task or group name> unmonitor task or group
32
+ load <file> load a config into a running god
33
+ log <task name> show realtime log for given task
34
+ status show status of each task
35
+ quit stop god
36
+ terminate stop god and all tasks
37
+
38
+ Options:
39
+ EOF
91
40
 
92
- if command == 'load'
93
- file = ARGV[1]
41
+ opts.on("-cCONFIG", "--config-file CONFIG", "Configuration file") do |x|
42
+ options[:config] = x
43
+ end
94
44
 
95
- puts "Sending '#{command}' command"
45
+ opts.on("-pPORT", "--port PORT", "Communications port (default 17165)") do |x|
46
+ options[:port] = x
47
+ end
96
48
 
97
- code = File.read(file)
49
+ opts.on("-b", "--auto-bind", "Auto-bind to an unused port number") do
50
+ options[:port] = "0"
51
+ end
98
52
 
99
- watches = server.running_load(code)
53
+ opts.on("-PFILE", "--pid FILE", "Where to write the PID file") do |x|
54
+ options[:pid] = x
55
+ end
100
56
 
101
- # output response
102
- puts 'The following watches were affected:'
103
- watches.each do |w|
104
- puts ' ' + w.name
57
+ opts.on("-lFILE", "--log FILE", "Where to write the log file") do |x|
58
+ options[:log] = x
105
59
  end
106
60
 
107
- puts "Done"
108
- elsif command == 'status'
109
- watches = server.status
110
- watches.keys.sort.each do |name|
111
- state = watches[name][:state]
112
- puts "#{name}: #{state}"
61
+ opts.on("-D", "--no-daemonize", "Don't daemonize") do
62
+ options[:daemonize] = false
113
63
  end
114
- elsif command == 'log'
115
- begin
116
- Signal.trap('INT') { exit!(0) }
117
- name = ARGV[1]
118
- t = Time.at(0)
119
- loop do
120
- print server.running_log(name, t)
121
- t = Time.now
122
- sleep 1
123
- end
124
- rescue God::NoSuchWatchError
125
- puts "No such watch"
126
- rescue DRb::DRbConnError
127
- puts "The server went away"
128
- rescue => e
129
- puts e.message
130
- puts e.backtrace.join("\n")
131
- ensure
132
- exit!(0)
64
+
65
+ opts.on("-v", "--version", "Print the version number and exit") do
66
+ options[:version] = true
133
67
  end
134
- elsif command == 'terminate'
135
- t = Thread.new { loop { STDOUT.print('.'); STDOUT.flush; sleep(1) } }
136
- if server.stop_all
137
- t.kill; STDOUT.puts
138
- puts 'Stopped all watches'
139
- else
140
- t.kill; STDOUT.puts
141
- puts 'Could not stop all watches within 10 seconds'
68
+
69
+ opts.on("-V", "Print extended version and build information") do
70
+ options[:info] = true
142
71
  end
72
+ end
73
+
74
+ opts.parse!
75
+
76
+ if options[:version]
77
+ require 'god'
78
+
79
+ # print version
80
+ puts "Version #{God::VERSION}"
81
+ exit
82
+ elsif options[:info]
83
+ require 'god'
84
+
85
+ puts "Version: #{God::VERSION}"
86
+ puts "Polls: enabled"
87
+ puts "Events: " + God::EventHandler.event_system
88
+
89
+ exit
90
+ elsif command = ARGV[0]
91
+ require 'god'
92
+
93
+ # a command was specified
94
+
95
+ # connect to drb unix socket
96
+ DRb.start_service
97
+ server = DRbObject.new(nil, God::Socket.socket(options[:port]))
143
98
 
144
99
  begin
145
- server.terminate
146
- abort 'Could not stop god'
100
+ server.ping
147
101
  rescue DRb::DRbConnError
148
- puts 'Stopped god'
149
- exit!(0)
102
+ puts "The server is not available (or you do not have permissions to access it)"
103
+ abort
150
104
  end
151
- else
152
- # get the name of the watch/group
153
- name = ARGV[1]
154
-
155
- begin
105
+
106
+ if command == 'load'
107
+ file = ARGV[1]
108
+
156
109
  puts "Sending '#{command}' command"
110
+ puts
111
+
112
+ unless File.exist?(file)
113
+ abort "File not found: #{file}"
114
+ end
115
+
116
+ names, errors = *server.running_load(File.read(file), File.expand_path(file))
157
117
 
158
- t = Thread.new { loop { STDOUT.print('.'); STDOUT.flush; sleep(1) } }
159
-
160
- # send command
161
- watches = server.control(name, command)
162
-
163
118
  # output response
164
- t.kill; STDOUT.puts
165
- puts 'The following watches were affected:'
166
- watches.each do |w|
167
- puts ' ' + w.name
119
+ unless names.empty?
120
+ puts 'The following tasks were affected:'
121
+ names.each do |w|
122
+ puts ' ' + w
123
+ end
168
124
  end
169
- rescue God::InvalidCommandError
170
- abort "Command '#{command}' is not valid. Run 'god --help' for usage"
171
- end
172
- end
173
-
174
- exit!(0)
175
- else
176
- # start god
177
- if !options[:daemonize]
178
- require 'god'
179
-
180
- if options[:port]
181
- God.port = options[:port]
182
- end
183
-
184
- load File.expand_path(options[:config])
185
- else
186
- pid = fork do
125
+
126
+ unless errors.empty?
127
+ puts errors
128
+ exit(1)
129
+ end
130
+ elsif command == 'status'
131
+ watches = server.status
132
+ watches.keys.sort.each do |name|
133
+ state = watches[name][:state]
134
+ puts "#{name}: #{state}"
135
+ end
136
+ elsif command == 'log'
137
+ begin
138
+ Signal.trap('INT') { exit }
139
+ name = ARGV[1]
140
+ t = Time.at(0)
141
+ loop do
142
+ print server.running_log(name, t)
143
+ t = Time.now
144
+ sleep 1
145
+ end
146
+ rescue God::NoSuchWatchError
147
+ puts "No such watch"
148
+ rescue DRb::DRbConnError
149
+ puts "The server went away"
150
+ end
151
+ elsif command == 'quit'
152
+ begin
153
+ server.terminate
154
+ abort 'Could not stop god'
155
+ rescue DRb::DRbConnError
156
+ puts 'Stopped god'
157
+ end
158
+ elsif command == 'terminate'
159
+ t = Thread.new { loop { STDOUT.print('.'); STDOUT.flush; sleep(1) } }
160
+ if server.stop_all
161
+ t.kill; STDOUT.puts
162
+ puts 'Stopped all watches'
163
+ else
164
+ t.kill; STDOUT.puts
165
+ puts 'Could not stop all watches within 10 seconds'
166
+ end
167
+
168
+ begin
169
+ server.terminate
170
+ abort 'Could not stop god'
171
+ rescue DRb::DRbConnError
172
+ puts 'Stopped god'
173
+ end
174
+ else
175
+ # get the name of the watch/group
176
+ name = ARGV[1]
177
+
187
178
  begin
188
- require 'god'
179
+ puts "Sending '#{command}' command"
189
180
 
190
- log_file = options[:log] || "/dev/null"
181
+ t = Thread.new { loop { sleep(1); STDOUT.print('.'); STDOUT.flush; sleep(1) } }
191
182
 
192
- STDIN.reopen "/dev/null"
193
- STDOUT.reopen(log_file, "a")
194
- STDERR.reopen STDOUT
183
+ # send command
184
+ watches = server.control(name, command)
195
185
 
196
- puts "Starting god"
197
-
198
- unless God::EventHandler.loaded?
199
- puts
200
- puts "***********************************************************************"
201
- puts "*"
202
- puts "* Event conditions are not available for your installation of god."
203
- puts "* You may still use and write custom conditions using the poll system"
204
- puts "*"
205
- puts "***********************************************************************"
206
- puts
186
+ # output response
187
+ t.kill; STDOUT.puts
188
+ unless watches.empty?
189
+ puts 'The following watches were affected:'
190
+ watches.each do |w|
191
+ puts ' ' + w
192
+ end
193
+ else
194
+ puts 'No matching task or group'
207
195
  end
196
+ rescue God::InvalidCommandError
197
+ t.kill rescue nil; STDOUT.puts
198
+ abort "Command '#{command}' is not valid. Run 'god --help' for usage"
199
+ end
200
+ end
201
+ else
202
+ # start god
203
+ $run = true
208
204
 
209
- puts "Resetting file descriptors"
210
-
211
- puts "Loading config"
205
+ if !options[:daemonize]
206
+ require 'god'
207
+
208
+ if options[:port]
209
+ God.port = options[:port]
210
+ end
211
+
212
+ if options[:config]
213
+ unless File.exist?(options[:config])
214
+ abort "File not found: #{options[:config]}"
215
+ end
212
216
 
213
- if options[:port]
214
- God.port = options[:port]
217
+ begin
218
+ load File.expand_path(options[:config])
219
+ rescue Exception => e
220
+ if e.instance_of?(SystemExit)
221
+ raise
222
+ else
223
+ puts e.message
224
+ puts e.backtrace.join("\n")
225
+ abort "There was an error in your configuration file (see above)"
226
+ end
227
+ end
228
+ end
229
+ else
230
+ # trap and ignore SIGHUP
231
+ Signal.trap('HUP') {}
232
+
233
+ pid = fork do
234
+ begin
235
+ require 'god'
236
+
237
+ log_file = options[:log] || "/dev/null"
238
+
239
+ unless God::EventHandler.loaded?
240
+ puts
241
+ puts "***********************************************************************"
242
+ puts "*"
243
+ puts "* Event conditions are not available for your installation of god."
244
+ puts "* You may still use and write custom conditions using the poll system"
245
+ puts "*"
246
+ puts "***********************************************************************"
247
+ puts
248
+ end
249
+
250
+ # set port if requested
251
+ if options[:port]
252
+ God.port = options[:port]
253
+ end
254
+
255
+ # load config
256
+ if options[:config]
257
+ unless File.exist?(options[:config])
258
+ abort "File not found: #{options[:config]}"
259
+ end
260
+
261
+ begin
262
+ load File.expand_path(options[:config])
263
+ rescue Exception => e
264
+ if e.instance_of?(SystemExit)
265
+ raise
266
+ else
267
+ puts e.message
268
+ puts e.backtrace.join("\n")
269
+ abort "There was an error in your configuration file (see above)"
270
+ end
271
+ end
272
+ end
273
+
274
+ # reset file descriptors
275
+ STDIN.reopen "/dev/null"
276
+ STDOUT.reopen(log_file, "a")
277
+ STDERR.reopen STDOUT
278
+ rescue => e
279
+ puts e.message
280
+ puts e.backtrace.join("\n")
281
+ abort "There was a fatal system error while starting god (see above)"
215
282
  end
283
+ end
216
284
 
217
- load File.expand_path(options[:config])
218
-
219
- Signal.trap('HUP') {}
220
- rescue => e
221
- File.open('god.log', 'a') { |f| f.puts e.message + "\n" + e.backtrace }
222
- abort "!!! ERROR - See god.log !!!"
285
+ if options[:pid]
286
+ File.open(options[:pid], 'w') { |f| f.write pid }
223
287
  end
288
+
289
+ ::Process.detach pid
290
+
291
+ exit
224
292
  end
225
-
226
- if options[:pid]
227
- File.open(options[:pid], 'w') { |f| f.write pid }
228
- end
229
-
230
- ::Process.detach pid
231
-
232
- exit!(0)
233
293
  end
234
- end
294
+ rescue Exception => e
295
+ if e.instance_of?(SystemExit)
296
+ raise
297
+ else
298
+ puts 'Uncaught exception'
299
+ puts e.message
300
+ puts e.backtrace.join("\n")
301
+ end
302
+ end