当python日志服务器恢复联机时,如何将未发送的日志发送到它?

2024-04-28 10:18:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经成功地在一台计算机上创建了一个中央python日志服务器,并且可以从多个rpi登录到它。但是,当日志服务器关闭时,日志就会丢失。有没有一种方法可以存储日志(以持久的形式)直到日志服务器再次可用?在

我看过一些程序,比如graylog,sentry和logstash,但是没有找到任何选项来做这个。在

任何帮助都将不胜感激。在


Tags: 方法程序服务器graylog选项计算机rpi形式
1条回答
网友
1楼 · 发布于 2024-04-28 10:18:37

我想出了一个定制的套接字处理程序,它在传递之前缓冲未发送的记录。此缓冲区存储在二进制文件中,因此未发送的日志将在程序重新启动或系统关闭期间保留。在

import os, os.path
import logging.handlers
import pickle

class BufferingSocketHandler(logging.handlers.SocketHandler):
    def __init__(self, host, port, buffer_file):
        super().__init__(host, port)
        self._buffer = FileBuffer(buffer_file)

    @property  # getter only
    def buffer(self):
        return self._buffer

    def _emit(self, record):
        try:
            s = self.makePickle(record)
            self.send(s)
            return (self.sock is not None)
        except Exception:
            self.handleError(record)
            return False

    def emit(self, record):
        self.send_buffer()
        success = self._emit(record)
        if not success:
            self.buffer.append(record)

    def send_buffer(self):
        try:
            self.acquire()
            success = True
            for item in self.buffer:
                success &= self._emit(item)
            if success:
                self.buffer.flush()
        finally:
            self.release()


class FileBuffer:
    def __init__(self, fname):
        self.fname = fname

    @property
    def size(self):
        return int(os.path.isfile(self.fname) \
                and os.path.getsize(self.fname))

    def append(self, data):
        with open(self.fname, 'ba') as f:
            pickle.dump(data, f)

    def __iter__(self):
        if self.size > 0:
            try:
                with open(self.fname, 'br') as f:
                    while True:
                        yield pickle.load(f)
            except EOFError:
                return

    def flush(self):
        if self.size > 0:
            os.remove(self.fname)

当创建BufferingSocketHandler时,您必须添加一个缓冲区文件名,未送达的日志记录将保存到传递之前。正在使用^{}序列化数据,有关详细信息,请参阅上面示例中的FileBuffer类。但是,这是一个非常简单的实现,为了提高线程安全性,您可能需要添加一个数据库来存储日志记录。在

处理程序基于logging模块的^{},它的source对于理解这个修改背后的逻辑也很有意思。在

使用the logging Cookbook's example,只需导入此自定义处理程序并将其添加到根日志记录器:

^{pr2}$

这段代码只使用python3进行测试,我不知道它是否与Python-2兼容。在

相关问题 更多 >