-
Notifications
You must be signed in to change notification settings - Fork 695
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
log-master fails on log messages larger than 2k in Mac OS X #75
Comments
Can you attach/paste a sample script to reproduce the problem ? Would help a lot. Even if i am afraid tuning the pipe buffer of OSX from uWSGI will be pretty impossibile, spitting out a warning can be helpful. Thanks |
def application(environ, start_response):
import logging
for pow in xrange(5, 14):
numbytes = 1 << pow
logging.warning('%6d bytes %s' % (numbytes, 'X' * (numbytes - 27)))
start_response("200 OK", [("Content-Type", "text/plain")])
return ["pong"] Run with |
But of course it's not logging-specific, so this test is more direct: def application(environ, start_response):
from sys import stdout, stderr
for pow in xrange(5, 14):
numbytes = 1 << pow
try:
stdout.write('%6d bytes %s\n' % (numbytes, 'X' * (numbytes - 14)))
except IOError, ioe:
stderr.write('Errno %d on %d bytes\n' % (ioe.errno, numbytes))
start_response("200 OK", [("Content-Type", "text/plain")])
return ["pong"] ... and hey, trying this out I got one case of only 32 bytes coming out, for one message:
Before now, I had seen only multiples of 1024 bytes (up to and including 4096). |
Are you sure you cannot reproduce the error on Linux ? Those 1000 bytes limit is hardcoded into python: (from Python/sysmodule.c) *** WARNING ***
Can you retry using uwsgi.log() instead of stdout.write() ? |
I tried with So I've still seen the problem only on Mac OS X. |
Is this issue report still valid? Does it happen with 1.9? |
Please excuse my delayed response — yes, both problems still happen. Here's the “Errno 40” problem exhibited by the second code example above (I've abbreviated long X strings):
and here's the “Errno 55” problem, exhibited by almost the same code, with just this change to try more messages around 2048 bytes: for pow in xrange(-15, 15, 3):
numbytes = 2048 + pow Output (I've omitted startup loglines and abbreviated long X strings):
I also tried with a slightly wider and finer-grained range of chunk lengths around 2048: for pow in xrange(-25, 25):
numbytes = 2048 + pow but then the write to stderr (reporting the IO error that resulted from writing to stdout) fails as well:
|
it took me ages, but i finally found the problem. Basically the internal buffers created by OSX for socketpair() are extremely tiny (4k). The patch get the size of the uWSGI log buffer and if it is higher than the socketpair() buffer increases it. There is no 1:1 mapping so very probably the logger bufsize should be doubled: ./uwsgi -w foo2 --master --log-master --http-socket :9090 --log-master-buf 16384 (for 8k messages) another approach i added is creating the socketpair() as a STREAM (like tcp sockets). In such a way the messages will be eventually split: ./uwsgi -w foo2 --master --log-master --http-socket :9090 --log-master-stream this works pretty badly as logs can be splitted and multiple threads will overlap messages, but could be useful in scenarios where avoiding the exception is better than inconsistent logs. |
I can't use
--log-master
on Mac OS X to pass python logging output (from StreamHandler) through the master, because log messages larger than 2k fail to emit, with "IOError: [Errno 40] Message too long".Also, messages close to exactly 2k in length sometimes fail with "IOError: [Errno 55] No buffer space available"
Changing
setlinebuf(stdout);
tosetbuf(stdout, (char*)malloc(4096));
in uwsgi.c:1736 makes the former problem (Errno 40) go away; all messages get through. But long messages still get truncated at either 1024, 2048, 3072 or 4096 bytes (and that same "IOError: [Errno 55] No buffer space available" error and stack trace gets printed right after). Making that stdout buffer bigger (even much bigger) does not help.So it seems like there are two separate problems, both seeming to involve the OS X pipe buffer, and that
setlinebuf
→setbuf
changefixesworks around one of them.The text was updated successfully, but these errors were encountered: