我正在使用Supervisor(用python编写的进程控制器)来启动和控制我的Web服务器和相关服务。我发现有时需要在服务器运行时进入pdb(或ipdb)进行调试。我无法通过主管这样做。
Supervisor允许使用名为supervisord的守护进程启动和控制进程,并通过名为supervisorctl的客户端提供访问权限。此客户端允许您附加到使用“fg”命令启动的其中一个前台进程。像这样:
supervisor> fg webserver
所有日志记录数据都会发送到终端。但我没有从pdb调试器获得任何文本。它确实接受了我的输入,因此stdin似乎正在工作。
作为调查的一部分,我确认print
和raw_input
都没有发送和发送;但在raw_input
的情况下,标准输入确实有效。
我也能确认这是有效的:
sys.stdout.write('message')
sys.flush()
当我发出fg
命令时,我就好像我已经在标准终端的前台运行了进程......但是看起来supervisorctl正在做更多的事情。例如,定期打印不会刷新。有什么想法吗?
如何在supervisorctl中使用fg
命令连接到前台终端时,pdb,标准打印等是否正常工作?
(可能有帮助的参考:http://supervisord.org/subprocess.html#nondaemonizing-of-subprocesses)
答案 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)