Skip to content

Instantly share code, notes, and snippets.

@nickstenning
Created August 20, 2008 23:56
Show Gist options
  • Save nickstenning/6466 to your computer and use it in GitHub Desktop.
Save nickstenning/6466 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
#
# ./script/demodblogger
#
# Designed to assist with running a command in the background and capturing
# its output as it runs, this script takes a demo id, and calls
# @demo.job_log(line) for each line given it on stdin. Run without arguments for a
# brief summary of usage.
#
options = {}
case ARGV.length
when 0..2
abort "Usage: ./script/demodblogger <environment> <demo_id> somecommand --args"
else
options[:environment] = ARGV.shift
options[:demo_id] = Integer(ARGV.shift)
options[:command] = ARGV
end
if options[:environment]
ENV["RAILS_ENV"] = options[:environment]
RAILS_ENV.replace( options[:environment] ) if defined?(RAILS_ENV)
end
require File.dirname(__FILE__) + '/../config/environment'
class DBLogger
def initialize( demo )
@demo = demo
end
def log( msg, stream )
@demo.job_log msg.rstrip, stream
end
end
require 'open4'
require 'stringio'
begin
# Try and open the command, logging stdout and stderr as you go.
@demo = Demo.find(options[:demo_id])
@dblogger = DBLogger.new(@demo)
@log = Queue.new
producer = Thread.new do
@status = Open4.spawn( options[:command],
:stdin => STDIN.read,
:stdout => @log,
:stderr => @log,
:exitstatus => true )
end
consumer = Thread.new do
loop do
@dblogger.log( @log.pop, 'out' )
end
end
consumer.join
rescue Errno::ENOENT => e
# If the command doesn't exist, catch that as well, and log it as if it were
# on stderr.
@stderr << e.message
@stderr << e.backtrace.join("\n")
# Exit with the standard not found code.
exit 127
end
# Exit with the process's exit code.
exit @status.exitstatus
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment