寻找Python方法处理常闭日志文件

时间:2018-07-10 22:06:24

标签: python logging logfile

我有一个使用RotatingFileHandler进行记录的Python程序。日志文件处理程序以独占模式(一次)打开日志文件,并保持打开状态,直到应用程序关闭。问题是我需要允许其他进程在Python程序仍在运行时读取日志文件。

在过去使用C ++的项目中,我创建了一个排队的记录器。它维护了一个日志条目队列。辅助工作线程将定期检查队列,如果有任何条目,请打开日志文件,将条目转储到文件中,然后立即关闭文件,直到有更多日志条目排队。这意味着(在处理器时间中)> 99%的时间,文件将被关闭,并可供其他进程窥探日志文件。

(经过一点挖掘,我觉得Python日志记录类已经可以处理日志条目的排队了……这不是我要问的部分。)

有没有一种简单的方法可以在Python中完成常闭的日志文件处理程序? (最好不必添加第三方库或子系统。)

2 个答案:

答案 0 :(得分:1)

如评论中所建议,我将使用QueueHandler作为单个根处理程序,并结合使用QueueListener来处理到达的新记录。除此之外,自定义RotatingFileHandler是必需的,它将在记录保留后并且队列中没有记录时关闭文件。

免责声明:以下代码未经测试。

import logging
import queue

global que_listener


class MyHandler(logging.RotatingFileHandler):

    def __init__(self, queue, *args, **kwargs):
        super().__init__(*args, delay=True, **kwargs)
        self.queue = queue

    def emit(self, record):
        if self.stream is None:
            self.stream = self._open()
        super().emit(record)
        if self.queue.empty():
            self.stream.close()
            self.stream = None


def init_logging():
    que = queue.Queue(-1)
    root_handler = QueueHandler(que)
    file_handler = MyHandler(que)
    que_listener = QueueListener(que, file_handler)
    root = logging.getLogger()
    root.addHandler(root_handler)
    que_listener.start()  # starts a separate thread to listen for queue updates


def cleanup_logging():  # stop listener on program exit
    que_listener.stop()

我使用了delay=True,因此处理程序将不会像默认行为那样立即在init上打开并锁定文件。另外,由于在持久化记录之间关闭了文件,因此请考虑在emit中进行适当的错误处理(文件已被其他进程删除/锁定,等等)。

答案 1 :(得分:0)

在我看来,似乎创建了一个单独的线程来管理此特定主题。正如您所指出的,这是最好的策略。

该线程可以对其他所有程序执行读/写操作。

您可以使用日志记录库在python中完美设计此线程。

另一种策略是使用诸如Sentry或Kibana之类的系统