Why does stdout not flush when connecting to a process that is run with supervisord?

python, supervisord, terminal, unix

Solution

It turns out that python defaults to buffering its output stream. In certain cases (such as this one) - it results in output being detained.

Idioms like this exist:

sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)

to force the buffer to zero.

But the better alternative I think is to start the base python process in an unbuffered state using the `-u` flag. Within the supervisord.conf file it simply becomes:

command=python -u script.py

ref: http://docs.python.org/2/using/cmdline.html#envvar-PYTHONUNBUFFERED

Also note that this dirties up your log file - especially if you are using something like ipdb with ANSI coloring. But since it is a dev environment it is not likely that this matters.

If this is an issue - another solution is to stop the process to be debugged in supervisorctl and then run the process temporarily in another terminal for debugging. This would keep the logfiles clean if that is needed.

Problem

I am using Supervisor (process controller written in python) to start and control my web server and associated services. I find the need at times to enter into pdb (or really ipdb) to debug when the server is running. I am having trouble doing this through Supervisor. Supervisor allows the processes to be started and controlled with a daemon called supervisord, and offers access through a client called supervisorctl. This client allows you to attach to one of the foreground processes that has been started using a 'fg' command. Like this: ``` supervisor> fg webserver ``` All logging data gets sent to the terminal. But I do not get any text from the pdb debugger. It does accept my input so stdin seems to be working. As part of my investigation I was able to confirm that neither `print` nor `raw_input` send and text out either; but in the case of `raw_input` the stdin is indeed working. I was also able to confirm that this works: ``` sys.stdout.write('message') sys.flush() ``` I though that when I issued the `fg` command that it would be as if I had run the process in the foreground in the standard terminal ... but it appears that supervisorctl is doing something more. Regular printing does not flush for example. Any ideas? How can I get pdb, standard prints, etc to work properly when connecting to the foreground terminal using the `fg` command in supervisorctl? (Possible helpful ref: http://supervisord.org/subprocess.html#nondaemonizing-of-subprocesses)

Original source