Python:将sys.stdout和sys.stderr都捕获为日志文件

时间:2016-02-04 06:21:55

标签: python python-2.7 logging python-2.6 stderr

粗略地说,我想把它移植到纯Python:

#!/bin/bash

{
    python test.py
} &> /tmp/test.log

由于某些未知原因,这项工作无效:

import os.path, sys
import tempfile

with open(os.path.join(tempfile.gettempdir(), "test.log"), "a") as fp:
    sys.stdout = sys.stderr = fp
    raise Exception("I'm dying")

当我在CentOS x86_64上使用Python 2.6.6,Python 2.7.8和Python 3.4.2测试时,生成的test.log为空(我在控制台上看不到任何内容)。

但理想情况下,我想要一个Python 2.6的解决方案。

(目前,只要任何数据不会消失在一个数据中,就可以使用来自stdoutstderr或多线程的混合输出来混淆日志文件。黑洞。)

向我展示一个简洁易用的解决方案,该解决方案经过确认可以使用sys.stderr上的异常堆栈跟踪。(最好不是os.dup2

3 个答案:

答案 0 :(得分:2)

您可以使用以下方法:

with output_to_file('test.log'):
    print('hello')
    raise Exception('I am dying')

用法是:

cat test.log

hello Traceback (most recent call last): File "<ipython-input-3-a3b702c7b741>", line 20, in outputi_to_file yield File "<ipython-input-4-f879d82580b2>", line 3, in <module> raise Exception('I am dying') Exception: I am dying 产生:

{{1}}

答案 1 :(得分:2)

请记住with阻止后文件对象关闭:)

简单地使用:

sys.stdout = sys.stderr = open("test.log","w")
raise Exception("Dead")

退出后test.log的内容:

Traceback (most recent call last):
  File "test.py", line 5, in <module>
    raise Exception("Dead")
Exception: Dead

答案 2 :(得分:1)

这对我有用:

#!/usr/bin/env python
from __future__ import print_function
import os, os.path, sys, tempfile

old_out = os.dup(sys.stdout.fileno())
old_err = os.dup(sys.stderr.fileno())
with open(os.path.join(tempfile.gettempdir(), "test.log"), "a") as fp:
    fd = fp.fileno()
    os.dup2(fd, sys.stdout.fileno())
    os.dup2(fd, sys.stderr.fileno())
    print("Testing")
    print('testing errs', file=sys.stderr)
    raise Exception("I'm dying")

future 仅用于使用相同的示例更清晰地处理Python2或Python3。 (我还更改了 raise 语句以实例化异常,因为异常已被弃用了很长时间而且Python3下它们没有得到正确支持。

old_ *值就是我们想要在使用重定向文件后恢复原始标准输出和/或stderr。