god binary status, log, terminate, logging system improvements
[god.git] / bin / god
blobfe3a3c4ecc3b186a85ac13453e4118f77f7ef3c5
1 #!/usr/bin/env ruby
3 $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
5 require 'rubygems'
6 require 'optparse'
7 require 'drb'
9 options = {:daemonize => true, :port => 17165}
11 OptionParser.new do |opts|
12 opts.banner = <<-EOF
13 Usage: god [command] [options]
15 Commands:
16 start <watch or group name>
17 stop <watch or group name>
18 monitor <watch or group name>
19 unmonitor <watch or group name>
20 load <file>
21 log <watch name>
22 status
23 terminate
25 Options:
26 EOF
28 opts.on("-cCONFIG", "--config-file CONFIG", "Configuration file") do |x|
29 options[:config] = x
30 end
32 opts.on("-pPORT", "--port PORT", "Communications port") do |x|
33 options[:port] = x
34 end
36 opts.on("-PFILE", "--pid FILE", "Where to write the PID file") do |x|
37 options[:pid] = x
38 end
40 opts.on("-lFILE", "--log FILE", "Where to write the log file") do |x|
41 options[:log] = x
42 end
44 opts.on("-D", "--no-daemonize", "Don't daemonize") do
45 options[:daemonize] = false
46 end
48 opts.on("-v", "--version", "Print the version number and exit") do
49 options[:version] = true
50 end
52 opts.on("-V", "Print extended version and build information") do
53 options[:info] = true
54 end
55 end.parse!
57 if options[:version]
58 require 'god'
60 # print version
61 puts "Version #{God::VERSION}"
62 exit!(0)
63 elsif options[:info]
64 require 'god'
66 puts "Version: #{God::VERSION}"
67 puts "Polls: enabled"
68 puts "Events: " + God::EventHandler.event_system
70 exit!(0)
71 elsif command = ARGV[0]
72 require 'god'
74 # a command was specified
76 # connect to remote drb
77 DRb.start_service
78 server = DRbObject.new nil, "druby://localhost:#{options[:port]}"
80 if command == 'load'
81 file = ARGV[1]
83 puts "Sending '#{command}' command"
85 code = File.read(file)
87 watches = server.running_load(code)
89 # output response
90 puts 'The following watches were affected:'
91 watches.each do |w|
92 puts ' ' + w.name
93 end
95 puts "Done"
96 elsif command == 'status'
97 puts server.status
98 elsif command == 'log'
99 begin
100 Signal.trap('INT') { exit!(0) }
101 name = ARGV[1]
102 t = Time.at(0)
103 loop do
104 print server.running_log(name, t)
105 t = Time.now
106 sleep 1
108 rescue God::NoSuchWatchError
109 puts "No such watch"
110 rescue DRb::DRbConnError
111 puts "The server went away"
112 rescue => e
113 puts e.message
114 puts e.backtrace.join("\n")
115 ensure
116 exit!(0)
118 elsif command == 'terminate'
119 if server.stop_all
120 puts 'Stopped all watches'
121 else
122 puts 'Could not stop all watches within 10 seconds'
125 begin
126 server.terminate
127 abort 'Could not stop god'
128 rescue DRb::DRbConnError
129 puts 'Stopped god'
130 exit!(0)
132 else
133 # get the name of the watch/group
134 name = ARGV[1]
136 begin
137 puts "Sending '#{command}' command"
139 # send command
140 watches = server.control(name, command)
142 # output response
143 puts 'The following watches were affected:'
144 watches.each do |w|
145 puts ' ' + w.name
147 rescue God::InvalidCommandError
148 abort "Command '#{command}' is not valid. Run 'god --help' for usage"
152 exit!(0)
153 else
154 # start god
155 if !options[:daemonize]
156 require 'god'
158 if options[:port]
159 God.port = options[:port]
162 load File.expand_path(options[:config])
163 else
164 pid = fork do
165 begin
166 require 'god'
168 log_file = options[:log] || "/dev/null"
170 STDIN.reopen "/dev/null"
171 STDOUT.reopen(log_file, "a")
172 STDERR.reopen STDOUT
174 puts "Starting god"
176 unless God::EventHandler.loaded?
177 puts
178 puts "***********************************************************************"
179 puts "*"
180 puts "* Event conditions are not available for your installation of god."
181 puts "* You may still use and write custom conditions using the poll system"
182 puts "*"
183 puts "***********************************************************************"
184 puts
187 puts "Resetting file descriptors"
189 puts "Loading config"
191 if options[:port]
192 God.port = options[:port]
195 load File.expand_path(options[:config])
197 Signal.trap('HUP') {}
198 rescue => e
199 File.open('god.log', 'a') { |f| f.puts e.message + "\n" + e.backtrace }
200 abort "!!! ERROR - See god.log !!!"
204 if options[:pid]
205 File.open(options[:pid], 'w') { |f| f.write pid }
208 ::Process.detach pid
210 exit!(0)