【问题标题】:Making Python loggers log all stdout and stderr messages让 Python 记录器记录所有 stdout 和 stderr 消息
【发布时间】:2018-04-29 17:54:48
【问题描述】:

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

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

输出日志文件将包含:

16/11/2017 09:51:58 INFO - line1
16/11/2017 09:51:58 INFO - line2
16/11/2017 09:51:58 INFO - err1

知道如何编写这个 Log 类,同时保持“logging”包的优点(时间戳,...)?

【问题讨论】:

标签: python logging stdout tee


【解决方案1】:

实现您所要求的正确方法是使用 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)

现在对logger.info(msg) 的每次调用都将打印到屏幕上,并写入fh.log 文件。


还有另一种方法,您可以替换 sys.stdoutsys.stderr 流对象。创建一个类并自定义它(original answer here):

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

【讨论】:

  • 没有。我希望保留我的“打印”命令 - 如果可能的话 - 并使用记录器的优势发送到日志文件。类似于stackoverflow.com/questions/616645/…中的“多文件类”(shx2 的回答)
  • 检查我更新的答案。然后使用writer 类,但我强烈建议您使用记录器。如果您现在不这样做,相信我,如果您继续开发此代码,您将来会这样做。
  • 写方法中的fp是什么?
  • 我在 jupyter notebook 中使用了第二个代码,但出现了错误:NameError: name '_orig_stdout' is not defined_orig_stdout.flush()
【解决方案2】:

我让this package 完全按照你说的去做。

pip install stdlogging

从 pip 安装后,您可以通过日志记录捕获任何输出。但要小心捕获标准输出,因为它非常脆弱。

import stdlogging
stdlogging.enable(stdout=False, stderror=True)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-10-15
    • 2014-07-14
    • 2011-06-22
    • 1970-01-01
    • 1970-01-01
    • 2013-09-17
    • 2013-06-09
    • 1970-01-01
    相关资源
    最近更新 更多