作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个使用 RotatingFileHandler 进行日志记录的 Python 程序。日志文件处理程序以独占模式打开日志文件(一次)并保持打开状态直到应用程序关闭。问题是我需要在 Python 程序仍在运行时允许其他进程读取日志文件。
在过去使用 C++ 的项目中,我创建了一个排队记录器。它维护一个日志条目队列。辅助工作线程将定期检查队列,如果有任何条目,则打开日志文件,将条目转储到文件中,并立即关闭文件,直到更多日志条目排队。这意味着(在处理器时间内)>99% 的时间,该文件将被关闭并可供其他进程查看日志文件。
(通过一点挖掘,我的印象是 Python 日志记录类已经处理日志条目的排队......这不是我要问的部分。)
有没有一种简单的方法可以在Python中完成常闭日志文件处理程序? (最好不需要添加第 3 方库或子系统。)
最佳答案
根据评论中的建议,我会使用 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
中进行正确的错误处理(文件被另一个进程删除/锁定等)。
关于python - 寻找常闭日志文件的 Python 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51274541/
我是一名优秀的程序员,十分优秀!