PythonでNetcatとLINE Notifyを使って死活管理する

MInecraft

PythonからNetcatを呼び出し、ステータスをLINE Notifyで通知するプログラムを作成しました。

Netcatのコマンド

Netcatでは以下のコマンドで疎通確認ができます。

nc -vz [アドレス] [ポート]

これを実行し、接続に成功した場合は、このような結果が返ってきます。

❯ nc -vz pote-sala.com 80
Connection to pote-sala.com port 80 [tcp/http] succeeded!

一方、接続に失敗した場合はこのように返ってきます。

❯ nc -vz pote-sala.com 81
nc: connectx to pote-sala.com port 81 (tcp) failed: Operation timed out # タイムアウトの場合

❯ nc -vz localhost 3001
nc: connectx to localhost port 3001 (tcp) failed: Connection refused # サービスが停止している場合

サービスの稼働状態を取得するには、「succeeded」の文字列の有無で判定すればよいと考えました。

Pythonコード

Netcatの実行

subprocessを使います。

import subprocess

def checkServerStatus(address:str, port):
    if address == None or port == None:
        return "Please enter the server adress and port"
    else:
        response = subprocess.run(['nc', '-vz', str(address), str(port)], encoding='utf-8', stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        return "succeeded" in response.stderr # 出力結果はstderrに出力されるっぽい

print(checkServerStatus("example.com", 80)) # 接続成功したらTrue、それ以外はFalseと出力される

接続に成功するとTrueを返し、それ以外はFalseを返す関数を作成しました。

subprocessの実行結果なのですが、stdoutではなくstderrで返ってきたので注意が必要です。

LINE Notifyと組み合わせる

LINE Notifyと組み合わせて、最終的にこんなコードになりました。

import subprocess
import requests

def checkServerStatus(address:str, port):
    if address == None or port == None:
        return "Please enter the server adress and port"
    else:
        response = subprocess.run(['nc', '-vz', str(address), str(port)], encoding='utf-8', stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        return "succeeded" in response.stderr # 出力結果はstderrに出力されるっぽい


def send_line_notify(notification_message):
    line_notify_token = 'LINE Notifyのトークンを入力'
    line_notify_api = 'https://notify-api.line.me/api/notify'
    headers = {'Authorization': f'Bearer {line_notify_token}'}
    data = {'message': f'{notification_message}'}
    requests.post(line_notify_api, headers = headers, data = data)

if checkServerStatus("localhost", 3001) == False:
    send_line_notify("サーバーがダウンしました")

参考: https://qiita.com/akeome/items/e1e0fecf2e754436afc8

サーバーがダウンしていた場合、LINE Notifyにこのようなメッセージが届きます。

LINE Notifyのメッセージ

LINE Notifyのトークンはここから発行できます。

LINE Notify
LINE NotifyはGitHub,IFTTT,MackerelなどのWebサービスからの通知を、LINEで受信することが出来る便利なサービスです。

cronで定期実行

crontabを開きます。

crontab -e

15分ごとに実行させるように設定します。

間隔は各自変えてください。

# crontab

*/15 * * * * python /home/main.py

動かなかった場合はpythonを絶対パスに置き換えてみてください。

しかし、これでは、ずっとサーバーがダウンしていた場合、サーバーが復帰するまで通知が止まらない、ということになってしまいます。

これを解決するには、pythonファイル外で「前回のチェック時にサーバーが落ちていたか」という変数を保持しておき、「trueなら通知を送信しない」という処理をする必要があります。

テキストファイルに保持しておき、実行時に読み込み/書き込みするようにするといいでしょう。

最後に

Python環境を整えるだけですし、簡単にできるので是非やってみてください!

私はこの前建てた、Minecraftサーバーに使いました!

コメント

タイトルとURLをコピーしました