我有一个使用RotatingFileHandler进行日志记录的Python程序。日志文件处理程序以独占模式(一次)打开日志文件,并使其保持打开状态,直到应用程序关闭。问题是,我需要允许其他进程在Python程序仍在运行时读取日志文件。
在以前使用C++的项目中,我创建了一个队列记录器。它维护了一个日志条目队列。辅助工作线程将定期检查队列,如果有任何条目,则打开日志文件,将条目转储到文件,并立即关闭文件,直到有更多日志条目排队。这意味着(在处理器时间内) >99%的时间,该文件将被关闭,并可供其他进程窥视日志文件。
(根据一些挖掘,我的印象是Python日志记录类已经处理了日志条目的排队……这不是我要问的部分。)
在Python中有没有一种简单的方法来实现一个常闭的日志文件处理程序?(最好不必添加第三方库或子系统。)
发布于 2018-07-20 17:28:53
正如评论中所建议的,我倾向于使用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
中进行适当的错误处理(文件被另一个进程/等删除/锁定)。
发布于 2018-07-11 06:08:01
在我看来,创建一个单独的线程来管理这个特定的主题。正如你所指出的,这将是最好的策略。
该线程可以对其他程序执行读/写操作。
您可以使用日志记录库在python中完美地设计这个线程。
另一种策略是使用像Sentry或Kibana这样的系统
https://stackoverflow.com/questions/51274541
复制相似问题