我正在尝试在python中找到一种方法,将脚本执行日志以pythonic方式重定向到文件以及stdout
。有没有简单的方法来实现这个目标?
答案 0 :(得分:54)
使用记录模块(http://docs.python.org/library/logging.html):
import logging
logger = logging.getLogger('scope.name')
file_log_handler = logging.FileHandler('logfile.log')
logger.addHandler(file_log_handler)
stderr_log_handler = logging.StreamHandler()
logger.addHandler(stderr_log_handler)
# nice output format
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_log_handler.setFormatter(formatter)
stderr_log_handler.setFormatter(formatter)
logger.info('Info message')
logger.error('Error message')
答案 1 :(得分:36)
我想出了这个[未经测试的]
import sys
class Tee(object):
def __init__(self, *files):
self.files = files
def write(self, obj):
for f in self.files:
f.write(obj)
f.flush() # If you want the output to be visible immediately
def flush(self) :
for f in self.files:
f.flush()
f = open('out.txt', 'w')
original = sys.stdout
sys.stdout = Tee(sys.stdout, f)
print "test" # This will go to stdout and the file out.txt
#use the original
sys.stdout = original
print "This won't appear on file" # Only on stdout
f.close()
python中的 print>>xyz
期望write()
中的xyz
函数。您可以使用自己的自定义对象。或者,您也可以让sys.stdout引用您的对象,在这种情况下,即使没有>>xyz
,它也会被编辑。
答案 2 :(得分:7)
我只想建立在Serpens的答案并添加一行:
logger.setLevel('DEBUG')
这将允许您选择记录的消息级别。
例如在Serpens示例中,
logger.info('Info message')
不会被记录,因为它默认只记录警告及以上。
有关所用级别的更多信息,请参阅here
答案 3 :(得分:3)
您应该使用内置此功能的logging
库。您只需将处理程序添加到记录器以确定将输出发送到何处。
答案 4 :(得分:3)
可能是最短的解决方案:
def printLog(*args, **kwargs):
print(*args, **kwargs)
with open('output.out','a') as file:
print(*args, **kwargs, file=file)
printLog('hello world')
写下你好世界'到sys.stdout
和output.out
,其工作方式与print()完全相同。
注意:强>
请不要为printLog函数指定file参数。不支持printLog('test',file='output2.out')
之类的通话。
答案 5 :(得分:1)
最简单的解决方案是重定向标准输出。在您的python程序文件中使用以下内容:
if __name__ == "__main__":
sys.stdout = open('file.log', 'w')
#sys.stdout = open('/dev/null', 'w')
main()
任何标准输出(例如print 'hi there'
的输出)都将重定向到file.log
,或者如果取消注释第二行,任何输出都将被抑制。
答案 6 :(得分:0)
创建输出文件和自定义函数:
outputFile = open('outputfile.log', 'w')
def printing(text):
print(text)
if outputFile:
outputFile.write(str(text))
然后,在代码中而不是print(text)中调用打印功能。
printing("START")
printing(datetime.datetime.now())
printing("COMPLETE")
printing(datetime.datetime.now())
答案 7 :(得分:0)
这是对@UltraInstinct的Tee类的一个小改进,该类被修改为上下文管理器,并且捕获了所有异常。
import traceback
import sys
# Context manager that copies stdout and any exceptions to a log file
class Tee(object):
def __init__(self, filename):
self.file = open(filename, 'w')
self.stdout = sys.stdout
def __enter__(self):
sys.stdout = self
def __exit__(self, exc_type, exc_value, tb):
sys.stdout = self.stdout
if exc_type is not None:
self.file.write(traceback.format_exc())
self.file.close()
def write(self, data):
self.file.write(data)
self.stdout.write(data)
def flush(self):
self.file.flush()
self.stdout.flush()
要使用上下文管理器,请执行以下操作:
print("Print")
with Tee('test.txt'):
print("Print+Write")
raise Exception("Test")
print("Print")