[PATCH V5] [Wok] Make run_command log its output into a file.

From: Paulo Vital <pvital@linux.vnet.ibm.com> V4 -> V5: - Added try/exception to control file IO. V3 -> V4: - PEP8 fixes. V2 -> V3: - Changed the place of the log_file creation control. V1 -> V2: - Removed fixed log file, changing parameter of run_command() method to accept the path of the log file instead of a boolean. V1: 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. Paulo Vital (1): Make run_command log its output into a file. src/wok/utils.py | 50 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) -- 2.5.0

From: Paulo Vital <pvital@linux.vnet.ibm.com> Adds the ability of run_command to log the output of a console command into a given 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@linux.vnet.ibm.com> --- src/wok/utils.py | 50 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/src/wok/utils.py b/src/wok/utils.py index 7b1b309..05574d7 100644 --- a/src/wok/utils.py +++ b/src/wok/utils.py @@ -28,6 +28,7 @@ import pwd import re import sqlite3 import subprocess +import sys import traceback import xml.etree.ElementTree as ET from cherrypy.lib.reprconf import Parser @@ -135,13 +136,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=None): """ 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 a file path to store the output of the command, like 'tee' command. + tee default value is None, means output will not be logged. """ # subprocess.kill() can leave descendants running # and halting the execution. Using psutil to @@ -159,6 +162,24 @@ def run_command(cmd, timeout=None, silent=False): else: timeout_flag[0] = True + # function to append the given msg into the log_file + def tee_log(msg=None, log_file=None): + if (msg is None) or (log_file is None): + return + + try: + f = open(log_file, 'a') + except IOError as e: + msg = "Failed to open file %s: " % log_file + wok_log.error("%s %s", msg, e) + return + msg += '\n' + try: + f.write(msg) + except TypeError: + f.write(msg.encode('utf_8')) + f.close() + proc = None timer = None timeout_flag = [False] @@ -171,8 +192,33 @@ 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 is not None: + if os.path.exists(tee): + os.remove(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, tee) + out = ''.join(output) + error = proc.stderr.read() + else: + out, error = proc.communicate() if out: wok_log.debug("out:\n%s", out) -- 2.5.0

Reviewed-By: Ramon Medeiros <ramonn@br.ibm.com> -- Ramon Nunes Medeiros Kimchi Developer Linux Technology Center Brazil IBM Systems & Technology Group Phone : +55 19 2132 7878 ramonn@br.ibm.com

Reviewed-by: Daniel Barboza <dhbarboza82@gmail.com> On 12/28/2015 10:54 AM, pvital@linux.vnet.ibm.com wrote:
From: Paulo Vital <pvital@linux.vnet.ibm.com>
V4 -> V5: - Added try/exception to control file IO.
V3 -> V4: - PEP8 fixes.
V2 -> V3: - Changed the place of the log_file creation control.
V1 -> V2: - Removed fixed log file, changing parameter of run_command() method to accept the path of the log file instead of a boolean.
V1:
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.
Paulo Vital (1): Make run_command log its output into a file.
src/wok/utils.py | 50 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-)
-- 2.5.0
_______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel

Patch applied to the master branch of https://github.com/danielhb/wok.git Thanks! On 12/28/2015 10:54 AM, pvital@linux.vnet.ibm.com wrote:
From: Paulo Vital <pvital@linux.vnet.ibm.com>
V4 -> V5: - Added try/exception to control file IO.
V3 -> V4: - PEP8 fixes.
V2 -> V3: - Changed the place of the log_file creation control.
V1 -> V2: - Removed fixed log file, changing parameter of run_command() method to accept the path of the log file instead of a boolean.
V1:
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.
Paulo Vital (1): Make run_command log its output into a file.
src/wok/utils.py | 50 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-)
-- 2.5.0
_______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel
participants (4)
-
Aline Manera
-
Daniel Henrique Barboza
-
pvital@linux.vnet.ibm.com
-
Ramon Medeiros