Supervisor管理进程服务重启报警(EventListener监控进程并报警)
⼀、需求:
服务、进程等都被 Supervisor 管理,想实现 被管理的程序异常退出后,或者程序尝试重启多次失败后,Supervisor可以告警通知。
⼆、实现思路
Event 是在 Supervisor 3.0 引⼊的⼀个⾼级特性,如果只简单使⽤ Supervisor 管理进程,则不需要了解 Event。
但如果希望监控 Supervisor 管理的进程的各种状态(如: 启动、退出、失败、退出状态码 …)并⽀持告警,才需要了解Event。
introduction用法利⽤ 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_maxbytes或
stderr_capture_maxbytes是错误的。可以放⼊配置⽂件的事件侦听器部分的数量没有⼈为限制。
vim /etc/supervisord.d/eventlistener.iniwinter in my heart
[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
correction#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys教师节手抄报的内容
btdbfrom supervisor import childutils
def write_stdout(s):
sherry怎么读# only eventlistener protocol messages may be nt to stdout
sys.stdout.write(s)
sys.stdout.flush()
def write_stderr(s):
sys.stderr.write(s)
sys.stderr.flush()
def main():
while1:
# transition from ACKNOWLEDGED to READY
pant的意思write_stdout('READY\n')
# read header line and print it to stderr
line = adline()
melatonin
write_stderr(line)6688
# read event payload and print it to stderr
headers =dict([ x.split(':')for x in line.split()])
data = ad(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 ('expected',1)):
childutils.listener.ok(sys.stdout)
continue
el:# 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的配置项中有startcs配置项,是指程序启动时需要程序⾄少稳定运⾏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
参考资料: