views:

63

answers:

1

I am working on a website, hosted on DreamHost, using Python. For a while, I was using their default setup, which runs Python scripts using CGI. It worked fine, but I was worried that if I get a lot of traffic, it would run slow and use a lot of memory, so I switched it over to FastCGI using this module.

Overall, it still works fine, but there is one major annoyance: I can't seem to be able to see anything that gets written to the standard error stream. If anything goes wrong, my usual source of useful clues for what to do about it no longer works. Before, I used to see stuff sent to standard error in my Apache error log. Now, it just seems to disappear.

I tried making a test script, and writing strings using sys.stderr.write (from various places), and environ["wsgi.errors"].write (from within my app, where environ is the first parameter passed to the app by the WSGI/FastCGI wrapper). Either way, I couldn't find them. Does anyone know why, or how to access this data?

Keep in mind that this is my first time ever using FastCGI, so please let me know if I am making a bad choice by using this fcgi module.

+1  A: 

If something in your system is capturing file-descriptor two (the "real" stderr), you can assign sys.stderr to any open, writeable file object, or to a file-like object (it basically just needs to implement write) -- including a cStdIO.StdIO instance, whose value you can get at any time (before it's closed) with a call to its .getvalue() method.

To capture any uncaught exception just before it terminates your code, assign to sys.excepthook a function of yours in which you get the information and emit it in any way of your choice; or, to get and emit anything that was written to sys.stderr even without an exception (if that's what you want -- I'm not sure, from your question), use atexit to register your grab-info-and-emit-it function.

Alex Martelli
Quoting the FASTCGI specification (http://www.fastcgi.com/drupal/node/6?q=node/22). "It doesn't have the conventional open files stdin, stdout, and stderr, and it doesn't receive much information through environment variables". So, depending on whether the FASTCGI system being used religiously honours that, there may not be a stderr at all. As Alex says, map stderr to something. Easiest is to try 'sys.stderr = open("/tmp/myerrors.log", "w+")' as very first thing in FASTCGI script file.
Graham Dumpleton
I tried your suggestion about reassigning sys.stderr and it worked. Sort of. I can't get the errors to go to the error log like they used to but this may be good enough for my purposes.I haven't tried sys.excepthook for this purpose but I have used it before and it seems like it would work.I haven't tried atexit yet.
mikez302
@mikez, yeah, I don't know how to write from the Apache log from within fastcgi (which I don't use anyway -- hooray for `mod_wsgi`!-). But, writing to a file, mailing the error log to yourself, using the `logging` module, showing the error log on the browser (for sites not yet in production, only: I _hate_ sites that show me big tracebacks, be they Java or Python or anything, when they have a problem and I'm just a user!-), etc, are several other possibilities.
Alex Martelli
I wish I could use WSGI, but DreamHost doesn't officially support it and I don't want to experiment too much. I think I can find a way around this problem. The logging module looks cool. I will check it out.
mikez302
I believe DreamHost uses Phusion Passenger for Ruby. It also supports a Python WSGI feature. If you can actually find documentation on using that, you might try that instead as people often have better success with that at DreamHost than FASTCGI.
Graham Dumpleton