god 0.4.3 → 0.5.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 (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