主管事件:如何监听所有或指定进程的 PROCESS_STATE_STOPPED 事件

mic*_*ckm 2 python supervisord

我正在尝试使用 supervisord 事件来监听PROCESS_STATE_STOPPED来自 Supervisor 管理的进程的事件。

我的事件侦听器 ( 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()
Run Code Online (Sandbox Code Playgroud)

我对应的入口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
Run Code Online (Sandbox Code Playgroud)

我研究了该领域的其他 StackOverflow 问题,并尝试从以下方面实施公认的解决方案:

但是,当我运行时listener.py,它输出READY到 SDOUT 并且不再继续。我试过停止/启动和重新启动主管监视的进程,但我的脚本确实会拾取任何东西。

为了测试这个,我是:

  1. 在终端 A 中运行我的事件侦听器脚本;
  2. 对终端 B 中kill -9 <pid>/bin/cat进程执行 a 。

我的主管日志如下:

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)
Run Code Online (Sandbox Code Playgroud)

虽然主管日志知道我的进程已终止:

i) 没有检测到 listener.py,它保持在“READY”提示。

ii) 主管重新开始处理(如预期)。

我想知道为什么侦听器没有PROCESS_STATE_STOPPED为配置文件中定义的程序获取事件(根据 Supervisor 事件文档)。此外 - 这是否可以普遍应用于所有主管管理的流程。

谢谢。

lap*_*ira 5

配置变量redirect_stderr:

http://supervisord.org/configuration.html

不要在 [eventlistener:x] 部分设置 redirect_stderr=true。事件监听器使用 stdout 和 stdin 与 supervisord 通信。如果 stderr 被重定向,stderr 的输出将干扰事件侦听器协议。

这是我的工作脚本:

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")
Run Code Online (Sandbox Code Playgroud)

但我相信你不能简单地运行你的脚本来测试它。您的 supervisorctl .conf 文件有一些特殊的环境变量,例如您手动运行脚本时不会出现的事件

如果您想测试它,请向您的侦听器添加一些日志记录:

[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
Run Code Online (Sandbox Code Playgroud)

您也可以调试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...
Run Code Online (Sandbox Code Playgroud)

当我 kil -9 时,上述输出出现在日志中。

此外, stdout_logfile 将记录此类信息:

RESULT 2
OKREADY
RESULT 2
OKREADY
RESULT 2
OKREADY
RESULT 2
OKREADY
RESULT 2
OKREADY
Run Code Online (Sandbox Code Playgroud)