Supervisor 管理进程服务重启报警(Event & Listener 监控进程并报警)

一、需求:

服务、进程等都被 Supervisor 管理,想实现 被管理的程序异常退出后,或者程序尝试重启多次失败后,Supervisor可以告警通知。

二、实现思路

Event 是在 Supervisor 3.0 引入的一个高级特性,如果只简单使用 Supervisor 管理进程,则不需要了解 Event。

但如果希望监控 Supervisor 管理的进程的各种状态(如: 启动、退出、失败、退出状态码 …)并支持告警,才需要了解Event。

利用 Supervisor 的 Event & Listener 功能进行订阅异常退出事件,并进行报警处理。

Supervisor 官方对其 Event 机制的描述是:一个进程的监控/通知框架

该机制主要通过一个 event listener 订阅 event 通知实现。当被 Supervisor 管理的进程有特定行为的时候,supervisor 就会自动发出对应类型的 event。即使没有配置 listener,这些 event 也是会发的;如果配置了 listener 并监听该类型的 event,那么这个 listener 就会接收到该 event。 event listener 需要自己实现,并像 program 一样,作为 superviosr 的子进程运行。

三、具体配置实现

1、配置事件监听器

主管事件侦听器是通过 配置文件中的[eventlistener:x]指定的。关于Supervisor [eventlistener:x] 在配置中允许的键方面,几乎与supervisor [program:x]完全一样,只是Supervisor不遵循事件侦听器进程的“捕获模式”输出(即事件侦听器不能是 PROCESS_COMMUNICATIONS_EVENT事件生成器)。因此,在事件``侦听器的配置中指定stdout_capture_maxbytesstderr_capture_maxbytes是错误的。可以放入配置文件的事件侦听器部分的数量没有人为限制。

vim /etc/supervisord.d/eventlistener.ini

[eventlistener:mylistener]
command=/opt/my_custom_listener.py  ; 自定义的监控程序
events=PROCESS_STATE_EXITED,PROCESS_STATE_FATAL,TICK_60  ; 监控事件
; 下面的配置和`[program:x]`完全一样
autostart=true
autorestart=true
log_stdout=true
log_stderr=true
stdout_logfile=/opt/supervisor_event_exited-stdout.log
stdout_logfile_maxbytes=50MB
stdout_logfile_backups=3
buffer_size=10
stderr_logfile=/opt/supervisor_event_exited-stderr.log
stderr_logfile_maxbytes=50MB
stderr_logfile_backups=3

2、配置监听器脚本

vim /opt/my_custom_listener.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
from supervisor import childutils


def write_stdout(s):
    # only eventlistener protocol messages may be sent to stdout
    sys.stdout.write(s)
    sys.stdout.flush()

def write_stderr(s):
    sys.stderr.write(s)
    sys.stderr.flush()

def main():
    while 1:
        # transition from ACKNOWLEDGED to READY
        write_stdout('READY\n')

        # read header line and print it to stderr
        line = sys.stdin.readline()
        write_stderr(line)

        # read event payload and print it to stderr
        headers = dict([ x.split(':') for x in line.split() ])
        data = sys.stdin.read(int(headers['len']))
        write_stderr(data)

        # transition from READY to ACKNOWLEDGED
        write_stdout('RESULT 2\nOK')


        # 使用supervisor的childutils解析
        headers, payload = childutils.listener.wait(sys.stdin, sys.stdout)
        pheaders, pdata = childutils.eventdata(payload + '\n')
        # 当 program 的退出码为对应配置中的 exitcodes 值时, expected=1; 否则为0
        if int(pheaders.get('expected', 1)):
            childutils.listener.ok(sys.stdout)
            continue
        else:  # 0, 异常退出,根据 pheaders 的值发送报警处理
            ############################
            pass  # 你的自定制发送报警逻辑 #
            with open('/opt/sup.log', 'a') as f:  # 这里写入文件作为报警简单模拟
                f.write(str(pheaders))
                f.write(str(pdata))
                f.write('\n')
            ############################

            # 向 stdout 写入"RESULT\nOK",并进入下一次循环
            childutils.listener.ok(sys.stdout)

if __name__ == '__main__':
    main()

3、测试

我这边测试kill -9 可以模拟异常退出

kill pid  # 程序正常退出  expected 退出码,1

kill -9 pid  # 程序异常退出,expected 退出码,0

四、常用的事件类型

Event解释
PROCESS_STATE进程状态发生改变
PROCESS_STATE_STARTING进程状态从其他状态转换为正在启动(Supervisord的配置项中有startsecs配置项,是指程序启动时需要程序至少稳定运行x秒才认为程序运行正常,在这x秒中程序状态为正在启动)
PROCESS_STATE_RUNNING进程从正在启动状态转换为正在运行状态
PROCESS_STATE_BACKOFF进程从正在启动状态转换为启动失败状态,Supervisor 正在重启该进程
PROCESS_STATE_STOPPING进程从正在运行状态或正在启动状态转换为正在停止状态
PROCESS_STATE_EXITED进程从正在运行状态转换为退出状态,expected 退出码,如果是 0 表示进程异常退出,1 表示进程正常退出。
PROCESS_STATE_STOPPED进程从正在停止状态转换为已停止状态
PROCESS_STATE_FATAL进程从启动失败状态(BACKOFF)转换为失败状态(FATAL). 意味着 startretries 尝试次数已达上限,Supervisor 已放弃重启该进程。
PROCESS_LOG进程产生日志输出,被管理的进程需配置,stdout_events_enabled=true or stderr_events_enabled=true 这个事件通知才会生效。
PROCESS_LOG_STDOUT进程产生标准输出,被管理的进程需配置,stdout_events_enabled=true
PROCESS_LOG_STDERR进程产生错误输出,被管理的进程需配置,stderr_events_enabled=true

参考资料:

http://supervisord.org/events.html

https://blog.51cto.com/tchuairen/2432698

https://lework.github.io/2019/10/16/supervistor-event/

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 书香水墨 设计师:CSDN官方博客 返回首页