supports sending logging messages to a remote or local Unix syslog.
-.. class:: SysLogHandler(address=('localhost', SYSLOG_UDP_PORT), facility=LOG_USER, socktype=socket.SOCK_DGRAM)
+.. class:: SysLogHandler(address=('localhost', SYSLOG_UDP_PORT), facility=LOG_USER, socktype=socket.SOCK_DGRAM, timeout=None)
Returns a new instance of the :class:`SysLogHandler` class intended to
communicate with a remote Unix machine whose address is given by *address* in
*socktype* argument, which defaults to :const:`socket.SOCK_DGRAM` and thus
opens a UDP socket. To open a TCP socket (for use with the newer syslog
daemons such as rsyslog), specify a value of :const:`socket.SOCK_STREAM`.
+ If *timeout* is specified, it sets a timeout (in seconds) for the socket operations.
+ This can help prevent the program from hanging indefinitely if the syslog server is
+ unreachable. By default, *timeout* is ``None``, meaning no timeout is applied.
+
+
Note that if your server is not listening on UDP port 514,
:class:`SysLogHandler` may appear not to work. In that case, check what
.. versionchanged:: 3.2
*socktype* was added.
+ .. versionchanged:: 3.14
+ *timeout* was added.
.. method:: close()
}
def __init__(self, address=('localhost', SYSLOG_UDP_PORT),
- facility=LOG_USER, socktype=None):
+ facility=LOG_USER, socktype=None, timeout=None):
"""
Initialize a handler.
self.address = address
self.facility = facility
self.socktype = socktype
+ self.timeout = timeout
self.socket = None
self.createSocket()
err = sock = None
try:
sock = socket.socket(af, socktype, proto)
+ if self.timeout:
+ sock.settimeout(self.timeout)
if socktype == socket.SOCK_STREAM:
sock.connect(sa)
break
import logging.handlers
import logging.config
+
import codecs
import configparser
import copy
self.handled.wait(support.LONG_TIMEOUT)
self.assertEqual(self.log_output, b'<11>sp\xc3\xa4m\x00')
+ @patch('socket.socket')
+ def test_tcp_timeout(self, mock_socket):
+ instance_mock_sock = mock_socket.return_value
+ instance_mock_sock.connect.side_effect = socket.timeout
+
+ with self.assertRaises(socket.timeout):
+ logging.handlers.SysLogHandler(address=('localhost', 514),
+ socktype=socket.SOCK_STREAM,
+ timeout=1)
+
+ instance_mock_sock.close.assert_called()
+
@unittest.skipUnless(hasattr(socket, "AF_UNIX"), "Unix sockets required")
class UnixSysLogHandlerTest(SysLogHandlerTest):
--- /dev/null
+Add a socket *timeout* keyword argument to
+:class:`logging.handlers.SysLogHandler`.