monitで監視した諸々のプロセス監視に関する通知をPythonスクリプトでSlackに連携する

# 概要
サーバー内のプロセス監視と自動復旧にmonitを積極利用しており、チームのコラボレーションツールとしてSlackを利用しています。
monitのデフォルトの通知はメールであり、状況の把握が遅くなることがあったため、SlackのIncoming Webhookを利用してSlackのチャンネルに連携することにしました。
実装にあたってはmonitの仕様もあれこれ調べたので、Pythonのスクリプトとmonitのコンフィグ数種もあわせてご紹介。
（monitのコンフィグは大体一緒だから書かなくても良かった気がする）

# 詳細
## 構成
* OS : CentOS 6.10 (古い)
* 監視ツール : monit 5.25.1    # ver.5.14だとelseの構文でエラーが出たので、動かない場合はVerUpしてあげてください
* Python version : Python 3.5.6

## 通知スクリプト
monitから呼ばれるスクリプトをPython 3.5.6を作ったのですが、CentOS 6.xでPython 3系を使うにはお決まりの環境構築が必要になるので、まずは環境を整備。
必要なディレクトリは適宜読み替えて、好きなところに配置して上げるようにしてください。

### Python3実行環境整備
#### pyenvでPython 3.5.6をインストール
~~~shell
[root@monit scripts]# yum install bzip2-devel    # Ubuntu 18.04なら apt install libbz2-dev libssl-dev zlib1g-dev

[root@monit ~]# git clone https://github.com/pyenv/pyenv.git ~/.pyenv
[root@monit ~]# git clone https://github.com/yyuu/pyenv-virtualenv.git ~/.pyenv/plugins/pyenv-virtualenv

[root@monit ~]# echo 'export PATH="$HOME/.pyenv/bin:$PATH"' >> ~/.bashrc
[root@monit ~]# echo 'eval "$(pyenv init -)"' >> ~/.bashrc
[root@monit ~]# echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bashrc
[root@monit ~]# source ~/.bashrc

[root@monit ~]# pyenv -v
pyenv 1.2.7

[root@monit ~]# pyenv install --list

[root@monit ~]# pyenv install 3.5.6
~~~

#### 実行環境の整備
~~~shell
[root@monit ~]# mkdir /usr/local/scripts

[root@monit ~]# cd /usr/local/scripts

[root@monit scripts]# mkdir monitSlack

[root@monit monitSlack]# cd monitSlack/

[root@monit monitSlack]# python --version
Python 2.6.6

[root@monit monitSlack]# pyenv local 3.5.6

[root@monit monitSlack]# python --version
Python 3.5.6
~~~

#### 必要なpackageのインストール
スクリプトをスッキリさせるために外から .env ファイルを読み込んで環境変数を設定するようにしたので、必要なpackageをインストールしておきます。

~~~shell
[root@monit monitSlack]# pip install --upgrade pip

[root@monit monitSlack]# pip install python-dotenv
~~~

#### Logのフォルダを掘る
ログを吐くようにしてあげているので、先にディレクトリを配置。ついでに後で使う .env も先に配置。

~~~shell
[root@monit monitSlack]# mkdir log
[root@monit monitSlack]# vim .env
[root@monit monitSlack]# cat .env
export SLACK_URL="https://hooks.slack.com/services/xxxxx/xxxxx/xxxxxxxxxxxxxxxxx"  # 自身のURLに適宜書き換え
export SLACK_CHANNEL="#systemalert"  # 自身のチャンネルに適宜書き換え
export SLACK_USER="monit"  # 適宜書き換え（monitユーザーにして、monitの犬のアイコンにするとかわいい）
export SLACK_ICON=":icon:"
~~~

#### スクリプトの配置
ようやく実際のスクリプト。
あれこれネット上の記事を参考にしてPythonスクリプトを書いていきます。

~~~shell
[root@monit monitSlack]# vim monitNotifyToSlack.py
~~~

中身はこんな感じ。

~~~python
#!/root/.pyenv/shims/python
import urllib.request
import json
import os
import datetime
import logging
from dotenv import load_dotenv

# load .env file
load_dotenv()

# Logging settings
formatter = '%(levelname)s : %(asctime)s : %(message)s'
logdir = os.path.dirname(os.path.abspath(__file__))
logfile = logdir + "/log/logger.log"
logging.basicConfig(filename=logfile, level=logging.DEBUG, format=formatter)

# logging attributes
logging.debug("==================== START ====================")
logging.debug("Slack notification script started.")
logging.debug("MOINT_HOST         : " + os.getenv('MONIT_HOST'))
logging.debug("MOINT_SERVICE      : " + os.getenv('MONIT_SERVICE'))
logging.debug("MOINT_DESCRIPTION  : " + os.getenv('MONIT_DESCRIPTION'))

if __name__ == "__main__":

  # set script attributes
  surl = os.getenv('SLACK_URL')
  schannel = os.getenv('SLACK_CHANNEL')
  suser = os.getenv('SLACK_USER')
  sicon = os.getenv('SLACK_ICON')
  mhost = os.getenv('MONIT_HOST')
  mservice = os.getenv('MONIT_SERVICE')
  mdesc = os.getenv('MONIT_DESCRIPTION')
  curDate = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
  colorAlert = "#ff0000"
  colorRecover = "#008000"

  if 'not running' in mdesc or 'failed' in mdesc or 'resource limit' in mdesc:
    titleText = "[" + curDate + "] " + mhost + " - " + mservice
    color = colorAlert
    descMessage = mservice + " " + mdesc
  else:
    titleText = "[" + curDate + "] " + mhost + " - " + mservice
    color = colorRecover
    descMessage = mservice + " " + mdesc

  # Set context to Slack webhook notification format.
  data = {
    "channel" : schannel,
    "username" : suser,
    "iconi_emoji" : sicon,
  }
  data['text'] = titleText
  data['attachments'] = []
  data['attachments'].append({})
  data['attachments'][0]['color'] = color
  data['attachments'][0]['fields'] = []
  data['attachments'][0]['fields'].append({})
  data['attachments'][0]['fields'][0]['title'] = "Monit Alert on " + mhost
  data['attachments'][0]['fields'][0]['value'] = descMessage
  logging.debug("WEBHOOK_DATA : " + str(data))

  headers = {
    'Content-Type': 'application/json'
  }

  req = urllib.request.Request(surl, json.dumps(data).encode(), headers)
  with urllib.request.urlopen(req) as res:
    result = res.read()
    logging.debug("request sent to " + surl)
    logging.debug("result : " + str(result))

  logging.debug("==================== END ====================")
~~~

log/logger.log にSlackにWebhookのリクエストのログを吐くようにしています。
monitのログと突き合わせて、monitから呼んだはずなのに実行されてないとか、POSTしたデータが間違ってないかとかの確認に使うと良いかと思います。
作成後に実行権限を付けるのもお忘れなく。

~~~shell
[root@monit monitSlack]# chmod +x monitNotifyToSlack.py
[root@monit monitSlack]# ls -l monitNotifyToSlack.py
-rwxr-xr-x 1 root root 2553 Mar  9 16:20 monitNotifyToSlack.py
~~~

#### テスト実行
テストで手動で一度実行しましょう。実際にはmonitから呼ばれるため、monitの環境変数付きで実行されますから、今回は自身のshellに環境変数を設定して実行してみます。

~~~shell
[root@monit monitSlack]# export MONIT_HOST=monitslacktest.com
[root@monit monitSlack]# export MONIT_SERVICE=testservice
[root@monit monitSlack]# export MONIT_DESCRIPTION="monit test failed"
[root@monit monitSlack]# ./monitNotifyToSlack.py

~~~

成功すれば、以下のような通知がSlackに飛んでくるはずです。
<img width="332" alt="monitSlack_1.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67425/199b0b37-3a44-1901-9f79-526bf7bf2866.jpeg">
ちなみにログには以下のような出力が出ているはずです。

~~~shell
[root@monit monitSlack]# less log/logger.log
DEBUG : 2020-03-10 10:54:27,635 : ==================== START ====================
DEBUG : 2020-03-10 10:54:27,635 : Slack notification script started.
DEBUG : 2020-03-10 10:54:27,635 : MOINT_HOST         : monitslacktest.com
DEBUG : 2020-03-10 10:54:27,635 : MOINT_SERVICE      : testservice
DEBUG : 2020-03-10 10:54:27,635 : MOINT_DESCRIPTION  : monit test failed
DEBUG : 2020-03-10 10:54:27,635 : WEBHOOK_DATA : {'username': 'monit', 'attachments': [{'color': '#ff0000', 'fields': [{'title': 'Monit Alert on monitslacktest.com', 'value': 'testservice monit test failed'}]}], 'channel': '#systemalert', 'iconi_emoji': ':icon:', 'text': '[2020-03-10 10:54:27] monitslacktest.com - testservice'}
DEBUG : 2020-03-10 10:54:28,571 : request sent to https://hooks.slack.com/services/xxxxx/xxxxxx/xxxxxxxxxxxxxxxxxxxxx
DEBUG : 2020-03-10 10:54:28,571 : result : b'ok'
DEBUG : 2020-03-10 10:54:28,571 : ==================== END ====================
~~~

復旧時を想定した処理も確認してみましょう。ログは必要であれば確認して下さい。

~~~shell
[root@monit monitSlack]# export MONIT_DESCRIPTION="monit test process is running with pid 27554"
[root@monit monitSlack]# ./monitNotifyToSlack.py                                 
~~~

正しく動けば今度は緑で通知が来るはずです。
<img width="362" alt="monitSlack_2.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67425/8bcec8b4-ba63-1a73-b70a-07b4727b5bd8.jpeg">
処理の中で環境変数MONIT_DESCRIPTIONの値を確認し、 failed とか not running とか、monitがアラート発報する際によく出るものが含まれていれば色を赤、そうでなければ緑にしてあります。

## monit側の設定
monitの監視スクリプトを書いていきます。
monitは自身が実行したのが restart とかであれば、自分で賢く管理できるようなのですが、スクリプトを呼ぶ場合はexecを使ってあげる必要があります。
スクリプトの実行とプロセス再起動を一緒に処理させたいとか、execを利用して再起動した後の反応を見てunmonitorしたいとか、そういう場合は自分で指示を一つずつ書いてあげる必要があり、ちょっとコンフィグが複雑になります。

### monitのインストール
割愛します。epel-releaseとかから適当に入れてください。
以下、 /etc/配下に以下の構成でmonitがインストールされているとして進めます。

* /etc/monit.conf   (新しいバージョンでは monitrc ファイルになっていたはず)
* /etc/monit.d/

### monit基本設定
詳細は割愛しますが、以下あたりをケアください
* アラートのメール飛ばし先
* sendmailをローカルで上げるなり、外部SMTPホストを指定するなりメールの送信の設定
* check system $HOST の部分は別途conf.d/でケアするのでここではコメントのままにしておく
* デフォルトで include /etc/monit.d/* しているが、* -> *.conf にすることでバックアップファイルをうっかり読まないようにする

### monit config
では、書いていきます。長いので、必要なところだけ拾ってください。冗長。
先に、先程の * -> *.conf によって logging が読み込まれなくなってしまっているので、loggingファイルをリネーム。

~~~shell
[root@monit monit.d]# cd /etc/monit.d
[root@monit monit.d]# mv logging logging.conf
~~~

#### Nginx
監視要項は以下。最初だけ解説です。その後は大体一緒なので割愛します。

* プロセス監視
    * プロセスが存在しない場合はスクリプトを実行し、ログを log/monit.log に出力し、再起動する。
    * 毎サイクル実施。
    * 成功したらその旨通知して監視継続
    * 5サイクルのうち4回プロセス不在のままであればunmonitorする
* サービス監視
    * / から正常なレスポンスが返ってくるか確認
    * 問題があればスクリプトを実行し、ログを log/monit.log に出力し、再起動する。
    * 異常の場合は10サイクル毎に再チェック。

~~~shell
[root@monit monit.d]# vim nginx.conf
[root@monit monit.d]# cat nginx.conf
check process nginx with pidfile /var/run/nginx.pid
  start program = "/etc/init.d/nginx start" with timeout 30 seconds
  stop program  = "/etc/init.d/nginx stop"

  if failed port 80 protocol http
    and request "/"
    then exec "/bin/bash -c '/usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1 & /etc/init.d/nginx restart'"
    repeat every 10 cycles
  else if succeeded
    then exec "/bin/bash -c '/usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1'"

  if does not exist
    then exec "/bin/bash -c '/usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1 & /etc/init.d/nginx restart'"
    repeat every 1 cycles
  else if succeeded
    then exec "/bin/bash -c '/usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1'"

  if does not exist for 4 times within 5 cycles then unmonitor
~~~

#### host (OSの基本の監視)
~~~shell
[root@monit monit.d]# vim host.conf
[root@monit monit.d]# cat host.conf
check system $HOST
  if loadavg (1min) > 8
    then exec "/bin/bash -c '/usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1'"
  else if succeeded
    then exec "/bin/bash -c '/usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1'"

  if loadavg (5min) > 4
    then exec "/bin/bash -c '/usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1'"
  else if succeeded
    then exec "/bin/bash -c '/usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1'"

  if cpu usage > 80% for 3 cycles
    then exec "/bin/bash -c '/usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1'"
  else if succeeded
    then exec "/bin/bash -c '/usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1'"

  if memory usage > 75%
    then exec "/bin/bash -c '/usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1'"
  else if succeeded
    then exec "/bin/bash -c '/usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1'"

  if swap usage > 50%
    then exec "/bin/bash -c '/usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1'"
  else if succeeded
    then exec "/bin/bash -c '/usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1'"
~~~

#### crond
~~~shell
[root@monit monit.d]# vim crond.conf
[root@monit monit.d]# cat crond.conf
check process crond with pidfile /var/run/crond.pid
  start program = "/etc/init.d/crond start" with timeout 30 seconds
  stop program = "/etc/init.d/crond stop"

  if does not exist
    then exec "/bin/bash -c '/usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1 & /etc/init.d/crond restart'"
    repeat every 1 cycles
  else if succeeded
    then exec "/bin/bash -c '/usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1'"

  if does not exist for 4 times within 5 cycles then unmonitor
~~~

#### ディスク容量
~~~shell
[root@monit monit.d]# cat disk.conf
check device xvda1 with path /
  if SPACE usage > 80%
    then exec "/bin/bash -c '/usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1'"
  else if succeeded
    then exec "/bin/bash -c '/usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1'"
~~~

#### jetty
tomcatも同じ要領でいけるかと思います。

~~~shell
[root@monit monit.d]# vim jetty.conf
[root@monit monit.d]# cat jetty.conf
  start program = "/etc/init.d/jetty start" with timeout 30 seconds
  stop program = "/etc/init.d/jetty stop"

  if failed port 8080 protocol http with timeout 15 seconds
    then exec "/bin/bash -c '/usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1 & /etc/init.d/jetty restart'"
    repeat every 1 cycles
  else if succeeded
    then exec "/bin/bash -c '/usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1'"

  if does not exist
    then exec "/bin/bash -c '/usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1 & /etc/init.d/jetty restart'"
    repeat every 1 cycles
  else if succeeded
    then exec "/bin/bash -c '/usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1'"

  if does not exist for 4 times within 5 cycles then unmonitor
~~~

#### MySQL
~~~shell
[root@monit monit.d]# vim mysqld.conf
[root@monit monit.d]# cat mysqld.conf
check process mysqld with pidfile /var/run/mysqld/mysqld.pid
  start program = "/etc/init.d/mysqld start" with timeout 30 seconds
  stop program = "/etc/init.d/mysqld stop"

  if failed port 3306 protocol mysql with timeout 10 seconds
    then exec "/bin/bash -c '/usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1 & /etc/init.d/mysqld restart'"
  else if succeeded
    then exec "/bin/bash -c '/usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1'"

  if does not exist
    then exec "/bin/bash -c '/usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1 & /etc/init.d/mysqld restart'"
    repeat every 1 cycles
  else if succeeded
    then exec "/bin/bash -c '/usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1'"

  if does not exist for 4 times within 5 cycles then unmonitor
~~~

#### リモートホストのMySQL
~~~shell
[root@monit monit.d]# vim mysql-remotedb.conf
[root@monit monit.d]# cat mysql-remotedb.conf
check host mysql-remotedb with address 172.xxx.xxx.xxx   # IPは適宜書き換えてください

  if failed port 3306 protocol mysql with timeout 10 seconds
    then exec "/bin/bash -c '/usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1'"
  else if succeeded
    then exec "/bin/bash -c '/usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1'"
~~~

#### ntpd
chronyも同じ要領でいけるかと思います。

~~~shell
[root@monit monit.d]# vim ntpd.conf
[root@monit monit.d]# cat ntpd.conf
check process ntpd with pidfile /var/run/ntpd.pid
  start program = "/etc/init.d/ntpd start" with timeout 30 seconds
  stop program = "/etc/init.d/ntpd stop"

  if does not exist
    then exec "/bin/bash -c '/usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1 & /etc/init.d/ntpd restart'"
    repeat every 1 cycles
  else if succeeded
    then exec "/bin/bash -c '/usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1'"

  if does not exist for 4 times within 5 cycles then unmonitor
~~~

#### sendmail
~~~shell
[root@monit monit.d]# vim sendmail.conf
[root@monit monit.d]# cat sendmail.conf
check process sendmail with pidfile /var/run/sendmail.pid
  start program = "/etc/init.d/sendmail start" with timeout 30 seconds
  stop program = "/etc/init.d/sendmail stop"

  if does not exist
    then exec "/bin/bash -c '/usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1 & /etc/init.d/sendmail restart'"
    repeat every 1 cycles
  else if succeeded
    then exec "/bin/bash -c '/usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1'"

  if does not exist for 4 times within 5 cycles then unmonitor
~~~

#### sshd
~~~shell
[root@monit monit.d]# vim sshd.conf
[root@monit monit.d]# cat sshd.conf
check process sshd with pidfile /var/run/sshd.pid
  start program = "/etc/init.d/sshd start" with timeout 30 seconds
  stop program = "/etc/init.d/sshd stop"

  if does not exist
    then exec "/bin/bash -c '/usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1 & /etc/init.d/sshd restart'"
    repeat every 1 cycles
  else if succeeded
    then exec "/bin/bash -c '/usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1'"

  if does not exist for 4 times within 5 cycles then unmonitor
~~~

#### vsftpd
vsftpdはデフォルトだとpidファイルが生成されない。やりようはあるみたいですが、手抜きしてサービス監視だけ。

~~~shell
[root@monit monit.d]# vim vsftpd.conf
[root@monit monit.d]# cat vsftpd.conf
check host vsftpd with address 127.0.0.1
  start program = "/etc/init.d/vsftpd start" with timeout 30 seconds
  stop program = "/etc/init.d/vsftpd stop"

  if failed port 21 protocol ftp with timeout 15 seconds
    then exec "/bin/bash -c '/usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1 & /etc/init.d/vsftpd restart'"
  else if succeeded
    then exec "/bin/bash -c '/usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1'"
~~~

#### zabbix-agent
~~~shell
[root@monit monit.d]# cat zabbix-agent.conf
check process zabbix-agent with pidfile /var/run/zabbix/zabbix_agentd.pid
  start program = "/etc/init.d/zabbix-agent start" with timeout 30 seconds
  stop program = "/etc/init.d/zabbix-agent stop"

  if does not exist
    then exec "/bin/bash -c '/usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1 & /etc/init.d/zabbix-agent restart'"
    repeat every 1 cycles
  else if succeeded
    then exec "/bin/bash -c '/usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1'"

  if does not exist for 4 times within 5 cycles then unmonitor
~~~

### monitへの反映
monitをリロードして反映状況を確認しましょう。
以下のような感じで、 -Iv した際にmonitがちゃんと指定されたとおりに読み込めてたらOKです。
後は各自でmonitが正しく自動再起動できるか、unmonitorとかちゃんとしてくれるか確認してみてください。

~~~shell
[root@monit monit.d]# service monit reload
Reloading monit: Reinitializing monit daemon

[root@monit monit.d]# monit -Iv
...
Process Name          = mysqld
 Pid file             = /var/run/mysqld/mysqld.pid
 Monitoring mode      = active
 On reboot            = start
 Start program        = '/etc/init.d/mysqld start' timeout 30 s
 Stop program         = '/etc/init.d/mysqld stop' timeout 30 s
 Existence            = if does not exist for 4 times within 5 cycles then unmonitor
 Existence            = if does not exist then exec '/bin/bash -c /usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1 & /etc/init.d/mysqld restart' repeat every 1 cycle(s) else if succeeded then exec '/bin/bash -c /usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1'
 Port                 = if failed [localhost]:3306 type TCP/IP protocol MYSQL with timeout 10 s then exec '/bin/bash -c /usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1 & /etc/init.d/mysqld restart' else if succeeded then exec '/bin/bash -c /usr/local/scripts/monitSlack/monitNotifyToSlack.py >> /usr/local/scripts/monitSlack/log/monitlog.log 2>&1'
...

~~~

おしまい。

#### 参考

* [Monit Manual](https://mmonit.com/monit/documentation/monit.html#PID-TEST)
* [Monitでプロセスを監視してスラックで通知する](https://qiita.com/MasatoYamashita/items/823d7ffc8cb7bc5a597c)
* [monit による障害検知の通知を Slack に飛ばすメモ](https://cloudpack.media/10085)
* [【細かすぎて伝わらないかもしれない tips】時代はイミュータブルインフラストラクチャだけど, 敢えて monit について書いてみる](https://inokara.hateblo.jp/entry/2019/03/21/093051)

#### 2020.09.22 追記

~~~
# curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash
~~~
でpyenvをインストールするように書いていましたが、本日実施したところ　443 failed: Connection refused　と言われてつながらなかったのでgit cloneを利用したインストール方法に書き換えました。
中国からアクセスしてるせいでブロックされたのかな・・・