Source code for safe_syslog_handler.handlers

# -*- coding: utf-8 -*-

import errno
from logging.handlers import SysLogHandler
import socket
import sys


[docs]class SafeSysLogHandler(SysLogHandler): """ A handler class that inherits from `logging.handlers.SyslogHandler`. If using `socket.SOCK_STREAM` as the sockettype and it's not using a unixsocket, then this handler will try to restore the socket's connection if target go down. It will supress any `[Errno 32] Broken pipe` exception that might occour during the emission of the message, and instead will try to reconect the socket. If any socket.error exception occours during this reconnection, then this error is handled by `logging.handlers.SyslogHandler`. That is, it will try to traceback the exception into `sys.stderr`. """
[docs] def is_socketstream_and_not_unixsocket(self): return self.socktype == socket.SOCK_STREAM and not self.unixsocket
[docs] def recreate_socket(self): self.socket.close() self.socket = socket.socket(socket.AF_INET, self.socktype)
[docs] def retry_socketstream_connection(self, record): self.recreate_socket() try: self.socket.connect(self.address) except socket.error as e: """ this connection error is handled by SyslogHandler that basically will try to traceback into sys.stderr """ SysLogHandler.handleError(self, record)
[docs] def handleError(self, record): # not sure if it should check for # raiseException and sys.stderr here, just as it's verified in here: # https://hg.python.org/cpython/file/2.7/Lib/logging/__init__.py#l808 ei = sys.exc_info() if isinstance(ei[1], socket.error): sock_error = ei[1] if sock_error.errno == errno.EPIPE and self.is_socketstream_and_not_unixsocket(): del ei self.retry_socketstream_connection(record) """ will suppress exception so wont call the baseclasse handleError in here """ return SysLogHandler.handleError(self, record)