-
-
Notifications
You must be signed in to change notification settings - Fork 29.5k
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 crash atexit #82961
Comments
On Python 3.8.0: $ python -c "import logging.handlers, socket; handler = logging.handlers.SysLogHandler(facility=logging.handlers.SysLogHandler.LOG_LOCAL7, address='/dev/log', socktype=socket.SOCK_RAW)"
Error in atexit._run_exitfuncs:
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/logging/__init__.py", line 2112, in shutdown
h.close()
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/logging/handlers.py", line 892, in close
self.socket.close()
AttributeError: 'SysLogHandler' object has no attribute 'socket' Probably that shouldn't happen. |
Same error on Python 2.7 and 3.7 |
I only observe this issue on macOS. On Linux, the error doesn't occur. |
I guess that makes sense, as |
For background, this issue originated from pytest-dev/pytest-services#20. |
The issue probably stems from cpython/Lib/logging/handlers.py Lines 828 to 835 in 138ccbb
|
In the downstream issue, it's also reported that crashes occur in emit as well, suggesting that the comment is additionally wrong on that front. |
I could imagine extending the shutdown code to catch the reported error ( cpython/Lib/logging/__init__.py Lines 2130 to 2135 in 138ccbb
Similarly, the SysLogHandler could override shutdown to bypass the error if no socket attribute is present, but that again wouldn't address the emit case. |
As you noted /dev/log doesn't exist on macOS (the correct path is /var/run/syslog). I guess the change that would be most in spirit of the comment is to set self.socket to None when the socket cannot be opened and test for that before closing the socket. Likewise, emit() can test if self.socket is None and then attempt to open the socket (and not write to the log when the socket still is None) This makes errors pass silently, but does match the spirit of the POSIX API (where the syslog function does not return an error). |
There are a variety of different reasons this can fail, not just on MacOS. You could give it a bad IP address of a server, etc. [That was my particular case]. The constructor should create an attribute 'socket' and initialize it to None early on. Then, the close function in logging/handlers.py should check for None. Or alternatively, it shouldn't register the object with atexit until it's been constructed "well-enough". |
Attached patch is based on Ronald Oussoren's and Alan Robertson's comments: Initialise self.socket to None early in __init()__, and then check for None in close() and emit(). Passes make test on 3.9, 3.8 and 3.7. If this solution is ok I'll add a unit test for the case that triggered this report and prepare a PR. |
I'm a bit uncertain if the previous patch can handle the emit() case correctly. Proposed improvement in attached patch (0002-Improve-emit.patch). |
Is there any update on this issue? I'm experiencing the same problem on macos. |
I'll take a look at the patch and convert it to a PR. |
I've applied the patches and pushed them to https://github.com/jaraco/cpython/tree/bugfix/bpo-38780.
|
Erlend, inspired by your patches, I created e972300, which uses a NullSocket instance instead of None, allowing the behavior-suppression to be encapsulated in a single place and swapped out by creation of a proper socket instance. I do believe this approach addresses the issue. Are you still willing to put together a test case or more? |
Thanks, Jason! I won't have time to look at this until perhaps next week, however, feel free to add tests as you like. N.B.: My patches might not be the best solution to the problem; it was just something I threw up based on my initial understanding of the problem. |
I started work on a test in https://github.com/jaraco/cpython/tree/bugfix/bpo-38780-test, but (a) the test was failing to exhibit the expected failures, and (b) I realized that the fix isn't having the intended effect either, because for unix sockets, self.socket is unconditionally set, overriding any NullSocket or None value. The SysLogHandler code will need to be reorganized if self.socket is intended to model two modes (broken and initialized). I'm not sure when I'll get another chance to take a look at this, but I'll not be able to wrap it up today, so I'm going to unassign it for now. |
I've forked your work, Jason: I added the test from msg356475, and I'm able to reproduce it by asserting that the |
Using a NullSocket fixes the test in commit f0f8ff8 |
TBH as I said in the now-closed PR, using a NullSocket seems overkill. As mentioned in msg359594, it seems to make more sense to assign a socket attribute to None early in the constructor. If an error occurs during socket creation, the socket attribute will remain at None. When closing, just ensure the socket attribute isn't None before trying to close it. This mirrors what SocketHandler does. |
On Wed, Jan 6, 2021, at 10:30 AM, Vinay Sajip wrote:
-- |
As far as I know, this only happens during shutdown. During shutdown it has already removed the attribute as part of the teardown process. In this case adding the attribute at the begining will do no good. On Wed, Jan 6, 2021, at 10:30 AM, Vinay Sajip wrote:
|
Certainly, that's true - there are a number of issues that get laid at logging's door because of interpreter shutdown sometimes intersecting with asyncio, threads and error handling using logging to report, which then fails in turn because of inconsistent interpreter state during shutdown. That would then perhaps be a "wontfix" or "cantfix" because there is no good solution. But the missing socket attribute in SysLogHandler might cause other problems in the future - I'm just saying that the approach you suggested is, to me, preferable to the NullSocket approach to deal with a similar issue in this area. |
I think this issue is out of date due to more recent changes. Certainly, I can't reproduce the original report in the |
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: