Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
5421f35d
Commit
5421f35d
authored
Sep 27, 2013
by
Vinay Sajip
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
logging: added support for Unix domain sockets to SocketHandler and DatagramHandler.
parent
55798896
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
130 additions
and
21 deletions
+130
-21
Doc/howto/logging.rst
Doc/howto/logging.rst
+2
-2
Doc/library/logging.handlers.rst
Doc/library/logging.handlers.rst
+6
-0
Lib/logging/handlers.py
Lib/logging/handlers.py
+17
-3
Lib/test/test_logging.py
Lib/test/test_logging.py
+102
-16
Misc/NEWS
Misc/NEWS
+3
-0
No files found.
Doc/howto/logging.rst
View file @
5421f35d
...
...
@@ -900,10 +900,10 @@ provided:
disk files, rotating the log file at certain timed intervals.
#. :class:`~handlers.SocketHandler` instances send messages to TCP/IP
sockets.
sockets.
Since 3.4, Unix domain sockets are also supported.
#. :class:`~handlers.DatagramHandler` instances send messages to UDP
sockets.
sockets.
Since 3.4, Unix domain sockets are also supported.
#. :class:`~handlers.SMTPHandler` instances send messages to a designated
email address.
...
...
Doc/library/logging.handlers.rst
View file @
5421f35d
...
...
@@ -381,6 +381,9 @@ sends logging output to a network socket. The base class uses a TCP socket.
Returns a new instance of the :class:`SocketHandler` class intended to
communicate with a remote machine whose address is given by *host* and *port*.
.. versionchanged:: 3.4
If ``port`` is specified as ``None``, a Unix domain socket is created
using the value in ``host`` - otherwise, a TCP socket is created.
.. method:: close()
...
...
@@ -466,6 +469,9 @@ over UDP sockets.
Returns a new instance of the :class:`DatagramHandler` class intended to
communicate with a remote machine whose address is given by *host* and *port*.
.. versionchanged:: 3.4
If ``port`` is specified as ``None``, a Unix domain socket is created
using the value in ``host`` - otherwise, a TCP socket is created.
.. method:: emit()
...
...
Lib/logging/handlers.py
View file @
5421f35d
...
...
@@ -494,6 +494,10 @@ class SocketHandler(logging.Handler):
logging
.
Handler
.
__init__
(
self
)
self
.
host
=
host
self
.
port
=
port
if
port
is
None
:
self
.
address
=
host
else
:
self
.
address
=
(
host
,
port
)
self
.
sock
=
None
self
.
closeOnError
=
False
self
.
retryTime
=
None
...
...
@@ -509,7 +513,13 @@ class SocketHandler(logging.Handler):
A factory method which allows subclasses to define the precise
type of socket they want.
"""
return
socket
.
create_connection
((
self
.
host
,
self
.
port
),
timeout
=
timeout
)
if
self
.
port
is
not
None
:
result
=
socket
.
create_connection
(
self
.
address
,
timeout
=
timeout
)
else
:
result
=
socket
.
socket
(
socket
.
AF_UNIX
,
socket
.
SOCK_STREAM
)
result
.
settimeout
(
timeout
)
result
.
connect
(
self
.
address
)
return
result
def
createSocket
(
self
):
"""
...
...
@@ -643,7 +653,11 @@ class DatagramHandler(SocketHandler):
The factory method of SocketHandler is here overridden to create
a UDP socket (SOCK_DGRAM).
"""
s
=
socket
.
socket
(
socket
.
AF_INET
,
socket
.
SOCK_DGRAM
)
if
self
.
port
is
None
:
family
=
socket
.
AF_UNIX
else
:
family
=
socket
.
AF_INET
s
=
socket
.
socket
(
family
,
socket
.
SOCK_DGRAM
)
return
s
def
send
(
self
,
s
):
...
...
@@ -656,7 +670,7 @@ class DatagramHandler(SocketHandler):
"""
if
self
.
sock
is
None
:
self
.
createSocket
()
self
.
sock
.
sendto
(
s
,
(
self
.
host
,
self
.
port
)
)
self
.
sock
.
sendto
(
s
,
self
.
address
)
class
SysLogHandler
(
logging
.
Handler
):
"""
...
...
Lib/test/test_logging.py
View file @
5421f35d
...
...
@@ -59,7 +59,9 @@ try:
import
smtpd
from
urllib.parse
import
urlparse
,
parse_qs
from
socketserver
import
(
ThreadingUDPServer
,
DatagramRequestHandler
,
ThreadingTCPServer
,
StreamRequestHandler
)
ThreadingTCPServer
,
StreamRequestHandler
,
ThreadingUnixStreamServer
,
ThreadingUnixDatagramServer
)
except
ImportError
:
threading
=
None
try
:
...
...
@@ -854,6 +856,9 @@ if threading:
super(TestTCPServer, self).server_bind()
self.port = self.socket.getsockname()[1]
class TestUnixStreamServer(TestTCPServer):
address_family = socket.AF_UNIX
class TestUDPServer(ControlMixin, ThreadingUDPServer):
"""
A UDP server which is controllable using :class:`ControlMixin`.
...
...
@@ -901,6 +906,9 @@ if threading:
super(TestUDPServer, self).server_close()
self._closed = True
class TestUnixDatagramServer(TestUDPServer):
address_family = socket.AF_UNIX
# - end of server_helper section
@unittest.skipUnless(threading, 'Threading required for this test.')
...
...
@@ -1358,17 +1366,22 @@ class SocketHandlerTest(BaseTest):
"""Test for SocketHandler objects."""
server_class = TestTCPServer
address = ('localhost', 0)
def setUp(self):
"""Set up a TCP server to receive log messages, and a SocketHandler
pointing to that server's address and port."""
BaseTest.setUp(self)
addr = ('localhost', 0)
self.server = server = TestTCPServer(addr, self.handle_socket,
0.01)
self.server = server = self.server_class(self.address,
self.handle_socket, 0.01)
server.start()
server.ready.wait()
self.sock_hdlr = logging.handlers.SocketHandler('localhost',
server.port)
hcls = logging.handlers.SocketHandler
if isinstance(server.server_address, tuple):
self.sock_hdlr = hcls('localhost', server.port)
else:
self.sock_hdlr = hcls(server.server_address, None)
self.log_output = ''
self.root_logger.removeHandler(self.root_logger.handlers[0])
self.root_logger.addHandler(self.sock_hdlr)
...
...
@@ -1425,21 +1438,46 @@ class SocketHandlerTest(BaseTest):
self.root_logger.error('Nor this')
@unittest.skipUnless(threading, 'Threading required for this test.')
class UnixSocketHandlerTest(SocketHandlerTest):
"""Test for SocketHandler with unix sockets."""
server_class = TestUnixStreamServer
def setUp(self):
# override the definition in the base class
fd, self.address = tempfile.mkstemp(prefix='test_logging_',
suffix='.sock')
os.close(fd)
os.remove(self.address) # just need a name - file can't be present
SocketHandlerTest.setUp(self)
def tearDown(self):
SocketHandlerTest.tearDown(self)
os.remove(self.address)
@unittest.skipUnless(threading, 'Threading required for this test.')
class DatagramHandlerTest(BaseTest):
"""Test for DatagramHandler."""
server_class = TestUDPServer
address = ('localhost', 0)
def setUp(self):
"""Set up a UDP server to receive log messages, and a DatagramHandler
pointing to that server's address and port."""
BaseTest.setUp(self)
addr = ('localhost', 0)
self.server = server = TestUDPServer(addr,
self.handle_datagram, 0.01)
self.server = server = self.server_class(self.address,
self.handle_datagram, 0.01)
server.start()
server.ready.wait()
self.sock_hdlr = logging.handlers.DatagramHandler('localhost',
server.port)
hcls = logging.handlers.DatagramHandler
if isinstance(server.server_address, tuple):
self.sock_hdlr = hcls('localhost', server.port)
else:
self.sock_hdlr = hcls(server.server_address, None)
self.log_output = ''
self.root_logger.removeHandler(self.root_logger.handlers[0])
self.root_logger.addHandler(self.sock_hdlr)
...
...
@@ -1473,22 +1511,46 @@ class DatagramHandlerTest(BaseTest):
self.assertEqual(self.log_output, "
spam
\
neggs
\
n
")
@unittest.skipUnless(threading, 'Threading required for this test.')
class UnixDatagramHandlerTest(DatagramHandlerTest):
"""Test for DatagramHandler using Unix sockets."""
server_class = TestUnixDatagramServer
def setUp(self):
# override the definition in the base class
fd, self.address = tempfile.mkstemp(prefix='test_logging_',
suffix='.sock')
os.close(fd)
os.remove(self.address) # just need a name - file can't be present
DatagramHandlerTest.setUp(self)
def tearDown(self):
DatagramHandlerTest.tearDown(self)
os.remove(self.address)
@unittest.skipUnless(threading, 'Threading required for this test.')
class SysLogHandlerTest(BaseTest):
"""Test for SysLogHandler using UDP."""
server_class = TestUDPServer
address = ('localhost', 0)
def setUp(self):
"""Set up a UDP server to receive log messages, and a SysLogHandler
pointing to that server's address and port."""
BaseTest.setUp(self)
addr = ('localhost', 0)
self.server = server = TestUDPServer(addr, self.handle_datagram,
0.01)
self.server = server = self.server_class(self.address,
self.handle_datagram, 0.01)
server.start()
server.ready.wait()
self.sl_hdlr = logging.handlers.SysLogHandler(('localhost',
server.port))
hcls = logging.handlers.SysLogHandler
if isinstance(server.server_address, tuple):
self.sl_hdlr = hcls(('localhost', server.port))
else:
self.sl_hdlr = hcls(server.server_address)
self.log_output = ''
self.root_logger.removeHandler(self.root_logger.handlers[0])
self.root_logger.addHandler(self.sl_hdlr)
...
...
@@ -1525,6 +1587,29 @@ class SysLogHandlerTest(BaseTest):
self.assertEqual(self.log_output, b'<11>h
\
xc3
\
xa4
m-sp
\
xc3
\
xa4
m')
@unittest.skipUnless(threading, 'Threading required for this test.')
class UnixSysLogHandlerTest(SysLogHandlerTest):
"""Test for SysLogHandler with Unix sockets."""
server_class = TestUnixDatagramServer
def setUp(self):
# override the definition in the base class
fd, self.address = tempfile.mkstemp(prefix='test_logging_',
suffix='.sock')
os.close(fd)
os.remove(self.address) # just need a name - file can't be present
SysLogHandlerTest.setUp(self)
def tearDown(self):
SysLogHandlerTest.tearDown(self)
os.remove(self.address)
# def test_output(self):
# import pdb; pdb.set_trace()
# SysLogHandlerTest.test_output(self)
@unittest.skipUnless(threading, 'Threading required for this test.')
class HTTPHandlerTest(BaseTest):
"""Test for HTTPHandler."""
...
...
@@ -4034,7 +4119,8 @@ def test_main():
SMTPHandlerTest, FileHandlerTest, RotatingFileHandlerTest,
LastResortTest, LogRecordTest, ExceptionTest,
SysLogHandlerTest, HTTPHandlerTest, NTEventLogHandlerTest,
TimedRotatingFileHandlerTest
TimedRotatingFileHandlerTest, UnixSocketHandlerTest,
UnixDatagramHandlerTest, UnixSysLogHandlerTest
)
if __name__ == "
__main__
":
...
...
Misc/NEWS
View file @
5421f35d
...
...
@@ -15,6 +15,9 @@ Core and Builtins
Library
-------
-
logging
:
added
support
for
Unix
domain
sockets
to
SocketHandler
and
DatagramHandler
.
-
Issue
#
18996
:
TestCase
.
assertEqual
()
now
more
cleverly
shorten
differing
strings
in
error
report
.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment