fix god command output formatting
[god.git] / bin / god
blobf55948014d809cdaf7505eee2beacefcbb36318a
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 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
26 Options:
27 EOF
29 opts.on("-cCONFIG", "--config-file CONFIG", "Configuration file") do |x|
30 options[:config] = x
31 end
33 opts.on("-pPORT", "--port PORT", "Communications port") do |x|
34 options[:port] = x
35 end
37 opts.on("-PFILE", "--pid FILE", "Where to write the PID file") do |x|
38 options[:pid] = x
39 end
41 opts.on("-lFILE", "--log FILE", "Where to write the log file") do |x|
42 options[:log] = x
43 end
45 opts.on("-D", "--no-daemonize", "Don't daemonize") do
46 options[:daemonize] = false
47 end
49 opts.on("-v", "--version", "Print the version number and exit") do
50 options[:version] = true
51 end
53 opts.on("-V", "Print extended version and build information") do
54 options[:info] = true
55 end
56 end.parse!
58 if options[:version]
59 require 'god'
61 # print version
62 puts "Version #{God::VERSION}"
63 exit!(0)
64 elsif options[:info]
65 require 'god'
67 puts "Version: #{God::VERSION}"
68 puts "Polls: enabled"
69 puts "Events: " + God::EventHandler.event_system
71 exit!(0)
72 elsif command = ARGV[0]
73 require 'god'
75 # a command was specified
77 # connect to remote drb
78 DRb.start_service
79 server = DRbObject.new nil, "druby://127.0.0.1:#{options[:port]}"
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
92 if command == 'load'
93 file = ARGV[1]
95 puts "Sending '#{command}' command"
97 code = File.read(file)
99 watches = server.running_load(code)
101 # output response
102 puts 'The following watches were affected:'
103 watches.each do |w|
104 puts ' ' + w.name
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}"
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
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)
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'
144 begin
145 server.terminate
146 abort 'Could not stop god'
147 rescue DRb::DRbConnError
148 puts 'Stopped god'
151 exit!(0)
152 else
153 # get the name of the watch/group
154 name = ARGV[1]
156 begin
157 puts "Sending '#{command}' command"
159 t = Thread.new { loop { sleep(1); STDOUT.print('.'); STDOUT.flush; sleep(1) } }
161 # send command
162 watches = server.control(name, command)
164 # output response
165 t.kill; STDOUT.puts
166 puts 'The following watches were affected:'
167 watches.each do |w|
168 puts ' ' + w.name
170 rescue God::InvalidCommandError
171 t.kill rescue nil; STDOUT.puts
172 abort "Command '#{command}' is not valid. Run 'god --help' for usage"
176 exit!(0)
177 else
178 # start god
179 if !options[:daemonize]
180 require 'god'
182 if options[:port]
183 God.port = options[:port]
186 load File.expand_path(options[:config])
187 else
188 pid = fork do
189 begin
190 require 'god'
192 log_file = options[:log] || "/dev/null"
194 STDIN.reopen "/dev/null"
195 STDOUT.reopen(log_file, "a")
196 STDERR.reopen STDOUT
198 puts "Starting god"
200 unless God::EventHandler.loaded?
201 puts
202 puts "***********************************************************************"
203 puts "*"
204 puts "* Event conditions are not available for your installation of god."
205 puts "* You may still use and write custom conditions using the poll system"
206 puts "*"
207 puts "***********************************************************************"
208 puts
211 puts "Resetting file descriptors"
213 puts "Loading config"
215 if options[:port]
216 God.port = options[:port]
219 load File.expand_path(options[:config])
221 Signal.trap('HUP') {}
222 rescue => e
223 File.open('god.error.log', 'a') { |f| f.write e.message + "\n" + e.backtrace.join("\n") }
227 if options[:pid]
228 File.open(options[:pid], 'w') { |f| f.write pid }
231 ::Process.detach pid
233 exit!(0)