Windowsバッチでチェックをして、エラーならMattermostにメッセージを送る

#はじめに

勤務先でMattermostを使っています。

現場の人から

>自動処理をさせているプログラムが気づいたら落ちていて困る。
特に、業務時間外（深夜、朝方）に落ちると気づくこともできない　(>_<)

ということが発生。

そこで、

>「プロセスをチェックし、落ちてたら（プロセスがいなかったら）起動させる」

というバッチを作りました。
しかし、そもそも解決すべきは「落ちる原因を突き止めて、落ちないようにする」こと。
でも、バッチで自動起動させては落ちていたことすら気づけない。
気づけないと根本原因も見えないし、何より「動いてるし、これでいっか」ってなっちゃう。

いつ落ちたのか確認するにはログを吐かせる手もあるけど、それだとログを見に行かなきゃいけないし、面倒。
それなら、
　　「落ちてたら、再起動させつつ、Mattermostに通知すればログの代わりになるじゃん」
ってことで、Mattermostに通知するVBSを作りました。

#設定

##Mattermost　IncomingWebhookの設定
Mattermostで、通知用のチャンネルを作成します。
そして、Mattermostに「IncomingWebhook」を設定します。
[公式ページ](https://docs.mattermost.com/developer/webhooks-incoming.html) を参照しつつ設定してください。

##メッセージ送信スクリプト

IncomingWebhookの設定で作成したURLを「INCOMING_WEBHOOKS_URL」に代入します。
Mattermostに通知するメッセージを「msgStr」に作成します。
メッセージのアイコンがあれば、「BOT_ICON_URL」にアイコン画像のURLを設定してください。
メッセージは通知内容に合わせて適切なものに変更してください。
メッセージに合わせてアイコンを変えることで、ユーザの気づきにもなるかと思います。

```vb:SendAlertMsg.wsf
<package>
	<JOB ID="SEND_ALERT_MSG">
		<COMMENT>***********************************************************
		**********************************************************</COMMENT>

		<OBJECT id="oWHR" progid="WinHttp.WinHttpRequest.5.1" />

		<SCRIPT language="VBScript">
			Option Explicit

			Const INCOMING_WEBHOOKS_URL = "http://server_name:8065/hooks/XXXXXXXXXXXXXXXXXXXXXXXXXX"
			Const BOT_ICON_URL = "http://server_name/icon/Monitoring_bot.png"
			Const CHANNEL_NAME = "monitoring"
			Const  = "Monitoring_Bot"

			'-----------------------------------------------
			' 共通変数等定義

			'-----------------------------------------------
			' データ読み込み
			Dim msgStr : msgStr = ""
			msgStr = msgStr & """text"": ""#### プロセス停止を検知\n\n"
			msgStr = msgStr & " **プログラムの停止** を検知しました。\n"
			msgStr = msgStr & "プログラムを先起動しました。\n"
			msgStr = msgStr & """"
			msgStr = msgStr & "}"

			Dim sendMsg : sendMsg = ""
			sendMsg = sendMsg & "payload={"
			sendMsg = sendMsg & """channel"": """ & CHANNEL_NAME & ""","
			sendMsg = sendMsg & """username"": """ & BOT_NAME & ""","
			sendMsg = sendMsg & """icon_url"": """ & BOT_ICON_URL & ""","
			sendMsg = sendMsg & msgStr
			sendMsg = sendMsg & "}"

			oWHR.Open "POST", INCOMING_WEBHOOKS_URL, false
			oWHR.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
			oWHR.send sendMsg

			Dim sResult
			sResult = oWHR.Status & " " & oWHR.StatusText & vbCrLf _
					& oWHR.GetAllResponseHeaders & vbCrLf _
					& oWHR.ResponseText

			WScript.Echo sResult

			WScript.Quit

		</SCRIPT>
	</JOB>
</package>
```

##チェックおよびメッセージ送信スクリプト起動バッチ

以下のサンプルでは「notepad.exe（メモ帳）」にしていますが、監視対象のプログラムに変更してください。
データベースやその他のものをチェックする場合は、

```
TASKLIST | FIND %PROCNAME% > NUL
IF NOT ERRORLEVEL 1
```

の部分を別のコードに書き換えたり、チェックするためのスクリプト、プログラムの呼び出しに変更してください。
チェック対象を正しく判定できるように変更しましょう。

```bat:check_task.bat
@ECHO OFF

rem ********************************************************
rem 初期化
SET BASEDIR=%~dp0
SET PROCNAME=notepad.exe

SET CSCRIPT_EXE=C:\Windows\SysWOW64\cscript.exe
SET WSF_MAKE_MSG=%BASEDIR%SendAlertMsg.wsf

rem ********************************************************
rem 処理開始
TASKLIST | FIND %PROCNAME% > NUL
IF NOT ERRORLEVEL 1 (
	GOTO END
) ELSE (
	ECHO 「%PROCNAME%」が起動していません。
	GOTO PGNG
)

:PGOK
	ECHO 「%PROCNAME%」は起動しています。
	GOTO END

:PGNG
	REM プログラム起動
	start C:\Windows\System32\notepad.exe
	REM Mattermost通知
	%CSCRIPT_EXE% //nologo %WSF_MAKE_MSG% //job:SEND_ALERT_MSG
	GOTO END
:END
	ECHO 終了処理
EXIT
```

あとは、このバッチをタスクスケジューラで定期実行するように設定してやれば完了です。

#まとめ

通知が必要なければ、再起動のバッチだけ使うのもありだと思います。
また、通知の部分をメール送信に変更する手も。
環境や必要性に合わせて変更してください。

皆さんのお仕事のコストを減らす一助になれば幸いです m(_ _)m