python - 将所有 stdout/stderr 全局重定向到记录器

标签 python python-2.7 logging stdout python-2.x

背景

我有一个非常大的 python 应用程序,它启动命令行实用程序来获取它需要的数据片段。我目前只是将 python 启动器脚本重定向到一个日志文件,它为我提供了所有 print() 输出,以及命令行实用程序的输出,即:

python -m launcher.py &> /root/out.log

问题

I've since implemented a proper logger via logging, which lets me format the logging statements more precisely, lets me limit log file size, etc.我已将大部分 print() 语句替换为对记录器的调用。但是,我遇到了一个问题:命令行应用程序的任何输出都没有出现在我的日志中。它反而被转储到控制台。此外,这些程序的启动方式也不尽相同:有些是通过 popen() 启动的,有些是通过 exec() 启动的,有些是通过 os.system( )


问题

有没有办法将所有 stdout/stderr 文本全局重定向到我的日志记录功能,而不必重新编写/修改启动这些命令行的代码工具?我尝试设置我在另一个问题中发现的以下内容:

sys.stderr.write = lambda s: logger.error(s)

但是失败并显示“sys.stderr.write is read-only”。

最佳答案

虽然这不是完整的答案,但它可能会向您显示重定向以适应您的特定情况。不久前我就是这样做的。虽然我不记得我为什么这样做,或者我试图规避的限制是什么,但以下是将 stdoutstderr 重定向到 的类print() 语句。该类随后写入屏幕和文件:

import os
import sys
import datetime

class DebugLogger():

    def __init__(self, filename):
        timestamp = datetime.datetime.strftime(datetime.datetime.utcnow(), 
                                               '%Y-%m-%d-%H-%M-%S-%f')
        #build up full path to filename
        logfile = os.path.join(os.path.dirname(sys.executable), 
                               filename + timestamp)
        self.terminal = sys.stdout
        self.log = open(logfile, 'a')

    def write(self, message):
        timestamp = datetime.datetime.strftime(datetime.datetime.utcnow(), 
                                               ' %Y-%m-%d-%H:%M:%S.%f')
        #write to screen
        self.terminal.write(message)
        #write to file
        self.log.write(timestamp + ' - ' + message)      
        self.flush()

    def flush(self):
        self.terminal.flush()
        self.log.flush()
        os.fsync(self.log.fileno())

    def close(self):
        self.log.close()


def main(debug = False):
    if debug:
        filename = 'blabla'
        sys.stdout = DebugLogger(filename)
        sys.stderr = sys.stdout
    print('test')

if __name__ == '__main__':
    main(debug = True)

关于python - 将所有 stdout/stderr 全局重定向到记录器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48548937/

相关文章:

Python 解析 JSON 并将列表存储到 SQLite 表中

python - 如何使使用 Discord.py 机器人登录的帐户加入特定服务器

ruby - 如何在纯 ruby​​ 应用程序中的 Resque 工作人员内部使用 Logger

python - 带有服务帐户的 Google Cloud Pub Sub

python - 如何让元素粘在 Tkinter 的右下角?

python - 在枚举 python 中包含停止参数的最简单方法?

Python file.write 随着输出文件变大而变慢

python - 附加到 h5py 组

python - 向单元测试中的所有装置添加日志分隔符

c# - 在 C# 中创建日志