简体   繁体   English

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

[英]Making Python loggers log all stdout and stderr messages

Using the python logging package, and writing a class Log, I'd like to tee stdout and stderr to a log file : 使用python日志记录包,并编写一个Log类,我想将stdout和stderr放入日志文件:

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

The output log file would contain : 输出日志文件将包含:

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

Any idea how to write this Log class, keeping the advantages of the "logging" package (time-stamps, ...) ? 任何想法如何编写此Log类,同时保留“ logging”包的优点(时间戳,...)?

The right way to achieve what you ask is to use Logger object. 实现您要求的正确方法是使用Logger对象。 It gives you much more flexability. 它为您提供了更多的灵活性。 This object can be bound to multiple handlers; 该对象可以绑定到多个处理程序。 You need a streamhandler to log message to sys.stdout and a file handler to log it to a file. 您需要一个流处理程序以将消息记录到sys.stdout以及一个文件处理程序以将其记录到文件。 You then both print to the screen and log to a file in a single command. 然后,您都可以打印到屏幕上并通过单个命令登录到文件。

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)

Now every call to logger.info(msg) will be printed both to the screen, and written to fh.log file. 现在,每次对logger.info(msg)调用都将被打印到屏幕上,并写入fh.log文件。


There is another way, where you can replace sys.stdout and sys.stderr stream objects. 还有另一种方法,您可以替换sys.stdoutsys.stderr流对象。 Create a class and customize it ( 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

I made this package to do exactly what you said. 我做了这个包裹来照你说的做。

pip install stdlogging

After installed from pip, you can capture any output by logging. 从pip安装后,您可以通过记录捕获任何输出。 But be careful to capture stdout because it's very fragile. 但是请小心捕获stdout,因为它非常脆弱。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM