[Kimchi-devel] [PATCH] [Wok] Make run_command log its output into a file.

pvital at linux.vnet.ibm.com pvital at linux.vnet.ibm.com
Mon Dec 21 15:57:52 UTC 2015


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'
 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