Skip to content

Commit 3d315c3

Browse files
authored
bpo-44291: Fix reconnection in logging.handlers.SysLogHandler (GH-26490)
1 parent 8f010dc commit 3d315c3

File tree

2 files changed

+46
-25
lines changed

2 files changed

+46
-25
lines changed

Lib/logging/handlers.py

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -835,6 +835,36 @@ def __init__(self, address=('localhost', SYSLOG_UDP_PORT),
835835
self.address = address
836836
self.facility = facility
837837
self.socktype = socktype
838+
self.socket = None
839+
self.createSocket()
840+
841+
def _connect_unixsocket(self, address):
842+
use_socktype = self.socktype
843+
if use_socktype is None:
844+
use_socktype = socket.SOCK_DGRAM
845+
self.socket = socket.socket(socket.AF_UNIX, use_socktype)
846+
try:
847+
self.socket.connect(address)
848+
# it worked, so set self.socktype to the used type
849+
self.socktype = use_socktype
850+
except OSError:
851+
self.socket.close()
852+
if self.socktype is not None:
853+
# user didn't specify falling back, so fail
854+
raise
855+
use_socktype = socket.SOCK_STREAM
856+
self.socket = socket.socket(socket.AF_UNIX, use_socktype)
857+
try:
858+
self.socket.connect(address)
859+
# it worked, so set self.socktype to the used type
860+
self.socktype = use_socktype
861+
except OSError:
862+
self.socket.close()
863+
raise
864+
865+
def createSocket(self):
866+
address = self.address
867+
socktype = self.socktype
838868

839869
if isinstance(address, str):
840870
self.unixsocket = True
@@ -871,30 +901,6 @@ def __init__(self, address=('localhost', SYSLOG_UDP_PORT),
871901
self.socket = sock
872902
self.socktype = socktype
873903

874-
def _connect_unixsocket(self, address):
875-
use_socktype = self.socktype
876-
if use_socktype is None:
877-
use_socktype = socket.SOCK_DGRAM
878-
self.socket = socket.socket(socket.AF_UNIX, use_socktype)
879-
try:
880-
self.socket.connect(address)
881-
# it worked, so set self.socktype to the used type
882-
self.socktype = use_socktype
883-
except OSError:
884-
self.socket.close()
885-
if self.socktype is not None:
886-
# user didn't specify falling back, so fail
887-
raise
888-
use_socktype = socket.SOCK_STREAM
889-
self.socket = socket.socket(socket.AF_UNIX, use_socktype)
890-
try:
891-
self.socket.connect(address)
892-
# it worked, so set self.socktype to the used type
893-
self.socktype = use_socktype
894-
except OSError:
895-
self.socket.close()
896-
raise
897-
898904
def encodePriority(self, facility, priority):
899905
"""
900906
Encode the facility and priority. You can pass in strings or
@@ -914,7 +920,10 @@ def close(self):
914920
"""
915921
self.acquire()
916922
try:
917-
self.socket.close()
923+
sock = self.socket
924+
if sock:
925+
self.socket = None
926+
sock.close()
918927
logging.Handler.close(self)
919928
finally:
920929
self.release()
@@ -954,6 +963,10 @@ def emit(self, record):
954963
# Message is a string. Convert to bytes as required by RFC 5424
955964
msg = msg.encode('utf-8')
956965
msg = prio + msg
966+
967+
if not self.socket:
968+
self.createSocket()
969+
957970
if self.unixsocket:
958971
try:
959972
self.socket.send(msg)

Lib/test/test_logging.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1942,6 +1942,14 @@ def test_output(self):
19421942
self.handled.wait()
19431943
self.assertEqual(self.log_output, b'<11>h\xc3\xa4m-sp\xc3\xa4m')
19441944

1945+
def test_udp_reconnection(self):
1946+
logger = logging.getLogger("slh")
1947+
self.sl_hdlr.close()
1948+
self.handled.clear()
1949+
logger.error("sp\xe4m")
1950+
self.handled.wait(0.1)
1951+
self.assertEqual(self.log_output, b'<11>sp\xc3\xa4m\x00')
1952+
19451953
@unittest.skipUnless(hasattr(socket, "AF_UNIX"), "Unix sockets required")
19461954
class UnixSysLogHandlerTest(SysLogHandlerTest):
19471955

0 commit comments

Comments
 (0)