Add multiple threads to log_call

Conflicts:
	bootstrapvz/common/tools.py
This commit is contained in:
Tiago Ilieve 2014-04-17 16:35:25 -03:00 committed by Anders Ingemann
parent e68ed9b66c
commit f43f961de3

View file

@ -6,18 +6,20 @@ def log_check_call(command, stdin=None, env=None, shell=False):
return stdout return stdout
def stream_readline(args):
stream, q = args
for line in iter(stream.readline, ''):
q.put((stream, line.strip()))
def log_call(command, stdin=None, env=None, shell=False): def log_call(command, stdin=None, env=None, shell=False):
import subprocess import subprocess
import select
import logging import logging
import Queue
from multiprocessing.dummy import Pool as ThreadPool
from os.path import realpath from os.path import realpath
command_log = realpath(command[0]).replace('/', '.') command_log = realpath(command[0]).replace('/', '.')
log = logging.getLogger(__name__ + command_log) log = logging.getLogger(__name__ + command_log)
log.debug('Executing: {command}'.format(command=' '.join(command))) log.debug('Executing: {command}'.format(command=' '.join(command)))
if stdin is not None:
log.debug(' stdin: {stdin}'.format(stdin=stdin))
popen_args = {'args': command, popen_args = {'args': command,
'env': env, 'env': env,
'shell': shell, 'shell': shell,
@ -25,6 +27,7 @@ def log_call(command, stdin=None, env=None, shell=False):
'stdout': subprocess.PIPE, 'stdout': subprocess.PIPE,
'stderr': subprocess.PIPE, } 'stderr': subprocess.PIPE, }
if stdin is not None: if stdin is not None:
log.debug(' stdin: {stdin}'.format(stdin=stdin))
popen_args['stdin'] = subprocess.PIPE popen_args['stdin'] = subprocess.PIPE
process = subprocess.Popen(**popen_args) process = subprocess.Popen(**popen_args)
process.stdin.write(stdin + "\n") process.stdin.write(stdin + "\n")
@ -34,19 +37,22 @@ def log_call(command, stdin=None, env=None, shell=False):
process = subprocess.Popen(**popen_args) process = subprocess.Popen(**popen_args)
stdout = [] stdout = []
stderr = [] stderr = []
q = Queue.Queue()
pool = ThreadPool(2)
pool.map(stream_readline, [(process.stdout, q), (process.stderr, q)])
pool.close()
while True: while True:
reads = [process.stdout.fileno(), process.stderr.fileno()] try:
ret = select.select(reads, [], []) stream, output = q.get_nowait()
for fd in ret[0]: if stream is process.stdout:
if fd == process.stdout.fileno(): log.debug(output)
for line in iter(process.stdout.readline, ''): stdout.append(output)
log.debug(line.strip()) elif stream is process.stderr:
stdout.append(line.strip()) log.error(output)
if fd == process.stderr.fileno(): stderr.append(output)
for line in iter(process.stderr.readline, ''): except Queue.Empty:
log.error(line.strip()) pool.join()
stderr.append(line.strip()) process.wait()
if process.poll() is not None:
return process.returncode, stdout, stderr return process.returncode, stdout, stderr