Skip to content

Commit

Permalink
bpo-44291: Fix reconnection in logging.handlers.SysLogHandler (GH-26490)
Browse files Browse the repository at this point in the history
  • Loading branch information
cybergrind committed Aug 5, 2021
1 parent 8f010dc commit 3d315c3
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 25 deletions.
63 changes: 38 additions & 25 deletions Lib/logging/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -835,6 +835,36 @@ def __init__(self, address=('localhost', SYSLOG_UDP_PORT),
self.address = address
self.facility = facility
self.socktype = socktype
self.socket = None
self.createSocket()

def _connect_unixsocket(self, address):
use_socktype = self.socktype
if use_socktype is None:
use_socktype = socket.SOCK_DGRAM
self.socket = socket.socket(socket.AF_UNIX, use_socktype)
try:
self.socket.connect(address)
# it worked, so set self.socktype to the used type
self.socktype = use_socktype
except OSError:
self.socket.close()
if self.socktype is not None:
# user didn't specify falling back, so fail
raise
use_socktype = socket.SOCK_STREAM
self.socket = socket.socket(socket.AF_UNIX, use_socktype)
try:
self.socket.connect(address)
# it worked, so set self.socktype to the used type
self.socktype = use_socktype
except OSError:
self.socket.close()
raise

def createSocket(self):
address = self.address
socktype = self.socktype

if isinstance(address, str):
self.unixsocket = True
Expand Down Expand Up @@ -871,30 +901,6 @@ def __init__(self, address=('localhost', SYSLOG_UDP_PORT),
self.socket = sock
self.socktype = socktype

def _connect_unixsocket(self, address):
use_socktype = self.socktype
if use_socktype is None:
use_socktype = socket.SOCK_DGRAM
self.socket = socket.socket(socket.AF_UNIX, use_socktype)
try:
self.socket.connect(address)
# it worked, so set self.socktype to the used type
self.socktype = use_socktype
except OSError:
self.socket.close()
if self.socktype is not None:
# user didn't specify falling back, so fail
raise
use_socktype = socket.SOCK_STREAM
self.socket = socket.socket(socket.AF_UNIX, use_socktype)
try:
self.socket.connect(address)
# it worked, so set self.socktype to the used type
self.socktype = use_socktype
except OSError:
self.socket.close()
raise

def encodePriority(self, facility, priority):
"""
Encode the facility and priority. You can pass in strings or
Expand All @@ -914,7 +920,10 @@ def close(self):
"""
self.acquire()
try:
self.socket.close()
sock = self.socket
if sock:
self.socket = None
sock.close()
logging.Handler.close(self)
finally:
self.release()
Expand Down Expand Up @@ -954,6 +963,10 @@ def emit(self, record):
# Message is a string. Convert to bytes as required by RFC 5424
msg = msg.encode('utf-8')
msg = prio + msg

if not self.socket:
self.createSocket()

if self.unixsocket:
try:
self.socket.send(msg)
Expand Down
8 changes: 8 additions & 0 deletions Lib/test/test_logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -1942,6 +1942,14 @@ def test_output(self):
self.handled.wait()
self.assertEqual(self.log_output, b'<11>h\xc3\xa4m-sp\xc3\xa4m')

def test_udp_reconnection(self):
logger = logging.getLogger("slh")
self.sl_hdlr.close()
self.handled.clear()
logger.error("sp\xe4m")
self.handled.wait(0.1)
self.assertEqual(self.log_output, b'<11>sp\xc3\xa4m\x00')

@unittest.skipUnless(hasattr(socket, "AF_UNIX"), "Unix sockets required")
class UnixSysLogHandlerTest(SysLogHandlerTest):

Expand Down

0 comments on commit 3d315c3

Please sign in to comment.