在Python中使用SocketHandler记录日志时捕获错误

4 投票
2 回答
1862 浏览
提问于 2025-04-15 19:01

我的网页应用程序运行在多个Apache实例上,因此我遇到了多进程日志记录的问题。目前,我使用SocketHandler将日志发送到一个守护进程,这个守护进程通过SocketServer将日志写入一个单独的日志文件(类似于这个例子)。

现在,由于我在使用SocketHandler进行日志记录,我发现很难判断这个socket服务器是否崩溃了。例如,如果我尝试为一个没有监听的socket服务器创建SocketHandler,系统并不会抛出任何异常。我希望能够捕捉到这种错误并将其记录到文件中。

我的问题是,在使用SocketHandler进行日志记录时,如何判断所使用的socket当前是否在监听?

2 个回答

1

目前的这个“弹性”实现方式是无法做到你想要的那样的。“弹性”在这里的意思是,SocketHandler 会在遇到问题时自动尝试重新打开连接。

你只需要重启服务器,处理程序最终会重新连接上。

5

当创建一个套接字(socket)时,如果失败了(比如没有服务器在监听),默认的做法是下次记录事件时再试一次,并且会使用一种叫做指数退避的算法来控制重试的时间间隔。下面是一些你可以尝试的方法:

  1. 你可以创建一个新的类,继承自 SocketHandler,重写 createSocket 方法,然后在你的实现中处理异常。
  2. 要注意,如果 SocketHandler 实例的 sock 属性是 None,那就说明还没有创建套接字。如果在你记录事件后这个值还是 None,那么很可能 SocketHandler 并没有发送这个事件。
  3. 要知道,处理器的 makeSocket 方法是用来实际创建和连接套接字的。所以,你可以在记录任何内容之前自己调用 makeSocket,如果它抛出异常,那说明你的服务器可能没有在监听。如果成功返回,那你可以直接关闭这个返回的值。
  4. 你可以创建一个新的类,继承自 SocketHandler,重写 emit 方法,并在你的子类中引用一个备用的处理器实例(比如 FileHandlerSMTPHandler)。在你的 emit 代码中,尝试使用

    if self.sock is None:
        self.createSocket()
    if self.sock is None:
        # creation failed: do self.alternate_handler.handle(record)
    else:
        # creation succeeded: defer to superclass implementation
    

当然,这样做可能无法捕捉到在发送消息过程中服务器崩溃时发生的错误,但至少可以提醒你服务器存在一些问题。

撰写回答