[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