[Python-checkins] bpo-44291: Fix reconnection in logging.handlers.SysLogHandler (GH-26490)

vsajip webhook-mailer at python.org
Thu Aug 5 09:58:26 EDT 2021


https://github.com/python/cpython/commit/3d315c311676888201f4a3576e4ee3698684a3a2
commit: 3d315c311676888201f4a3576e4ee3698684a3a2
branch: main
author: Kirill Pinchuk <192182+cybergrind at users.noreply.github.com>
committer: vsajip <vinay_sajip at yahoo.co.uk>
date: 2021-08-05T14:58:16+01:00
summary:

bpo-44291: Fix reconnection in logging.handlers.SysLogHandler (GH-26490)

files:
M Lib/logging/handlers.py
M Lib/test/test_logging.py

diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py
index e2579db58046d..f1a2e3b69986e 100644
--- a/Lib/logging/handlers.py
+++ b/Lib/logging/handlers.py
@@ -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
@@ -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
@@ -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()
@@ -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)
diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py
index b3393d304b122..9998f1a02e4c9 100644
--- a/Lib/test/test_logging.py
+++ b/Lib/test/test_logging.py
@@ -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):
 



More information about the Python-checkins mailing list