使 Python 记录器记录所有 stdout 和 stderr 消息

Eri*_* H. 2 python logging stdout tee

使用 python logging 包,并编写一个类 Log,我想将 stdout 和 stderr 发送到日志文件:

log = Log("log.txt")
print "line1"
print "line2"
print >>sys.stderr, "err1"
del log
print "line to screen only"
Run Code Online (Sandbox Code Playgroud)

输出日志文件将包含:

16/11/2017 09:51:58 INFO - line1
16/11/2017 09:51:58 INFO - line2
16/11/2017 09:51:58 INFO - err1
Run Code Online (Sandbox Code Playgroud)

知道如何编写这个 Log 类,保持“日志”包(时间戳,...)的优势吗?

Che*_* A. 6

实现您所要求的正确方法是使用 Logger 对象。它为您提供了更多的灵活性。这个对象可以绑定到多个处理程序;您需要一个流sys.stdout处理程序来记录消息,并需要一个文件处理程序将其记录到文件中。然后,您可以在单个命令中打印到屏幕并登录到文件。

import logging

# create logger 
logger = logging.getLogger('example')
logger.setLevel(logging.INFO)

# create file handler which logs messages
fh = logging.FileHandler('fh.log')
fh.setLevel(logging.DEBUG)

# create console handler to print to screen
ch = logging.StreamHandler()
ch.setLevel(logging.INFO)

# create formatter and add it to the handlers
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)
ch.setFormatter(formatter)

# add the handlers to the logger
logger.addHandler(fh)
logger.addHandler(ch)
Run Code Online (Sandbox Code Playgroud)

现在每个调用logger.info(msg)都会被打印到屏幕上,并写入fh.log文件。


还有另一种方法,您可以在其中替换sys.stdoutsys.stderr流式传输对象。创建一个类并对其进行自定义(此处为原始答案):

import sys

class writer(object):
    _fh = None
    _orig_stdout = sys.stdout

   def __init__(self):
       _fh = open('logging.log', 'w')

    def write(self, data):
        fp.write(data)
        _orig_stdout.write(data)

    def flush():
        _orig_stdout.flush()

logger = writer()

sys.stdout = logger
sys.stderr = logger
Run Code Online (Sandbox Code Playgroud)