Python日志:标准方法如何记录到一个实时对象?

2 投票
1 回答
1558 浏览
提问于 2025-04-18 10:21

我是一名重度使用Vim的用户,打算把我的Python程序完全重写成一个Vim扩展。我的想法是让Vim作为这个程序的文本界面。因为Vim可以完全访问运行中的程序的每个部分,所以我可以通过自己定义的快捷键和命令来实时控制程序的操作,还可以通过Vim窗口查看程序的实时对象(以及它的输出),这样在转换过程中就不需要做太多的工作。

现在我担心的是日志记录的方法。因为Vim和Python将会合为一体,我不需要把日志记录到像文件或套接字这样的单独地方,我只需要把日志记录到一个实时的Python对象,比如一个列表,然后通过Vim窗口查看这个列表。之前我有一个顶层的StreamLogger,它把日志记录到标准输出。我想出了一个解决方案,可以无缝地替换它:

import threading
import datetime

class ObjectLogger:
    mapping= {
        'critical': 5,
        'error':    4,
        'warning':  3,
        'info':     2,
        'debug':    1,
        'notset':   0,
    }

    def __init__(self):
        self.data= []   # logging output
        self._lock= threading.Lock()    
        self._level= 0

    # ----------------- methods for setting logging level -----------------
    def set_critical(self):
        self._level= ObjectLogger.mapping['critical']

    # ------------------------------ logging ------------------------------
    def debug(self, message):
        if self._level > ObjectLogger.mapping['debug']:
            return None
        self._lock.acquire()
        self.data.append(datetime.datetime.now().strftime('%Y-%m-%d_%H:%M:%S') + ' >> ' + message)
        self._lock.release()

    # ---------------------- clear previous loggings ----------------------
    def clear(self):
        self._lock.acquire()
        del self.data[:]
        self._lock.release()

我的问题是,有没有更好的方法来做到这一点?有没有标准的方法可以记录到一个实时的Python对象?我查过MemoryHandler,但似乎不太符合我的需求,谢谢。

1 个回答

2

你在寻找的是 BufferingHandler,这个东西可以让你使用普通的Python日志功能。不过,它不会把日志信息写到硬盘上,而是会把这些信息存储在一个列表里,保持原样,方便你随意处理。

>>> import logging.handlers
>>> object_handler = logging.handlers.BufferingHandler(float('inf'))
>>> logging.root.handlers.append(object_handler)
>>> logging.root.level = logging.DEBUG
>>> something = object()
>>> object_handler.buffer
[]
>>> logging.info("something happened", something)
>>> object_handler.buffer
[<logging.LogRecord object at ...>]
>>> object_handler.buffer[-1].args[0] is something
True

撰写回答