在Python中使用SocketHandler记录日志时捕获错误
我的网页应用程序运行在多个Apache实例上,因此我遇到了多进程日志记录的问题。目前,我使用SocketHandler将日志发送到一个守护进程,这个守护进程通过SocketServer将日志写入一个单独的日志文件(类似于这个例子)。
现在,由于我在使用SocketHandler进行日志记录,我发现很难判断这个socket服务器是否崩溃了。例如,如果我尝试为一个没有监听的socket服务器创建SocketHandler,系统并不会抛出任何异常。我希望能够捕捉到这种错误并将其记录到文件中。
我的问题是,在使用SocketHandler进行日志记录时,如何判断所使用的socket当前是否在监听?
2 个回答
1
目前的这个“弹性”实现方式是无法做到你想要的那样的。“弹性”在这里的意思是,SocketHandler
会在遇到问题时自动尝试重新打开连接。
你只需要重启服务器,处理程序最终会重新连接上。
5
当创建一个套接字(socket)时,如果失败了(比如没有服务器在监听),默认的做法是下次记录事件时再试一次,并且会使用一种叫做指数退避的算法来控制重试的时间间隔。下面是一些你可以尝试的方法:
- 你可以创建一个新的类,继承自
SocketHandler
,重写createSocket
方法,然后在你的实现中处理异常。 - 要注意,如果
SocketHandler
实例的sock
属性是None
,那就说明还没有创建套接字。如果在你记录事件后这个值还是None
,那么很可能SocketHandler
并没有发送这个事件。 - 要知道,处理器的
makeSocket
方法是用来实际创建和连接套接字的。所以,你可以在记录任何内容之前自己调用makeSocket
,如果它抛出异常,那说明你的服务器可能没有在监听。如果成功返回,那你可以直接关闭这个返回的值。 你可以创建一个新的类,继承自
SocketHandler
,重写emit
方法,并在你的子类中引用一个备用的处理器实例(比如FileHandler
或SMTPHandler
)。在你的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
当然,这样做可能无法捕捉到在发送消息过程中服务器崩溃时发生的错误,但至少可以提醒你服务器存在一些问题。