如何将sys.stdout复制到python中的日志文件?

问题:

编辑:由于看起来没有解决方案,或者我正在做一些非标准的事情,没有人知道 – 我会修改我的问题,还要问:当一个python应用程序制作时,最好的方法是完成日志记录很多系统调用?
我的应用有两种模式。在交互模式下,我希望所有输出都转到屏幕以及日志文件,包括任何系统调用的输出。在守护进程模式下,所有输出都将转到日志中。守护进程模式使用os.dup2()非常有用。我无法找到一种方法来将所有输出“tee”到交互模式的日志中,而无需修改每个系统调用。
换句话说,我希望命令行’tee’的功能用于由python应用程序生成的任何输出包括系统调用输出
澄清:
要重定向所有输出,我做这样的事情,它的工作原理很好:

# open our log file
so = se = open("%s.log" % self.name, 'w', 0)

# re-open stdout without buffering
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)

# redirect stdout and stderr to the log file opened above
os.dup2(so.fileno(), sys.stdout.fileno())
os.dup2(se.fileno(), sys.stderr.fileno())

关于这一点的好处是,它不需要其他代码的特殊打印调用。代码还运行一些shell命令,所以很好,不必单独处理每个输出。
简单来说,除了duplicate而不是重定向,我也要这样做。
起初脸红,我以为只要扭转dup2就行了。为什么不呢这是我的测试:

import os, sys

### my broken solution:
so = se = open("a.log", 'w', 0)
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)

os.dup2(sys.stdout.fileno(), so.fileno())
os.dup2(sys.stderr.fileno(), se.fileno())
###

print "kljhf sdf"

os.spawnve("P_WAIT", "/bin/ls", ["/bin/ls"], {})
os.execve("/bin/ls", ["/bin/ls"], os.environ)

文件“a.log”应与屏幕上显示的相同。

回答:

由于您很容易从代码中产生外部流程,因此您可以使用tee本身。我不知道任何Unix系统调用完全符合tee的功能。

import subprocess, os, sys

# Unbuffer output
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)

tee = subprocess.Popen(["tee", "log.txt"], stdin=subprocess.PIPE)
os.dup2(tee.stdin.fileno(), sys.stdout.fileno())
os.dup2(tee.stdin.fileno(), sys.stderr.fileno())

print "\nstdout"
print >>sys.stderr, "stderr"
os.spawnve("P_WAIT", "/bin/ls", ["/bin/ls"], {})
os.execve("/bin/ls", ["/bin/ls"], os.environ)

您还可以使用multiprocessing包(或使用processing,如果您使用Python 2.5或更早版本)效仿tee

 
 
Code问答: http://codewenda.com/topics/python/
Stackoverflow: How do I duplicate sys.stdout to a log file in python?

*转载请注明本文链接以及stackoverflow的英文链接

发表评论

电子邮件地址不会被公开。 必填项已用*标注

46 − = 44