我有一个使用RotatingFileHandler进行记录的Python程序。日志文件处理程序以独占模式(一次)打开日志文件,并保持打开状态,直到应用程序关闭。问题是我需要允许其他进程在Python程序仍在运行时读取日志文件。
在过去使用C ++的项目中,我创建了一个排队的记录器。它维护了一个日志条目队列。辅助工作线程将定期检查队列,如果有任何条目,请打开日志文件,将条目转储到文件中,然后立即关闭文件,直到有更多日志条目排队。这意味着(在处理器时间中)> 99%的时间,文件将被关闭,并可供其他进程窥探日志文件。
(经过一点挖掘,我觉得Python日志记录类已经可以处理日志条目的排队了……这不是我要问的部分。)
有没有一种简单的方法可以在Python中完成常闭的日志文件处理程序? (最好不必添加第三方库或子系统。)
答案 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之类的系统