Opened 8 years ago
Closed 8 years ago
#12650 closed defect (fixed)
client disconnect errors are logged again with newer versions of mod_wsgi
Reported by: | Christian Boos | Owned by: | Christian Boos |
---|---|---|---|
Priority: | normal | Milestone: | 1.0.14 |
Component: | web frontend/mod_wsgi | Version: | |
Severity: | normal | Keywords: | logging |
Cc: | Branch: | ||
Release Notes: |
Reduce logging noise with client disconnects, for recent versions of mod_wsgi (e.g. 4.5.13) |
||
API Changes: | |||
Internal Changes: |
Description
We have an internal check to avoid polluting the trac.log with errors related to client disconnections or response write failures.
For mod_wsgi, this check rely on error messages. Newer versions (don't know since when exactly) add the "Apache/mod_wsgi" prefix to these messages, so we need to take that into account.
Example:
[pid 3682 139642907973376] 2017-01-05 17:00:28,194 Trac[main] ERROR: Internal Server Error: <RequestWithSession "GET '/log/trunk/trac/admin?rev=11508'">, referrer None Traceback (most recent call last): File "build/bdist.linux-x86_64/egg/trac/web/main.py", line 617, in _dispatch_request dispatcher.dispatch(req) File "build/bdist.linux-x86_64/egg/trac/web/main.py", line 274, in dispatch req.send(output, content_type or 'text/html') File "build/bdist.linux-x86_64/egg/trac/web/api.py", line 693, in send self.write(content) File "build/bdist.linux-x86_64/egg/trac/web/api.py", line 833, in write self._write(''.join(buf)) IOError: Apache/mod_wsgi failed to write response data: Broken pipeBroken pipe
Also, it's "failed to write response data" now instead of "failed to write data".
I think fixing this starting from 1.0 is good enough.
Attachments (0)
Change History (12)
comment:1 by , 8 years ago
comment:2 by , 8 years ago
1.2.1dev-mod-wsgi-prefix
string is incompatible with PEP-440. As the result, requirement Trac>=1.0
fails. dev
tag is not the reason to fail.
>>> from pkg_resources import parse_version >>> parse_version('1.2.1dev-mod-wsgi-prefix') <LegacyVersion('1.2.1dev-mod-wsgi-prefix')> >>> parse_version('1.2.1dev') >= parse_version('1.0') True >>> parse_version('1.2.1dev-mod-wsgi-prefix') >= parse_version('1.0') False >>> parse_version('1.0dev') >= parse_version('1.0') False >>> parse_version('1.0') >= parse_version('1.0') True
follow-up: 5 comment:3 by , 8 years ago
Thanks for the heads up, Jun! I seemed to remember something like that, yes. It's too bad we can't use that, as it would be very handy to have a quick way to check in the /about page that we have indeed loaded the version of Trac we expected.
comment:4 by , 8 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
follow-up: 7 comment:5 by , 8 years ago
Replying to Christian Boos:
Thanks for the heads up, Jun! I seemed to remember something like that, yes. It's too bad we can't use that, as it would be very handy to have a quick way to check in the /about page that we have indeed loaded the version of Trac we expected.
See also #12038.
follow-up: 8 comment:6 by , 8 years ago
After [15323], if 'mod_wsgi.version' in self.environ
line is duplicated.
-
trac/web/api.py
diff --git a/trac/web/api.py b/trac/web/api.py index 3b2a8794b..f04cc6b0a 100644
a b class Request(object): 832 832 # Note that mod_wsgi raises an IOError with only a message 833 833 # if the client disconnects 834 834 if 'mod_wsgi.version' in self.environ: 835 if 'mod_wsgi.version' in self.environ: 836 mod_wsgi_prefix = 'Apache/mod_wsgi ' 837 m = e.args[0] 838 if m.startswith(mod_wsgi_prefix): 839 m = m[len(mod_wsgi_prefix):] 835 mod_wsgi_prefix = 'Apache/mod_wsgi ' 836 m = e.args[0] 837 if m.startswith(mod_wsgi_prefix): 838 m = m[len(mod_wsgi_prefix):] 840 839 return m.startswith(('failed to write response data', 841 840 'failed to write data', 842 841 'client connection closed',
Another think: an IOError
typically has message and errno but several WSGI containers (mod_wsgi, uWSGI, …) raise an IOError
without errno because errno cannot be retrieved when reading request/writing response is failing. It might be good to assume client disconnected when the IOError
doesn't have errno.
https://github.com/unbit/uwsgi/search?utf8=%E2%9C%93&q=PyExc_IOError%2C+%22write+error%22&type=Code
comment:7 by , 8 years ago
Replying to Ryan J Ollos:
Replying to Christian Boos:
Thanks for the heads up, Jun! I seemed to remember something like that, yes. It's too bad we can't use that, as it would be very handy to have a quick way to check in the /about page that we have indeed loaded the version of Trac we expected.
See also #12038.
Yes, and now I see I simply should have used a '+' as a separator instead of a '-' (pep:0440/#local-version-identifiers):
>>> from pkg_resources import parse_version >>> parse_version('1.2.1dev+mod_wsgi_spec') >= parse_version('1.0dev') True
comment:8 by , 8 years ago
Replying to Jun Omae:
After [15323],
if 'mod_wsgi.version' in self.environ
line is duplicated.
Hmpf, yes…
Another think: an
IOError
typically has message and errno but several WSGI containers (mod_wsgi, uWSGI, …) raise anIOError
without errno because errno cannot be retrieved when reading request/writing response is failing. It might be good to assume client disconnected when theIOError
doesn't have errno.
That would simplify things indeed. I'll give it a try,
comment:9 by , 8 years ago
Resolution: | fixed |
---|---|
Status: | closed → reopened |
See [ab5bebe0/cboos.git].
I also simplified the isinstance
check, since we're on Python ≥ 2.6 on 1.0.
comment:10 by , 8 years ago
There continue to be many instances of the traceback shown in comment:description for t.e.o. Is that expected? The version is +t16250.2
, which is different than the comment:9 patch.
comment:11 by , 8 years ago
Status: | reopened → assigned |
---|
It's been a few days now it's running with cboos.git@t12650.1, and the errors seem to be correctly ignored.
The /var/log/apache2/error.log
show the following for the print >> sys.stderr
I left in the is_client_disconnect_exception
function:
[Tue Jan 24 06:23:24.655440 2017] [wsgi:error] [pid 25443:tid 139725917722368] [remote 42.156.138.82:52351] is_client_disconnect_exception: IOError = None
errno
is indeed None
for mod_wsgi.
comment:12 by , 8 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
We still support Python 2.5 on 1.0.14… Well, sorry, I no longer have a running Python 2.5 version for testing, I hope everything will be OK.
Only applying [219e462e/cboos.git] on 1.0-stable (r15377) and [73743369/cboos.git] goes on 1.2-stable (r15378).
Merged on trunk in r15379.
I thought it was a good idea to use a 'dev-mod_wsgi_prefix' tag while testing the change live on t.e.o, unfortunately, this variant of the 'dev' tag caused the SpamFilter to refuse to load…
Good to know ;-)