diff options
author | Kirill Pinchuk <192182+cybergrind@users.noreply.github.com> | 2021-08-05 13:58:16 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-05 13:58:16 (GMT) |
commit | 3d315c311676888201f4a3576e4ee3698684a3a2 (patch) | |
tree | f9fd948febf5c5d077af5eb79ba977c42a4c8208 | |
parent | 8f010dc920e1f6dc6a357e7cc1460a7a567c05c6 (diff) | |
download | cpython-3d315c311676888201f4a3576e4ee3698684a3a2.zip cpython-3d315c311676888201f4a3576e4ee3698684a3a2.tar.gz cpython-3d315c311676888201f4a3576e4ee3698684a3a2.tar.bz2 |
bpo-44291: Fix reconnection in logging.handlers.SysLogHandler (GH-26490)
-rw-r--r-- | Lib/logging/handlers.py | 63 | ||||
-rw-r--r-- | Lib/test/test_logging.py | 8 |
2 files changed, 46 insertions, 25 deletions
diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py index e2579db..f1a2e3b 100644 --- a/Lib/logging/handlers.py +++ b/Lib/logging/handlers.py @@ -835,6 +835,36 @@ class SysLogHandler(logging.Handler): 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 @@ -871,30 +901,6 @@ class SysLogHandler(logging.Handler): 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 @@ -914,7 +920,10 @@ class SysLogHandler(logging.Handler): """ self.acquire() try: - self.socket.close() + sock = self.socket + if sock: + self.socket = None + sock.close() logging.Handler.close(self) finally: self.release() @@ -954,6 +963,10 @@ class SysLogHandler(logging.Handler): # 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) diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index b3393d3..9998f1a 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -1942,6 +1942,14 @@ class SysLogHandlerTest(BaseTest): 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): |