https://www.zhihu.com/question/602070964
Python 的 logging
模块提供了一个灵活的框架用于发出日志消息,我们可以将 Python 程序中的所有输出都重定向到这个框架,从而记录在日志中。
为了实现这一点,你可以定义一个类,这个类的实例将会模拟文件对象(就像 sys.stdout
或 sys.stderr
)。然后,你可以将 sys.stdout
和 sys.stderr
重定向到这个模拟的文件对象。这个类的 write
方法会被调用每当一个 print
语句或者一个异常被输出。这个 write
方法可以调用 logging
模块将消息记录在日志中。
以下是一个简单的实现:
import sys
import logging
class LoggerWriter:
def __init__(self, level):
# 创建一个logger
self.logger = logging.getLogger("mylogger")
self.logger.setLevel(logging.DEBUG)
# 创建一个handler,用于写入日志文件
fh = logging.FileHandler('test.log', encoding='utf-8')
fh.setLevel(logging.DEBUG)
# 再创建一个handler,用于输出到控制台
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
# 定义handler的输出格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)
ch.setFormatter(formatter)
# 给logger添加handler
self.logger.addHandler(fh)
self.logger.addHandler(ch)
# 日志级别
self.level = level
def write(self, message):
# 只有message非空时才记录
if message.rstrip() != "":
self.logger.log(self.level, message.rstrip())
def flush(self):
# 这个方法是为了满足文件对象的接口,但是什么都不需要做
pass
# 重定向标准输出和错误输出
sys.stdout = LoggerWriter(logging.INFO)
sys.stderr = LoggerWriter(logging.ERROR)
# 现在,当我们使用 print 语句或者发生异常时,这些消息都会记录在日志中
print("Hello, world!")
raise Exception("Oh no, something went wrong!")
在这个代码中,我们首先定义了一个 LoggerWriter
类,它有一个 write
方法和一个 flush
方法。然后,我们创建了这个类的两个实例,一个用于记录标准输出(sys.stdout
),一个用于记录错误输出(sys.stderr
)。最后,我们使用 print
语句和引发一个异常来测试这个设置。
这种方法可以让你将所有输出到屏幕的打印记录在日志中,但是请注意,这也意味着你将无法在交互式会话中看到输出,除非你查看日志文件。如果你仍然希望在控制台看到输出,你可以在 write
方法中同时调用 print
函数。