为什么stdout在连接到使用supervisord运行的进程时不会刷新?

时间:2013-03-16 18:49:18

标签: python unix terminal supervisord

我正在使用Supervisor(用python编写的进程控制器)来启动和控制我的Web服务器和相关服务。我发现有时需要在服务器运行时进入pdb(或ipdb)进行调试。我无法通过主管这样做。

Supervisor允许使用名为supervisord的守护进程启动和控制进程,并通过名为supervisorctl的客户端提供访问权限。此客户端允许您附加到使用“fg”命令启动的其中一个前台进程。像这样:

supervisor> fg webserver

所有日志记录数据都会发送到终端。但我没有从pdb调试器获得任何文本。它确实接受了我的输入,因此stdin似乎正在工作。

作为调查的一部分,我确认printraw_input都没有发送和发送;但在raw_input的情况下,标准输入确实有效。

我也能确认这是有效的:

sys.stdout.write('message')
sys.flush()

当我发出fg命令时,我就好像我已经在标准终端的前台运行了进程......但是看起来supervisorctl正在做更多的事情。例如,定期打印不会刷新。有什么想法吗?

如何在supervisorctl中使用fg命令连接到前台终端时,pdb,标准打印等是否正常工作?

(可能有帮助的参考:http://supervisord.org/subprocess.html#nondaemonizing-of-subprocesses

2 个答案:

答案 0 :(得分:6)

事实证明,python默认缓冲其输出流。在某些情况下(例如这个) - 会导致输出被扣留。

这样的成语存在:

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

强制缓冲区为零。

但我认为更好的选择是使用-u标志以无缓冲状态启动基本python进程。在supervisord.conf文件中,它只是变成:

command=python -u script.py

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

另请注意,这会弄脏您的日志文件 - 特别是如果您使用的是带有ANSI着色的ipdb之类的东西。但由于它是一个开发环境,因此这不太重要。

如果这是一个问题 - 另一个解决方案是停止在supervisorctl中调试该进程,然后在另一个终端中临时运行该进程以进行调试。如果需要,这将使日志文件保持清洁。

答案 1 :(得分:0)

可能是你的web服务器将自己的stdout(内部)重定向到日志文件(即它忽略了supervisord的stdout重定向),这阻止了supervisord控制stdout的去向。

要检查是否是这种情况,您可以tail -f日志,并查看您希望在终端中看到的输出是否会在那里。

如果是这种情况,请查看是否可以找到一种方法来配置您的网络服务器不要这样做,或者,如果所有其他方法都失败了,请尝试使用两个终端...(一个用于输入,一个用于ouptut)