[Python] pingを送信して死活監視をする方法
Pythonでpingを送信して死活監視を行うには、subprocess
モジュールを使用してシステムのping
コマンドを実行する方法が一般的です。
subprocess.run()
を使って、指定したIPアドレスやホスト名に対してpingを送信し、その結果を確認します。
成功すればリターンコードが0、失敗すれば非0の値が返されます。
WindowsとLinuxでping
コマンドのオプションが異なるため、OSに応じたコマンドを使う必要があります。
Pythonでpingを送信する方法
subprocessモジュールを使ったpingの実行
Pythonのsubprocess
モジュールを使用すると、外部コマンドを実行することができます。
以下は、pingコマンドを実行するサンプルコードです。
import subprocess
def ping(host):
# pingコマンドを実行
result = subprocess.run(['ping', host], capture_output=True, text=True)
return result.stdout
# 使用例
output = ping('google.com')
print(output)
google.com [2404:6800:400a:80a::200e]に ping を送信しています 32 バイトのデータ:
2404:6800:400a:80a::200e からの応答: 時間 =3ms
2404:6800:400a:80a::200e からの応答: 時間 =3ms
2404:6800:400a:80a::200e からの応答: 時間 =3ms
2404:6800:400a:80a::200e からの応答: 時間 =3ms
2404:6800:400a:80a::200e の ping 統計:
パケット数: 送信 = 4、受信 = 4、損失 = 0 (0% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
最小 = 3ms、最大 = 3ms、平均 = 3ms
このコードでは、指定したホストに対してpingを実行し、その結果を取得して表示します。
WindowsとLinuxでのpingコマンドの違い
WindowsとLinuxでは、pingコマンドのオプションや出力形式が異なります。
以下の表に主な違いを示します。
特徴 | Windows | Linux |
---|---|---|
コマンド | ping <ホスト名> | ping <ホスト名> |
オプション | -n <回数> (送信回数指定) | -c <回数> (送信回数指定) |
結果の表示形式 | 各応答の時間がミリ秒で表示 | 各応答の時間がミリ秒で表示 |
pingの結果を取得する方法
pingの結果は、subprocess.run
の戻り値から取得できます。
stdout
属性を使用して、コマンドの出力を文字列として取得します。
以下は、pingの結果を取得するサンプルコードです。
import subprocess
def get_ping_result(host):
result = subprocess.run(['ping', host], capture_output=True, text=True)
return result.stdout
# 使用例
ping_result = get_ping_result('example.com')
print(ping_result)
このコードを実行すると、指定したホストへのping結果が表示されます。
pingのタイムアウト設定
pingコマンドには、タイムアウトを設定するオプションがあります。
Windowsでは-w
、Linuxでは-W
を使用します。
以下は、タイムアウトを設定したサンプルコードです。
import subprocess
def ping_with_timeout(host, timeout):
# Windowsの場合
result = subprocess.run(['ping', host, '-w', str(timeout)], capture_output=True, text=True)
return result.stdout
# 使用例
output = ping_with_timeout('google.com', 1000) # タイムアウトを1000ミリ秒に設定
print(output)
このコードでは、指定したタイムアウトでpingを実行します。
成功・失敗の判定方法
pingの結果から成功・失敗を判定するには、戻り値のreturncode
を確認します。
0の場合は成功、1の場合は失敗です。
以下は、成功・失敗を判定するサンプルコードです。
import subprocess
def ping_and_check(host):
result = subprocess.run(['ping', host], capture_output=True, text=True)
if result.returncode == 0:
return "成功"
else:
return "失敗"
# 使用例
status = ping_and_check('example.com')
print(status)
このコードを実行すると、指定したホストへのpingが成功したかどうかが表示されます。
Pythonでの死活監視の実装例
単一のホストに対するping監視
単一のホストに対してpingを実行し、その結果を監視する簡単なプログラムを作成します。
以下のサンプルコードでは、指定したホストにpingを送り、結果を表示します。
import subprocess
def ping_host(host):
result = subprocess.run(['ping', host], capture_output=True, text=True)
if result.returncode == 0:
print(f"{host} は生きています。")
else:
print(f"{host} は死んでいます。")
# 使用例
ping_host('example.com')
このコードを実行すると、指定したホストが生きているかどうかが表示されます。
複数ホストに対するping監視
複数のホストに対してpingを実行する場合、リストを使用して各ホストに対してpingを送信します。
以下のサンプルコードでは、複数のホストを監視します。
import subprocess
def ping_multiple_hosts(hosts):
for host in hosts:
result = subprocess.run(['ping', host], capture_output=True, text=True)
if result.returncode == 0:
print(f"{host} は生きています。")
else:
print(f"{host} は死んでいます。")
# 使用例
hosts_to_monitor = ['example.com', 'google.com', 'nonexistent.domain']
ping_multiple_hosts(hosts_to_monitor)
このコードを実行すると、リスト内の各ホストに対してpingを実行し、結果を表示します。
監視結果をログに記録する方法
監視結果をファイルにログとして記録することも可能です。
以下のサンプルコードでは、pingの結果をping_log.txt
というファイルに記録します。
import subprocess
def log_ping_result(host):
result = subprocess.run(['ping', host], capture_output=True, text=True)
with open('ping_log.txt', 'a') as log_file:
if result.returncode == 0:
log_file.write(f"{host} は生きています。\n")
else:
log_file.write(f"{host} は死んでいます。\n")
# 使用例
log_ping_result('example.com')
このコードを実行すると、pingの結果がping_log.txt
に追記されます。
監視結果をメールで通知する方法
監視結果をメールで通知するには、smtplib
モジュールを使用します。
以下のサンプルコードでは、pingの結果をメールで送信します。
import subprocess
import smtplib
from email.mime.text import MIMEText
def send_email(subject, body):
sender = 'your_email@example.com'
receiver = 'recipient@example.com'
msg = MIMEText(body)
msg['Subject'] = subject
msg['From'] = sender
msg['To'] = receiver
with smtplib.SMTP('smtp.example.com') as server:
server.login('your_email@example.com', 'your_password')
server.sendmail(sender, receiver, msg.as_string())
def ping_and_notify(host):
result = subprocess.run(['ping', host], capture_output=True, text=True)
if result.returncode == 0:
send_email(f"{host} の監視結果", f"{host} は生きています。")
else:
send_email(f"{host} の監視結果", f"{host} は死んでいます。")
# 使用例
ping_and_notify('example.com')
このコードを実行すると、指定したホストのping結果がメールで送信されます。
定期的にpingを実行する方法(スケジューリング)
定期的にpingを実行するには、time
モジュールを使用してスリープを挟む方法があります。
以下のサンプルコードでは、指定した間隔でpingを実行します。
import subprocess
import time
def periodic_ping(host, interval):
while True:
result = subprocess.run(['ping', host], capture_output=True, text=True)
if result.returncode == 0:
print(f"{host} は生きています。")
else:
print(f"{host} は死んでいます。")
time.sleep(interval)
# 使用例
periodic_ping('example.com', 60) # 60秒ごとにpingを実行
このコードを実行すると、指定したホストに対して60秒ごとにpingを実行し、結果を表示します。
応用例:ping以外の死活監視方法
ICMP以外のプロトコルを使った監視
ICMP以外のプロトコルを使用して死活監視を行うことも可能です。
例えば、TCPやUDPを使用して特定のポートに接続を試みることで、サービスの稼働状況を確認できます。
以下は、TCP接続を使用した監視のサンプルコードです。
import socket
def check_tcp_connection(host, port):
try:
with socket.create_connection((host, port), timeout=5):
print(f"{host}:{port} は生きています。")
except (socket.timeout, socket.error):
print(f"{host}:{port} は死んでいます。")
# 使用例
check_tcp_connection('example.com', 80) # HTTPポートを監視
このコードでは、指定したホストとポートにTCP接続を試み、成功した場合は生存を確認します。
HTTPリクエストを使ったWebサーバーの監視
Webサーバーの死活監視には、HTTPリクエストを使用する方法があります。
requests
モジュールを使って、指定したURLにGETリクエストを送り、応答を確認します。
以下はそのサンプルコードです。
import requests
def check_http_status(url):
try:
response = requests.get(url, timeout=5)
if response.status_code == 200:
print(f"{url} は生きています。")
else:
print(f"{url} は死んでいます。ステータスコード: {response.status_code}")
except requests.exceptions.RequestException:
print(f"{url} は死んでいます。")
# 使用例
check_http_status('http://example.com')
このコードを実行すると、指定したURLのHTTPステータスを確認し、結果を表示します。
ポートスキャンを使ったサービスの監視
ポートスキャンを使用して、特定のサービスが稼働しているかどうかを確認することもできます。
以下は、指定したポートのリストに対してスキャンを行うサンプルコードです。
import socket
def scan_ports(host, ports):
for port in ports:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.settimeout(1)
result = sock.connect_ex((host, port))
if result == 0:
print(f"{host}:{port} は生きています。")
else:
print(f"{host}:{port} は死んでいます。")
# 使用例
ports_to_scan = [22, 80, 443] # SSH, HTTP, HTTPSポート
scan_ports('example.com', ports_to_scan)
このコードを実行すると、指定したホストの各ポートに対して接続を試み、結果を表示します。
SNMPを使ったネットワークデバイスの監視
SNMP(Simple Network Management Protocol)を使用して、ネットワークデバイスの状態を監視することも可能です。
pysnmp
ライブラリを使用して、SNMPリクエストを送信し、デバイスの情報を取得します。
以下はそのサンプルコードです。
from pysnmp.hlapi import *
def check_snmp(host, community, oid):
iterator = getCmd(SnmpEngine(),
CommunityData(community),
UdpTransportTarget((host, 161)),
ContextData(),
ObjectType(ObjectIdentity(oid)))
errorIndication, errorStatus, errorIndex, varBinds = next(iterator)
if errorIndication:
print(f"SNMPエラー: {errorIndication}")
elif errorStatus:
print(f"SNMPエラー: {errorStatus.prettyPrint()}")
else:
for varBind in varBinds:
print(f"{host} の OID {oid} の値: {varBind}")
# 使用例
check_snmp('192.168.1.1', 'public', '1.3.6.1.2.1.1.1.0') # システムの説明を取得
このコードを実行すると、指定したSNMPデバイスからOIDに対応する情報を取得し、表示します。
SNMPを使用することで、ネットワークデバイスの状態を詳細に監視することができます。
まとめ
この記事では、Pythonを使用してpingを送信し、死活監視を行う方法について詳しく解説しました。
具体的には、subprocess
モジュールを利用したpingの実行方法から、複数ホストの監視、HTTPリクエストやポートスキャンを用いた監視手法まで幅広く取り上げました。
これを機に、実際のプロジェクトや運用において、さまざまな監視手法を活用してみてはいかがでしょうか。