主管事件:如何监听所有或指定进程的 PROCESS_STATE_STOPPED 事件
Supervisor events: how to listen for PROCESS_STATE_STOPPED events for all or specified processes
我正在尝试使用 supervisord 事件来侦听来自 Supervisor 管理的进程的 PROCESS_STATE_STOPPED
事件。
我的事件侦听器 (listener.py
),如下所示:
import sys
from supervisor.childutils import listener
def write_stdout(s):
sys.stdout.write(s)
sys.stdout.flush()
def write_stderr(s):
sys.stderr.write(s)
sys.stderr.flush()
def main():
while True:
headers, body = listener.wait(sys.stdin, sys.stdout)
body = dict([pair.split(":") for pair in body.split(" ")])
write_stderr("Headers: %r\n" % repr(headers))
write_stderr("Body: %r\n" % repr(body))
listener.ok(sys.stdout)
if headers["eventname"] == "PROCESS_STATE_STOPPED":
write_stderr("Process state stopped...\n")
if __name__ == '__main__':
main()
我在supervisord.conf
中对应的条目如下:
[program:theprogramname]
command=/bin/cat ; the program (relative uses PATH, can take args)
process_name=%(program_name)s ; process_name expr (default %(program_name)s)
numprocs=1 ; number of processes copies to start (def 1)
...
[eventlistener:theeventlistenername]
command=python /home/mickm/listener.py ; the program (relative uses PATH, can take args)
process_name=%(program_name)s_%(process_num)s ; process_name expr (default %(program_name)s)
numprocs=1 ; number of processes copies to start (def 1)
events=PROCESS_STATE ; event notif. types to subscribe to (req'd)
autorestart=true
redirect_stderr=true
我已经研究了这方面的其他 Whosebug 问题,并且我尝试实施来自以下方面的公认解决方案:
- How to subscribe to PROCESS_STATE_RUNNING events for all processes
- Supervisor event subscription is hanging on READY state
然而,当我 运行 listener.py
时,它输出 READY
到 SDOUT 并且不再继续。我已经尝试 stopping/starting 并重新启动主管监控的进程,但我的脚本确实拾取了任何东西。
为了测试这个,我是:
- 运行在终端 A 中启用我的事件侦听器脚本;
- 在终端 B 的
/bin/cat
进程上执行 kill -9 <pid>
。
我的主管日志如下:
2017-01-13 14:56:36,168 INFO success: theeventlistenername_0 entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2017-01-13 14:56:36,168 INFO success: theprogramname entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2017-01-13 14:57:29,457 INFO exited: theprogramname (terminated by SIGKILL; not expected)
2017-01-13 14:57:30,460 INFO spawned: 'theprogramname' with pid 25788
2017-01-13 14:57:31,462 INFO success: theprogramname entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
虽然主管日志知道我的进程已终止:
i) listener.py
未检测到任何内容,它保留在 'READY' 提示符下。
ii) supervisor 重新开始处理(如预期的那样)。
我想知道为什么侦听器没有为配置文件中定义的程序拾取 PROCESS_STATE_STOPPED
事件(根据主管事件 docs)。另外 - 这是否可以普遍应用于所有主管管理的流程。
谢谢。
配置变量redirect_stderr:
http://supervisord.org/configuration.html
Do not set redirect_stderr=true in an [eventlistener:x] section.
Eventlisteners use stdout and stdin to communicate with supervisord.
If stderr is redirected, output from stderr will interfere with the
eventlistener protocol.
这是我的工作脚本:
import sys
from supervisor.childutils import listener
def write_stdout(s):
sys.stdout.write(s)
sys.stdout.flush()
def write_stderr(s):
sys.stderr.write(s)
sys.stderr.flush()
def main():
while True:
headers, body = listener.wait(sys.stdin, sys.stdout)
body = dict([pair.split(":") for pair in body.split(" ")])
write_stderr("Headers: %r\n" % repr(headers))
write_stderr("Body: %r\n" % repr(body))
if headers["eventname"] == "PROCESS_STATE_STOPPING":
write_stderr("Process state stopping...\n")
# acknowledge the event
write_stdout("RESULT 2\nOK")
但我相信您无法简单地 运行 测试您的脚本。你的 supervisorctl .conf 文件有一些特殊的环境变量,比如 events 当你手动 运行 你的脚本时
它不会出现
如果您想测试它,请向您的侦听器添加一些日志记录:
[eventlistener:theeventlistenername]
command=python /home/mickm/listener.py ; the program (relative uses PATH, can take args)
process_name=%(program_name)s_%(process_num)s ; process_name expr (default %(program_name)s)
numprocs=1 ; number of processes copies to start (def 1)
events=PROCESS_STATE ; event notif. types to subscribe to (req'd)
autorestart=true
stderr_logfile=errorlogfile
stdout_logfile=applogfile
你也可以调试 headers 变量,你可以检查你收到的数据。
启用日志记录后,您可以在 stderr_logfile 上使用 tail -f error.log.path 对其进行测试日志文件。
Headers: "{'ver': '3.0', 'poolserial': '4', 'len': '71', 'server': 'supervisor', 'eventname': 'PROCESS_STATE_RUNNING', 'serial': '4', 'pool': 'mylistener'}"
Body: "{'from_state': 'STARTING', 'processname': 'someprocess', 'pid': '345', 'groupname': 'someprocess'}"
Process state running...
当我 kil -9 进程时,上面的输出出现在日志中。
另外 stdout_logfile 也会记录这种信息:
RESULT 2
OKREADY
RESULT 2
OKREADY
RESULT 2
OKREADY
RESULT 2
OKREADY
RESULT 2
OKREADY
我正在尝试使用 supervisord 事件来侦听来自 Supervisor 管理的进程的 PROCESS_STATE_STOPPED
事件。
我的事件侦听器 (listener.py
),如下所示:
import sys
from supervisor.childutils import listener
def write_stdout(s):
sys.stdout.write(s)
sys.stdout.flush()
def write_stderr(s):
sys.stderr.write(s)
sys.stderr.flush()
def main():
while True:
headers, body = listener.wait(sys.stdin, sys.stdout)
body = dict([pair.split(":") for pair in body.split(" ")])
write_stderr("Headers: %r\n" % repr(headers))
write_stderr("Body: %r\n" % repr(body))
listener.ok(sys.stdout)
if headers["eventname"] == "PROCESS_STATE_STOPPED":
write_stderr("Process state stopped...\n")
if __name__ == '__main__':
main()
我在supervisord.conf
中对应的条目如下:
[program:theprogramname]
command=/bin/cat ; the program (relative uses PATH, can take args)
process_name=%(program_name)s ; process_name expr (default %(program_name)s)
numprocs=1 ; number of processes copies to start (def 1)
...
[eventlistener:theeventlistenername]
command=python /home/mickm/listener.py ; the program (relative uses PATH, can take args)
process_name=%(program_name)s_%(process_num)s ; process_name expr (default %(program_name)s)
numprocs=1 ; number of processes copies to start (def 1)
events=PROCESS_STATE ; event notif. types to subscribe to (req'd)
autorestart=true
redirect_stderr=true
我已经研究了这方面的其他 Whosebug 问题,并且我尝试实施来自以下方面的公认解决方案:
- How to subscribe to PROCESS_STATE_RUNNING events for all processes
- Supervisor event subscription is hanging on READY state
然而,当我 运行 listener.py
时,它输出 READY
到 SDOUT 并且不再继续。我已经尝试 stopping/starting 并重新启动主管监控的进程,但我的脚本确实拾取了任何东西。
为了测试这个,我是:
- 运行在终端 A 中启用我的事件侦听器脚本;
- 在终端 B 的
/bin/cat
进程上执行kill -9 <pid>
。
我的主管日志如下:
2017-01-13 14:56:36,168 INFO success: theeventlistenername_0 entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2017-01-13 14:56:36,168 INFO success: theprogramname entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2017-01-13 14:57:29,457 INFO exited: theprogramname (terminated by SIGKILL; not expected)
2017-01-13 14:57:30,460 INFO spawned: 'theprogramname' with pid 25788
2017-01-13 14:57:31,462 INFO success: theprogramname entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
虽然主管日志知道我的进程已终止:
i) listener.py
未检测到任何内容,它保留在 'READY' 提示符下。
ii) supervisor 重新开始处理(如预期的那样)。
我想知道为什么侦听器没有为配置文件中定义的程序拾取 PROCESS_STATE_STOPPED
事件(根据主管事件 docs)。另外 - 这是否可以普遍应用于所有主管管理的流程。
谢谢。
配置变量redirect_stderr:
http://supervisord.org/configuration.html
Do not set redirect_stderr=true in an [eventlistener:x] section. Eventlisteners use stdout and stdin to communicate with supervisord. If stderr is redirected, output from stderr will interfere with the eventlistener protocol.
这是我的工作脚本:
import sys
from supervisor.childutils import listener
def write_stdout(s):
sys.stdout.write(s)
sys.stdout.flush()
def write_stderr(s):
sys.stderr.write(s)
sys.stderr.flush()
def main():
while True:
headers, body = listener.wait(sys.stdin, sys.stdout)
body = dict([pair.split(":") for pair in body.split(" ")])
write_stderr("Headers: %r\n" % repr(headers))
write_stderr("Body: %r\n" % repr(body))
if headers["eventname"] == "PROCESS_STATE_STOPPING":
write_stderr("Process state stopping...\n")
# acknowledge the event
write_stdout("RESULT 2\nOK")
但我相信您无法简单地 运行 测试您的脚本。你的 supervisorctl .conf 文件有一些特殊的环境变量,比如 events 当你手动 运行 你的脚本时
它不会出现如果您想测试它,请向您的侦听器添加一些日志记录:
[eventlistener:theeventlistenername]
command=python /home/mickm/listener.py ; the program (relative uses PATH, can take args)
process_name=%(program_name)s_%(process_num)s ; process_name expr (default %(program_name)s)
numprocs=1 ; number of processes copies to start (def 1)
events=PROCESS_STATE ; event notif. types to subscribe to (req'd)
autorestart=true
stderr_logfile=errorlogfile
stdout_logfile=applogfile
你也可以调试 headers 变量,你可以检查你收到的数据。
启用日志记录后,您可以在 stderr_logfile 上使用 tail -f error.log.path 对其进行测试日志文件。
Headers: "{'ver': '3.0', 'poolserial': '4', 'len': '71', 'server': 'supervisor', 'eventname': 'PROCESS_STATE_RUNNING', 'serial': '4', 'pool': 'mylistener'}"
Body: "{'from_state': 'STARTING', 'processname': 'someprocess', 'pid': '345', 'groupname': 'someprocess'}"
Process state running...
当我 kil -9 进程时,上面的输出出现在日志中。
另外 stdout_logfile 也会记录这种信息:
RESULT 2
OKREADY
RESULT 2
OKREADY
RESULT 2
OKREADY
RESULT 2
OKREADY
RESULT 2
OKREADY