爲了確保線上項目的穩定性,須要對supervisor屢次從新拉啓失敗後的進程,進行釘釘告警,以便相關的技術人員能及時處理。
具體實現的效果以下:
php
這裏針對從沒有接觸過supervisor和釘釘機器人對讀者的一個掃盲,若是你已經很熟悉了,能夠直接跳過。
一、什麼是supervisor?
supervisor是python編寫的一個可靠的進程管理工具,它會對其管理的子進程進行監控,當進程出現意外crash的時候,它將會嘗試從新拉起繼續執行(能夠設置最多拉起次數,通常也不會無限去拉起失敗的進程)。咱們只須要知道它的大概做用便可,具體能夠參考supervisor官網html
二、什麼是釘釘機器人?
釘釘機器人,是基於釘釘軟件的,對釘釘羣功能對一種擴展。羣機器人能夠將第三方服務的信息聚合到羣聊中,實現自動化的信息同步。機器人的種類有不少如gitlab機器人、github機器人、cooding機器人等,這裏咱們使用的是自定義機器人,具體能夠參考官網介紹python
一、打開釘釘軟件,找到機器人管理
git
二、單擊機器人管理,出現機器人管理菜單,大概是這個樣子
github
剩下的步驟在官網上已經有了很詳細的說明,我就再也不贅述了戳這裏shell
到最後咱們會獲得一個帶有access_token的url連接,咱們就是經過對這個url發起post請求進行告警,它大概是下面這個樣子:json
https://oapi.dingtalk.com/robot/send?access_token=XXXXXX
(ps:本文采用了ip限制的策略)c#
首先,先看下supervisor eventlistner的配置文件內容:api
[eventlistener:monitor] command=/home/zero/supervisord.d/monitor.py events=PROCESS_STATE_FATAL stdout_logfile=/var/log/supervisor/script_log/monitor.log stderr_logfile=/var/log/supervisor/script_log/monitor@error.log
簡單的分析一下上面的配置
第一行:[eventlistener:monitor],接觸過supervisor的同窗都知道,通常狀況下supervisor的子進程的配置第一行通常都是[program:進程名稱], 而這裏是 [eventlistener:監聽者名稱] 的形式,代表這個是一個關於事件監聽者的配置,監聽者的進程名稱叫作monitor。
第二行:command=/home/zero/supervisord.d/monitor.py ,表明執行該進程的命令,下面會詳細介紹一下,這裏暫時忽略。
第三行:events=PROCESS_STATE_FATAL,表明監聽者監聽的事件。截止supervisor 4.1 這個版本,目前支持23個事件,它們分別是:markdown
PROCESS_STATE PROCESS_STATE_STARTING PROCESS_STATE_RUNNING PROCESS_STATE_BACKOFF PROCESS_STATE_STOPPING PROCESS_STATE_EXITED PROCESS_STATE_STOPPED PROCESS_STATE_FATAL PROCESS_STATE_UNKNOWN REMOTE_COMMUNICATION PROCESS_LOG_STDOUT PROCESS_LOG_STDERR PROCESS_COMMUNICATION_STDOUT PROCESS_COMMUNICATION_STDERR SUPERVISOR_STATE_CHANGE SUPERVISOR_STATE_CHANGE_RUNNING SUPERVISOR_STATE_CHANGE_STOPPING TICK_5 TICK_60 TICK_3600 PROCESS_GROUP PROCESS_GROUP_ADDED PROCESS_GROUP_REMOVED
詳細的介紹能夠查看這裏
這裏咱們關注的是 PROCESS_STATE_FATAL 事件,這個事件是什麼意思呢?下面是官網的洋文:
Indicates a process has moved from the BACKOFF state to the FATAL state. This means that Supervisor tried startretries number of times unsuccessfully to start the process, and gave up attempting to restart it. 當這個事件發生的時候,意味着supervisor的子進程從BACKOFF 變爲了 FATAL狀態。 意味着supervisor屢次(重起次數,看本身的配置)嘗試重啓子進程,依然失敗,決定放棄
第四行、第五行:表明着監聽者在監聽過程當中 標準輸出日誌、錯誤日誌的輸出位置
這裏咱們承接上面提到的command配置項,command配置的是eventlistener的真正監聽的真正執行者,也就是上文提到的/home/zero/supervisord.d/monitor.py 腳本。理論上監聽腳本能夠用任何語言編寫,可是因爲supervisor自己是用python編寫的,而且提供了一個名字叫作supervisor.childutils 的模塊。這樣一來使用python腳本去編寫監聽者將會異常的簡單。官網上提供了一個簡單的👇demo👇,而咱們須要作的就是針對demo進行一個二次的開發,代碼以下:
#!/usr/bin/env python import sys import urllib2 import json 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() # read event payload and print it to stderr headers = dict([ x.split(':') for x in line.split() ]) notifyData = sys.stdin.read(int(headers['len'])) title = "warning online" content = "### supervisor sub process failed\n" + "> ![screenshot](一張圖片的url地址)\n" + "> " + notifyData +"\n" url = "設置自定義機器人時獲得的連接" headers = {'Content-Type':'application/json'} body = {'msgtype':'markdown', 'markdown':{'title':title, 'text':content, 'at':{'isAtAll':'true'}}} request = urllib2.Request(url,headers=headers,data=json.dumps(body)) response = urllib2.urlopen(request) # transition from READY to ACKNOWLEDGED write_stdout('RESULT 2\nOK') if __name__ == '__main__': main()
(ps:這裏使用的是支持markdown 格式的告警內容)
好了,配置完畢,enjoy!!!因爲我的能力有限,若有紕漏,不吝賜教!
supervisor官網 http://www.supervisord.org/index.html
釘釘文檔機器人的官網文檔 https://ding-doc.dingtalk.com/doc#/serverapi2/krgddi