-
-
Notifications
You must be signed in to change notification settings - Fork 30k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SysLogHandler can't send long messages #56116
Comments
It seems that logging.handlers.SysLogHandler can't handle messages that can't be passed atomically via the socket. I'm not sure what is the right behavior (the syslog() function truncates the message), but I think it shouldn't propagate the exception to the application. Python 2.7.1 (r271:86832, Apr 18 2011, 08:47:29)
[GCC 4.2.1 20070719 [FreeBSD]] on freebsd8
Type "help", "copyright", "credits" or "license" for more information.
>>> import logging.handlers
>>> handler = logging.handlers.SysLogHandler('/dev/log')
>>> logger = logging.getLogger()
>>> logger.addHandler(handler)
>>> logger.warn('x' * 4096)
Traceback (most recent call last):
File "/usr/local/lib/python2.7/logging/handlers.py", line 808, in emit
self.socket.send(msg)
error: [Errno 40] Message too long
Logged from file <stdin>, line 1 |
The entire part of emit() which sends to the socket is wrapped in an except: which should catch all except KeyboardInterrupt and SystemExit. The except clause calls the handleError method of the handler. See http://hg.python.org/cpython/file/fa277cbd66bb/Lib/logging/handlers.py#l804 So I can't see exactly what's happening, and moreover I can't reproduce this on Linux even when sending messages of > 16384 on the Unix socket. I don't have access to a FreeBSD system. Can you do a little more investigation, since I'm not sure what your source says? (The line nos. don't seem to match up exactly - in Mercurial, line 808 is an except socket.error clause). |
It seems that I was wrong, the exception is indeed not propagated to the application, but handled by the handleError() method. I was confused by seeing the traceback in my uWSGI log file. I'm unable to find a way to determine the maximum allowed syslog message size, otherwise the proper behavior would be probably to truncate the message. Specifically on FreeBSD, the clib source code seems to be using a buffer with 2048 bytes for the whole syslog line and 1024 bytes for the message formatting, so they are just arbitrary numbers. :( There probably isn't a way to solve this cleanly. Truncating the message would be much preferable to dropping it, but I really don't know what would be the right size. I'll write a LocalSysLogHandler for me that uses the syslog module. Regarding the line numbers, this is the version corresponding to the 2.7.1 release - http://hg.python.org/cpython/file/5395f96588d4/Lib/logging/handlers.py#l808 |
I've managed to get access to a FreeBSD system and done some investigation. The system is working as designed, and the error message is being printed by the handleError() method of the handler. To handle the exception differently, you either set logging.raiseExceptions to False (which will cause logging to swallow the exception) or you need to implement your own handler which takes appropriate action (e.g truncates the message). Closing as invalid. |
Sure, but bear in mind that on some Linux systems at least, the syslog module |
It will be called only from the handler, so I think it should be fine. The reason why I started using syslog was that I need to log into a single file from multiple processes, but it seems to be showing up as too much trouble. |
For other options you might like to consider, see: http://plumberjack.blogspot.com/2010/09/improved-queuehandler-queuelistener.html which refers to QueueHandler and QueueListener classes. These were added in 3.2 but are available for Python 2.x: |
The code doesn't appear to be conforming to RFC-3164 or RFC-5424: (From RFC-3164): 4.1 syslog Message Parts The full format of a syslog message seen on the wire has three (From RFC-5424) The reason syslog transport receivers need only support receiving up ... It must be noted that the IPv6 MTU is about 2.5 times 480. An With MTUs being what they are by default with ethernet, using an MTU <1500 with UDP when jumbo frames aren't available seems like a foolhardy thing to do. I believe part of the problem is that the socket send buffer size is not being set in the SysLogHandler via socket.setsockopt and it's trying to jam as much information as it can down the pipe and failing, but I need to do more digging... |
Please note that when I said "the code" I was looking at python 3.3 on OSX (compiled with MacPorts): $ python3.3
Python 3.3.5 (default, Mar 11 2014, 15:08:59)
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.2.79)] on darwin
Type "help", "copyright", "credits" or "license" for more information. It's of course similar in lineage (BSD-foundation), but not the same of course.. I have a couple FreeBSD systems I can test this out on as well.. |
Note: same bug is relevant to DatagramHandler since it uses UDP transport. |
I know this has been closed as "Not a bug" but it would have been convenient if the message was broken down into multiple packets and transmitted, should it exceed the packet limit. |
Writing your own handler is what Vinay recommended. Is it even possible to determine the maximum message size? If we can't do that reliably, then the best we can do is recommend writing your own exception handler using local knowledge. If it can be determined reliably, you could open a new issue with that feature request. |
This issue will stay closed, BUT I propose you to create a new issue with a new title: Feature: Support message over 1024 bytes for the SysLogHandler. and propose a patch for this feature. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: