Python subprocess.call() 为每个 stdout 和 stderr 行添加前缀

Fab*_*aze 6 python logging datetime subprocess stdout

我正在使用 python 运行一些 shell 脚本、RScript、python 程序等。这些程序可能会运行很长时间,并且可能会向 stdout 和 stderr 输出大量(日志记录)信息。我正在使用以下(Python 2.6)代码,它运行良好:

stdoutFile=open('stdout.txt', 'a')
stderrFile=open('stderr.txt', 'a')
subprocess.call(SHELL_COMMAND, shell=True, stdout=stdoutFile, stderr=stderrFile)
stdoutFile.close()
stderrFile.close()
Run Code Online (Sandbox Code Playgroud)

这主要是记录到文件的信息,并且该信息可以在很长一段时间内生成。因此我想知道是否可以在每一行前面加上日期和时间?

例如,如果我当前要记录:

Started
Part A done
Part B done
Finished
Run Code Online (Sandbox Code Playgroud)

那么我希望它是:

[2012-12-18 10:44:23] Started
[2012-12-18 12:26:23] Part A done
[2012-12-18 14:01:56] Part B done
[2012-12-18 22:59:01] Finished
Run Code Online (Sandbox Code Playgroud)

注意:修改我运行的程序不是一个选项,因为这个 python 代码有点像这些程序的包装器。

Sil*_*Ray 5

不要向stdoutstderr的参数提供文件,而是直接subprocess.call()创建一个对象并创建s,然后读取此管理器脚本中的这些管道,并在写入所需的任何日志文件之前添加所需的任何标记。PopenPIPE

\n\n
def flush_streams_to_logs(proc, stdout_log, stderr_log):\n\xc2\xa0 \xc2\xa0 pipe_data = proc.communicate()\n\xc2\xa0 \xc2\xa0 for data, log in zip(pipe_data, (stdout_log, stderr_log)):\n\xc2\xa0 \xc2\xa0 \xc2\xa0 \xc2\xa0 # Add whatever extra text you want on each logged message here\n\xc2\xa0 \xc2\xa0 \xc2\xa0 \xc2\xa0 log.write(str(data) + '\\n')\n\nwith open('stdout.txt', 'a') as stdout_log, open('stderr.txt', 'a') as stderr_log:\n    proc = subprocess.Popen(SHELL_COMMAND, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n    while proc.returncode is None:\n        flush_streams_to_logs(proc, stdout_log, stderr_log)\n    flush_streams_to_logs(proc, stdout_log, stderr_log)\n
Run Code Online (Sandbox Code Playgroud)\n\n

请注意,它communicate()会阻塞,直到子进程退出。您可能希望直接使用子进程的流,以便获得更多实时日志记录,但随后您必须自己处理并发和缓冲区填充状态。

\n