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のメッセージ](https://pote-sala.com/wordpress/wp-content/uploads/2024/03/IMG_3958-1024x193.webp)
LINE Notifyのトークンはここから発行できます。
![](https://scdn.line-apps.com/n/line_notice/img/og_160829/og_fb.png)
cronで定期実行
crontabを開きます。
crontab -e
15分ごとに実行させるように設定します。
間隔は各自変えてください。
# crontab
*/15 * * * * python /home/main.py
動かなかった場合はpythonを絶対パスに置き換えてみてください。
しかし、これでは、ずっとサーバーがダウンしていた場合、サーバーが復帰するまで通知が止まらない、ということになってしまいます。
これを解決するには、pythonファイル外で「前回のチェック時にサーバーが落ちていたか」という変数を保持しておき、「trueなら通知を送信しない」という処理をする必要があります。
テキストファイルに保持しておき、実行時に読み込み/書き込みするようにするといいでしょう。
最後に
Python環境を整えるだけですし、簡単にできるので是非やってみてください!
私はこの前建てた、Minecraftサーバーに使いました!
コメント