プロセスちゃんと動いてる?Shellで簡単にプロセス監視する方法

こんにちは、さるまりんです🐒

「このバッチ、ちゃんと動いてるのかな?」

定期的に動くバッチ処理や常駐プロセスを使っていると、想定通りに動いているかどうか監視したくなることってありますよね。

今回は、シェルスクリプトで簡単にできるプロセス監視の方法をいくつかメモしておきます。

基本:ps + grepで確認する

まずは一番ベーシックな方法です。

ps -ef | grep my-process.sh | grep -v grep

ps -efで全てのプロセスを一覧表示します。grep my-process.shで目的のプロセスを絞り込み、grep -v grepで自分自身(grep)を除外しています。

ちなみに、ps -efの代わりにps auxでも全プロセスの一覧表示をすることができます。これらは表示項目やその順序がちょっと違います。どちらがいいというのもあまりないと思うので、使いやすい方でOKです。

pgrepを使って簡潔に

pgrepを使えば、もっと短く書けます。

pgrep -f my-process.sh

pgreppsgrepを合わせたようなコマンドで、対象のプロセスがあればプロセスIDを返します。なければ、何も出力せずにexit code 1で終了します。-fをつけると、コマンドライン全体でマッチを探し、-lをつけると、PID以外にプロセス名も一緒に返します。

これを使ってスクリプトにするとこんな感じです。

if ! pgrep -f my-process.sh > /dev/null; then
  logger "my-process.sh is not running!"
fi

my-process.shが動いていなければloggerを使って記録しています。

シンプルでわかりやすいですね。

systemctl is-active –quietでサービス監視

systemdで管理されているプロセスなら、systemctlを使うのが便利です。

systemctl is-acitve --quietは「動いているか?」だけを確認します。

systemctl is-active --quiet nginx

プロセスが起動中であればexit 0、それ以外(停止中など)はexit 1を返し、--quietで出力をしないようにします。

ifで使うならこんな感じです。

if ! systemctl is-active --quiet nginx; then
  echo "nginx が止まっています!"
fi

これはデーモン系のサービス、サーバーが生きているかの死活確認にぴったりですね。

定期実行:cronで監視を自動化

↑の監視処理をスクリプトにして、cronで定期実行することで常時監視することができます。

* * * * * /home/user/bin/check_my_process.sh

check_my_process.shを1分ごとに実行して常時監視です。

ログ・通知を活用

プロセスが落ちてたときに気付けなければ意味がありませんよね。

loggerを使ってsyslogに出力

上のpgrepのところでこっそり書いてますが、loggerを使って記録します。

logger "my-process.sh is not running!"

Slack通知などと連携するには?

SlackのIncoming Webhookを使うことで、プロセスが停止していた場合にSlackに通知を送ることができます。

Webhookの設定(事前準備)

Slackの管理画面からIncoming Webhookを作成し、URLを取得しておきます。

 通知スクリプト
#!/bin/bash

WEBHOOK_URL="https://hooks.slack.com/services/XXXX/YYYY/ZZZZ"
MESSAGE=":warning: my-process.sh が停止しています!"

payload=$(cat <<EOF
{
  "text": "$MESSAGE"
}
EOF
)

curl -X POST -H 'Content-type: application/json' --data "$payload" "$WEBHOOK_URL"

このスクリプトを /home/user/bin/slack_notify.shとして保存しておきます。

監視スクリプトと組み合わせる
if ! pgrep -f my-process.sh > /dev/null; then
  logger "my-process.sh is not running!"
  /home/user/bin/slack_notify.sh
fi

Slack通知があると、異常をすぐに検知できて安心ですね。

ログをtailしながらgrepps+grepで調べるのを基本として、pgrepでシンプルにしたり、サービスならsystemctl is-active --quietを使ってみたり、cronやSlack通知などと組み合わせて使ってみたり。

状況に合わせて使い分けて、小さな監視でも、大きな事故を防げるように工夫をするのは大事ですね。

今日も安心安全に。

読んでくださってありがとうございました。

それではまた!