4

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

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

supervisor> fg webserver

所有记录数据都被发送到终端。但是我没有从 pdb 调试器中得到任何文本。它确实接受我的输入,所以标准输入似乎正在工作。

作为我调查的一部分,我能够确认既不发送print也不raw_input发送短信;但在标准输入的情况下raw_input确实有效。

我还能够确认这有效:

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

我认为,当我发出fg命令时,就好像我已经在标准终端的前台运行了该进程......但似乎 supervisorctl 正在做更多的事情。例如,常规打印不会刷新。有任何想法吗?

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

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

4

2 回答 2

7

事实证明,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 中停止要调试的进程,然后在另一个终端中临时运行该进程以进行调试。如果需要,这将使日志文件保持干净。

于 2013-03-17T13:10:45.377 回答
0

可能是您的网络服务器将其自己的标准输出(内部)重定向到日志文件(即它忽略了supervisord 的标准输出重定向),这阻止了supervisord 控制其标准输出的位置。

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

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

于 2013-03-16T21:27:43.097 回答