[Kimchi-devel] [PATCH] [Wok] Make run_command log its output into a file.
Aline Manera
alinefm at linux.vnet.ibm.com
Tue Dec 22 12:27:35 UTC 2015
On 12/21/2015 01:57 PM, pvital at linux.vnet.ibm.com wrote:
> From: Paulo Vital <pvital at linux.vnet.ibm.com>
>
> Adds the ability of run_command to log the output of a console command into the
> file /tmp/wok_tee_log_file, like the "tee" command does.
>
> Using this patch, a command that takes too many time to execute can be monitored
> by reading the log file while other tasks are executed.
>
> Signed-off-by: Paulo Vital <pvital at linux.vnet.ibm.com>
> ---
> src/wok/utils.py | 45 ++++++++++++++++++++++++++++++++++++++++++---
> 1 file changed, 42 insertions(+), 3 deletions(-)
>
> diff --git a/src/wok/utils.py b/src/wok/utils.py
> index 997adf3..96569d4 100644
> --- a/src/wok/utils.py
> +++ b/src/wok/utils.py
> @@ -40,6 +40,7 @@ from wok.exception import InvalidParameter, TimeoutExpired
>
>
> wok_log = cherrypy.log.error_log
> +tee_log_file = '/tmp/wok_tee_log_file'
You should create a different log file per run_command() instance.
We may have multiple simultaneous calls to run_command() which will make
the tee file a mess. =)
My suggestion is to use tempfile.mktemp() to create a temporary file
when running run_command() with tee=True.
> task_id = 0
>
>
> @@ -131,13 +132,15 @@ def import_module(module_name, class_name=''):
> return __import__(module_name, globals(), locals(), [class_name])
>
>
> -def run_command(cmd, timeout=None, silent=False):
> +def run_command(cmd, timeout=None, silent=False, tee=False):
> """
> cmd is a sequence of command arguments.
> timeout is a float number in seconds.
> timeout default value is None, means command run without timeout.
> silent is bool, it will log errors using debug handler not error.
> silent default value is False.
> + tee is bool and stores the output of the command in a log file, like 'tee'
> + tee default value is False.
> """
> # subprocess.kill() can leave descendants running
> # and halting the execution. Using psutil to
> @@ -155,6 +158,18 @@ def run_command(cmd, timeout=None, silent=False):
> else:
> timeout_flag[0] = True
>
> + def tee_log(msg=None):
> + if msg is None:
> + return
> +
> + f = open(tee_log_file, 'a')
> + msg +='\n'
> + try:
> + f.write(msg)
> + except TypeError:
> + f.write(msg.encode('utf_8'))
> + f.close()
> +
> proc = None
> timer = None
> timeout_flag = [False]
> @@ -167,8 +182,31 @@ def run_command(cmd, timeout=None, silent=False):
> timer.setDaemon(True)
> timer.start()
>
> - out, error = proc.communicate()
> wok_log.debug("Run command: '%s'", " ".join(cmd))
> + if tee:
> + output = []
> + while True:
> + line = ""
> + try:
> + line = proc.stdout.readline()
> + line = line.decode('utf_8')
> + except Exception:
> + type, e, tb = sys.exc_info()
> + wok_log.error(e)
> + wok_log.error("The output of the command could not be "
> + " decoded as %s\ncmd: %s\n line ignored: %s" %
> + ('utf_8', cmd, repr(line)))
> + pass
> +
> + output.append(line)
> + if not line:
> + break
> + line = line.rstrip('\n\r')
> + tee_log(line)
> + out = ''.join(output)
> + error = proc.stderr.read()
> + else:
> + out, error = proc.communicate()
>
> if out:
> wok_log.debug("out:\n%s", out)
> @@ -214,7 +252,8 @@ def run_command(cmd, timeout=None, silent=False):
> finally:
> if timer and not timeout_flag[0]:
> timer.cancel()
> -
> + if tee and os.path.exists(tee_log_file):
> + os.remove(tee_log_file)
>
> def parse_cmd_output(output, output_items):
> res = []
> --
> 2.5.0
More information about the Kimchi-devel
mailing list